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