3030import hashlib
3131import array
3232import os .path
33+ import re
3334import struct
35+ import uuid
3436from enum import Enum
3537
3638import click
9698 'DECOMP_SHA' : 0x71 ,
9799 'DECOMP_SIGNATURE' : 0x72 ,
98100 'COMP_DEC_SIZE' : 0x73 ,
101+ 'UUID_VID' : 0x74 ,
102+ 'UUID_CID' : 0x75 ,
99103}
100104
101105TLV_SIZE = 4
@@ -254,6 +258,27 @@ def tlv_matches_key_type(tlv_type, key):
254258
255259 return False
256260
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+
257282
258283class Image :
259284
@@ -263,7 +288,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
263288 overwrite_only = False , endian = "little" , load_addr = 0 ,
264289 rom_fixed = None , erased_val = None , save_enctlv = False ,
265290 security_counter = None , max_align = None ,
266- non_bootable = False ):
291+ non_bootable = False , vid = None , cid = None ):
267292
268293 if load_addr and rom_fixed :
269294 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,
292317 self .enctlv_len = 0
293318 self .max_align = max (DEFAULT_MAX_ALIGN , align ) if max_align is None else int (max_align )
294319 self .non_bootable = non_bootable
320+ self .vid = vid
321+ self .cid = cid
295322
296323 if self .max_align == DEFAULT_MAX_ALIGN :
297324 self .boot_magic = bytes ([
@@ -321,7 +348,7 @@ def __repr__(self):
321348 return "<Image version={}, header_size={}, security_counter={}, \
322349 base_addr={}, load_addr={}, align={}, slot_size={}, \
323350 max_sectors={}, overwrite_only={}, endian={} format={}, \
324- payloadlen=0x{:x}>" .format (
351+ payloadlen=0x{:x}, vid={}, cid={} >" .format (
325352 self .version ,
326353 self .header_size ,
327354 self .security_counter ,
@@ -333,7 +360,9 @@ def __repr__(self):
333360 self .overwrite_only ,
334361 self .endian ,
335362 self .__class__ .__name__ ,
336- len (self .payload ))
363+ len (self .payload ),
364+ self .vid ,
365+ self .cid )
337366
338367 def load (self , path ):
339368 """Load an image from a given file"""
@@ -509,6 +538,16 @@ def create(self, key, public_key_format, enckey, dependencies=None,
509538 # = 4 + 4 = 8 Bytes
510539 protected_tlv_size += TLV_SIZE + 4
511540
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+
512551 if sw_type is not None :
513552 if len (sw_type ) > MAX_SW_TYPE_LENGTH :
514553 msg = "'{}' is too long ({} characters) for sw_type. Its " \
@@ -612,6 +651,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
612651 if compression_tlvs is not None :
613652 for tag , value in compression_tlvs .items ():
614653 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+
615669 if custom_tlvs is not None :
616670 for tag , value in custom_tlvs .items ():
617671 prot_tlv .add (tag , value )
0 commit comments