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' : 0x74 ,
102
+ 'UUID_CID' : 0x75 ,
99
103
}
100
104
101
105
TLV_SIZE = 4
@@ -254,6 +258,27 @@ def tlv_matches_key_type(tlv_type, key):
254
258
255
259
return False
256
260
261
+ def parse_uuid (namespace , value ):
262
+ # Check if UUID is in the RAW format (12345678-1234-5678-1234-567812345678)
263
+ uuid_re = r'[0-9A-f]{8}-[0-9A-f]{4}-[0-9A-f]{4}-[0-9A-f]{4}-[0-9A-f]{12}'
264
+ if re .match (uuid_re , value ):
265
+ uuid_bytes = bytes .fromhex (value .replace ('-' , '' ))
266
+
267
+ # Check if UUID is in the RAW HEX format (12345678123456781234567812345678)
268
+ elif re .match (r'[0-9A-f]{32}' , value ):
269
+ uuid_bytes = bytes .fromhex (value )
270
+
271
+ # Check if UUID is in the string format
272
+ elif value .isprintable ():
273
+ if namespace is not None :
274
+ uuid_bytes = uuid .uuid5 (namespace , value ).bytes
275
+ else :
276
+ raise ValueError (f"Unknown namespace for UUID: { value } " )
277
+ else :
278
+ raise ValueError (f"Unknown UUID format: { value } " )
279
+
280
+ return uuid_bytes
281
+
257
282
258
283
class Image :
259
284
@@ -263,7 +288,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
263
288
overwrite_only = False , endian = "little" , load_addr = 0 ,
264
289
rom_fixed = None , erased_val = None , save_enctlv = False ,
265
290
security_counter = None , max_align = None ,
266
- non_bootable = False ):
291
+ non_bootable = False , vid = None , cid = None ):
267
292
268
293
if load_addr and rom_fixed :
269
294
raise click .UsageError ("Can not set rom_fixed and load_addr at the same time" )
@@ -292,6 +317,8 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
292
317
self .enctlv_len = 0
293
318
self .max_align = max (DEFAULT_MAX_ALIGN , align ) if max_align is None else int (max_align )
294
319
self .non_bootable = non_bootable
320
+ self .vid = vid
321
+ self .cid = cid
295
322
296
323
if self .max_align == DEFAULT_MAX_ALIGN :
297
324
self .boot_magic = bytes ([
@@ -321,7 +348,7 @@ def __repr__(self):
321
348
return "<Image version={}, header_size={}, security_counter={}, \
322
349
base_addr={}, load_addr={}, align={}, slot_size={}, \
323
350
max_sectors={}, overwrite_only={}, endian={} format={}, \
324
- payloadlen=0x{:x}>" .format (
351
+ payloadlen=0x{:x}, vid={}, cid={} >" .format (
325
352
self .version ,
326
353
self .header_size ,
327
354
self .security_counter ,
@@ -333,7 +360,9 @@ def __repr__(self):
333
360
self .overwrite_only ,
334
361
self .endian ,
335
362
self .__class__ .__name__ ,
336
- len (self .payload ))
363
+ len (self .payload ),
364
+ self .vid ,
365
+ self .cid )
337
366
338
367
def load (self , path ):
339
368
"""Load an image from a given file"""
@@ -509,6 +538,16 @@ def create(self, key, public_key_format, enckey, dependencies=None,
509
538
# = 4 + 4 = 8 Bytes
510
539
protected_tlv_size += TLV_SIZE + 4
511
540
541
+ if self .vid is not None :
542
+ # Size of the VID TLV: header ('HH') + payload ('16s')
543
+ # = 4 + 16 = 20 Bytes
544
+ protected_tlv_size += TLV_SIZE + 16
545
+
546
+ if self .cid is not None :
547
+ # Size of the CID TLV: header ('HH') + payload ('16s')
548
+ # = 4 + 16 = 20 Bytes
549
+ protected_tlv_size += TLV_SIZE + 16
550
+
512
551
if sw_type is not None :
513
552
if len (sw_type ) > MAX_SW_TYPE_LENGTH :
514
553
msg = "'{}' is too long ({} characters) for sw_type. Its " \
@@ -612,6 +651,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
612
651
if compression_tlvs is not None :
613
652
for tag , value in compression_tlvs .items ():
614
653
prot_tlv .add (tag , value )
654
+
655
+ if self .vid is not None :
656
+ vid = parse_uuid (uuid .NAMESPACE_DNS , self .vid )
657
+ payload = struct .pack (e + '16s' , vid )
658
+ prot_tlv .add ('UUID_VID' , payload )
659
+
660
+ if self .cid is not None :
661
+ if self .vid is not None :
662
+ namespace = uuid .UUID (bytes = vid )
663
+ else :
664
+ namespace = None
665
+ cid = parse_uuid (namespace , self .cid )
666
+ payload = struct .pack (e + '16s' , cid )
667
+ prot_tlv .add ('UUID_CID' , payload )
668
+
615
669
if custom_tlvs is not None :
616
670
for tag , value in custom_tlvs .items ():
617
671
prot_tlv .add (tag , value )
0 commit comments