Add a way to specify custom TLVs.
Custom TLVs will be placed in the protected area.
Tag and value come from command line.
Values with 0x prefix will be interpreted as an integer, otherwise
it will be interpreted as a string.
Signed-off-by: Ihor Slabkyy <ihor.slabkyy@cypress.com>
diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py
index acb1794..40a72bd 100644
--- a/scripts/imgtool/image.py
+++ b/scripts/imgtool/image.py
@@ -109,7 +109,10 @@
Add a TLV record. Kind should be a string found in TLV_VALUES above.
"""
e = STRUCT_ENDIAN_DICT[self.endian]
- buf = struct.pack(e + 'BBH', TLV_VALUES[kind], 0, len(payload))
+ if isinstance(kind, int):
+ buf = struct.pack(e + 'BBH', kind, 0, len(payload))
+ else:
+ buf = struct.pack(e + 'BBH', TLV_VALUES[kind], 0, len(payload))
self.buf += buf
self.buf += payload
@@ -273,7 +276,7 @@
return cipherkey, ciphermac, pubk
def create(self, key, public_key_format, enckey, dependencies=None,
- sw_type=None):
+ sw_type=None, custom_tlvs=None):
self.enckey = enckey
# Calculate the hash of the public key
@@ -324,12 +327,24 @@
dependencies_num = len(dependencies[DEP_IMAGES_KEY])
protected_tlv_size += (dependencies_num * 16)
+ if custom_tlvs:
+ for value in custom_tlvs.values():
+ protected_tlv_size += TLV_SIZE + len(value)
+
if protected_tlv_size != 0:
# Add the size of the TLV info header
protected_tlv_size += TLV_INFO_SIZE
- # At this point the image is already on the payload, this adds
- # the header to the payload as well
+ # At this point the image is already on the payload
+ #
+ # This adds the padding if image is not aligned to the 16 Bytes
+ # in encrypted mode
+ if self.enckey is not None:
+ pad_len = len(self.payload) % 16
+ if pad_len > 0:
+ self.payload += bytes(16 - pad_len)
+
+ # This adds the header to the payload as well
self.add_header(enckey, protected_tlv_size)
prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC)
@@ -360,6 +375,9 @@
)
prot_tlv.add('DEPENDENCY', payload)
+ for tag, value in custom_tlvs.items():
+ prot_tlv.add(tag, value)
+
protected_tlv_off = len(self.payload)
self.payload += prot_tlv.get()
diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py
index bc96ca9..b16832d 100755
--- a/scripts/imgtool/main.py
+++ b/scripts/imgtool/main.py
@@ -225,6 +225,12 @@
@click.argument('outfile')
@click.argument('infile')
+@click.option('--custom-tlv', required=False, nargs=2, default=[],
+ multiple=True, metavar='[tag] [value]',
+ help='Custom TLV that will be placed into protected area. '
+ 'Add "0x" prefix if the value should be interpreted as an '
+ 'integer, otherwise it will be interpreted as a string. '
+ 'Specify the option multiple times to add multiple TLVs.')
@click.option('-R', '--erased-val', type=click.Choice(['0', '0xff']),
required=False,
help='The value that is read back from erased flash.')
@@ -282,7 +288,7 @@
def sign(key, public_key_format, align, version, pad_sig, header_size,
pad_header, slot_size, pad, confirm, max_sectors, overwrite_only,
endian, encrypt, infile, outfile, dependencies, load_addr, hex_addr,
- erased_val, save_enctlv, security_counter, boot_record):
+ erased_val, save_enctlv, security_counter, boot_record, custom_tlv):
img = image.Image(version=decode_version(version), header_size=header_size,
pad_header=pad_header, pad=pad, confirm=confirm,
align=int(align), slot_size=slot_size,
@@ -305,7 +311,26 @@
if pad_sig and hasattr(key, 'pad_sig'):
key.pad_sig = True
- img.create(key, public_key_format, enckey, dependencies, boot_record)
+ # Get list of custom protected TLVs from the command-line
+ custom_tlvs = {}
+ for tlv in custom_tlv:
+ tag = int(tlv[0], 0)
+ if tag in custom_tlvs:
+ raise click.UsageError('Custom TLV %s already exists.' % hex(tag))
+ if tag in image.TLV_VALUES.values():
+ raise click.UsageError(
+ 'Custom TLV %s conflicts with predefined TLV.' % hex(tag))
+
+ value = tlv[1]
+ if value.startswith('0x'):
+ if len(value[2:]) % 2:
+ raise click.UsageError('Custom TLV length is odd.')
+ custom_tlvs[tag] = bytes.fromhex(value[2:])
+ else:
+ custom_tlvs[tag] = value.encode('utf-8')
+
+ img.create(key, public_key_format, enckey, dependencies, boot_record,
+ custom_tlvs)
img.save(outfile, hex_addr)