30
30
import hashlib
31
31
import array
32
32
import os .path
33
+ import re
33
34
import struct
35
+ import uuid
34
36
from enum import Enum
35
37
36
38
import click
96
98
'DECOMP_SHA' : 0x71 ,
97
99
'DECOMP_SIGNATURE' : 0x72 ,
98
100
'COMP_DEC_SIZE' : 0x73 ,
101
+ 'UUID_VID' : 0x80 ,
102
+ 'UUID_CID' : 0x81 ,
99
103
}
100
104
101
105
TLV_SIZE = 4
@@ -253,6 +257,23 @@ def tlv_matches_key_type(tlv_type, key):
253
257
254
258
return False
255
259
260
+ def parse_uuid (namespace , value ):
261
+ # Check if UUID is in the RAW format (12345678-1234-5678-1234-567812345678)
262
+ uuid_re = r'[0-9A-f]{8}-[0-9A-f]{4}-[0-9A-f]{4}-[0-9A-f]{4}-[0-9A-f]{12}'
263
+ if re .match (uuid_re , value ):
264
+ uuid_bytes = bytes .fromhex (value .replace ('-' , '' ))
265
+
266
+ # Check if UUID is in the string format
267
+ elif value .isprintable ():
268
+ if namespace is not None :
269
+ uuid_bytes = uuid .uuid5 (namespace , value ).bytes
270
+ else :
271
+ raise ValueError (f"Unknown namespace for UUID: { value } " )
272
+ else :
273
+ raise ValueError (f"Unknown UUID format: { value } " )
274
+
275
+ return uuid_bytes
276
+
256
277
257
278
class Image :
258
279
@@ -262,7 +283,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
262
283
overwrite_only = False , endian = "little" , load_addr = 0 ,
263
284
rom_fixed = None , erased_val = None , save_enctlv = False ,
264
285
security_counter = None , max_align = None ,
265
- non_bootable = False ):
286
+ non_bootable = False , vid = None , cid = None ):
266
287
267
288
if load_addr and rom_fixed :
268
289
raise click .UsageError ("Can not set rom_fixed and load_addr at the same time" )
@@ -291,6 +312,8 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
291
312
self .enctlv_len = 0
292
313
self .max_align = max (DEFAULT_MAX_ALIGN , align ) if max_align is None else int (max_align )
293
314
self .non_bootable = non_bootable
315
+ self .vid = vid
316
+ self .cid = cid
294
317
295
318
if self .max_align == DEFAULT_MAX_ALIGN :
296
319
self .boot_magic = bytes ([
@@ -320,7 +343,7 @@ def __repr__(self):
320
343
return "<Image version={}, header_size={}, security_counter={}, \
321
344
base_addr={}, load_addr={}, align={}, slot_size={}, \
322
345
max_sectors={}, overwrite_only={}, endian={} format={}, \
323
- payloadlen=0x{:x}>" .format (
346
+ payloadlen=0x{:x}, vid={}, cid={} >" .format (
324
347
self .version ,
325
348
self .header_size ,
326
349
self .security_counter ,
@@ -332,7 +355,9 @@ def __repr__(self):
332
355
self .overwrite_only ,
333
356
self .endian ,
334
357
self .__class__ .__name__ ,
335
- len (self .payload ))
358
+ len (self .payload ),
359
+ self .vid ,
360
+ self .cid )
336
361
337
362
def load (self , path ):
338
363
"""Load an image from a given file"""
@@ -499,6 +524,16 @@ def create(self, key, public_key_format, enckey, dependencies=None,
499
524
# = 4 + 4 = 8 Bytes
500
525
protected_tlv_size += TLV_SIZE + 4
501
526
527
+ if self .vid is not None :
528
+ # Size of the VID TLV: header ('HH') + payload ('16s')
529
+ # = 4 + 16 = 20 Bytes
530
+ protected_tlv_size += TLV_SIZE + 16
531
+
532
+ if self .cid is not None :
533
+ # Size of the CID TLV: header ('HH') + payload ('16s')
534
+ # = 4 + 16 = 20 Bytes
535
+ protected_tlv_size += TLV_SIZE + 16
536
+
502
537
if sw_type is not None :
503
538
if len (sw_type ) > MAX_SW_TYPE_LENGTH :
504
539
msg = "'{}' is too long ({} characters) for sw_type. Its " \
@@ -602,6 +637,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
602
637
if compression_tlvs is not None :
603
638
for tag , value in compression_tlvs .items ():
604
639
prot_tlv .add (tag , value )
640
+
641
+ if self .vid is not None :
642
+ vid = parse_uuid (uuid .NAMESPACE_DNS , self .vid )
643
+ payload = struct .pack (e + '16s' , vid )
644
+ prot_tlv .add ('UUID_VID' , payload )
645
+
646
+ if self .cid is not None :
647
+ if self .vid is not None :
648
+ namespace = uuid .UUID (bytes = vid )
649
+ else :
650
+ namespace = None
651
+ cid = parse_uuid (namespace , self .cid )
652
+ payload = struct .pack (e + '16s' , cid )
653
+ prot_tlv .add ('UUID_CID' , payload )
654
+
605
655
if custom_tlvs is not None :
606
656
for tag , value in custom_tlvs .items ():
607
657
prot_tlv .add (tag , value )
0 commit comments