Commit dfce0be6 authored by Andrzej Puzdrowski's avatar Andrzej Puzdrowski Committed by David Brown
Browse files

imgtool: export data vector to be signed



Extend sign/create command so it allows to export image's byte string
which is the substrate for the image signature. The new option is
'--vector-to-sign'. It might takes 'payload' or 'digest'.
The exported data might be used to calculate the signature externally.

Signed-off-by: default avatarAndrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
parent f72e3741
...@@ -305,7 +305,7 @@ class Image(): ...@@ -305,7 +305,7 @@ class Image():
return cipherkey, ciphermac, pubk return cipherkey, ciphermac, pubk
def create(self, key, public_key_format, enckey, dependencies=None, def create(self, key, public_key_format, enckey, dependencies=None,
sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None): sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None, vector_to_sign=None):
self.enckey = enckey self.enckey = enckey
# Calculate the hash of the public key # Calculate the hash of the public key
...@@ -315,6 +315,8 @@ class Image(): ...@@ -315,6 +315,8 @@ class Image():
sha.update(pub) sha.update(pub)
pubbytes = sha.digest() pubbytes = sha.digest()
elif pub_key is not None: elif pub_key is not None:
if hasattr(pub_key, 'sign'):
print("sign the payload")
pub = pub_key.get_public_bytes() pub = pub_key.get_public_bytes()
sha = hashlib.sha256() sha = hashlib.sha256()
sha.update(pub) sha.update(pub)
...@@ -433,26 +435,34 @@ class Image(): ...@@ -433,26 +435,34 @@ class Image():
tlv.add('SHA256', digest) tlv.add('SHA256', digest)
if key is not None and fixed_sig is None: if public_key_format == 'hash':
if public_key_format == 'hash': tlv.add('KEYHASH', pubbytes)
tlv.add('KEYHASH', pubbytes) else:
else: tlv.add('PUBKEY', pub)
tlv.add('PUBKEY', pub)
if vector_to_sign == 'payload':
# Stop amending data to the image
# Just keep data vector which is expected to be sigend
print('export payload')
return
elif vector_to_sign == 'digest':
self.payload = digest
print('export digest')
return
if key is not None and fixed_sig is None:
# `sign` expects the full image payload (sha256 done internally), # `sign` expects the full image payload (sha256 done internally),
# while `sign_digest` expects only the digest of the payload # while `sign_digest` expects only the digest of the payload
if hasattr(key, 'sign'): if hasattr(key, 'sign'):
print("sign the payload")
sig = key.sign(bytes(self.payload)) sig = key.sign(bytes(self.payload))
else: else:
print("sign the digest")
sig = key.sign_digest(digest) sig = key.sign_digest(digest)
tlv.add(key.sig_tlv(), sig) tlv.add(key.sig_tlv(), sig)
self.signature = sig self.signature = sig
elif fixed_sig is not None and key is None: elif fixed_sig is not None and key is None:
if public_key_format == 'hash':
tlv.add('KEYHASH', pubbytes)
else:
tlv.add('PUBKEY', pub)
tlv.add(pub_key.sig_tlv(), fixed_sig['value']) tlv.add(pub_key.sig_tlv(), fixed_sig['value'])
self.signature = fixed_sig['value'] self.signature = fixed_sig['value']
else: else:
......
...@@ -321,6 +321,10 @@ class BasedIntParamType(click.ParamType): ...@@ -321,6 +321,10 @@ class BasedIntParamType(click.ParamType):
@click.option('--sig-out', metavar='filename', @click.option('--sig-out', metavar='filename',
help='Path to the file to which signature will be written' help='Path to the file to which signature will be written'
'The image signature will be encoded as base64 formatted string') 'The image signature will be encoded as base64 formatted string')
@click.option('--vector-to-sign', type=click.Choice(['payload', 'digest']),
help='send to OUTFILE the payload or payload''s digest instead of'
'complied image. These data can be used for external image'
'signing')
@click.command(help='''Create a signed or unsigned image\n @click.command(help='''Create a signed or unsigned image\n
INFILE and OUTFILE are parsed as Intel HEX if the params have INFILE and OUTFILE are parsed as Intel HEX if the params have
.hex extension, otherwise binary format is used''') .hex extension, otherwise binary format is used''')
...@@ -329,7 +333,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, ...@@ -329,7 +333,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
endian, encrypt_keylen, encrypt, infile, outfile, dependencies, endian, encrypt_keylen, encrypt, infile, outfile, dependencies,
load_addr, hex_addr, erased_val, save_enctlv, security_counter, load_addr, hex_addr, erased_val, save_enctlv, security_counter,
boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig,
fix_sig_pubkey, sig_out): fix_sig_pubkey, sig_out, vector_to_sign):
if confirm: if confirm:
# Confirmed but non-padded images don't make much sense, because # Confirmed but non-padded images don't make much sense, because
...@@ -393,7 +397,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, ...@@ -393,7 +397,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
} }
img.create(key, public_key_format, enckey, dependencies, boot_record, img.create(key, public_key_format, enckey, dependencies, boot_record,
custom_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key) custom_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key,
vector_to_sign)
img.save(outfile, hex_addr) img.save(outfile, hex_addr)
if sig_out is not None: if sig_out is not None:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment