From d09aa6b4f9fd788aba9433f48749f5b71db5882f Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Fri, 7 Jan 2022 16:48:58 +0100 Subject: [PATCH] imgtool: Add clear image generation with encryption capability Create an option to generate a clear image with encryption capability that can be installed on a primary slot. Since image has encryption capability image can be swapped encrypted in secondary slot Signed-off-by: Michel Jaouen --- scripts/imgtool/image.py | 17 +++++++++-------- scripts/imgtool/main.py | 8 ++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 2f0a1fa4..d04333ec 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -305,7 +305,7 @@ class Image(): return cipherkey, ciphermac, pubk def create(self, key, public_key_format, enckey, dependencies=None, - sw_type=None, custom_tlvs=None, encrypt_keylen=128): + sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False): self.enckey = enckey # Calculate the hash of the public key @@ -472,13 +472,14 @@ class Image(): else: tlv.add('ENCX25519', enctlv) - nonce = bytes([0] * 16) - cipher = Cipher(algorithms.AES(plainkey), modes.CTR(nonce), - backend=default_backend()) - encryptor = cipher.encryptor() - img = bytes(self.payload[self.header_size:]) - self.payload[self.header_size:] = \ - encryptor.update(img) + encryptor.finalize() + if not clear: + nonce = bytes([0] * 16) + cipher = Cipher(algorithms.AES(plainkey), modes.CTR(nonce), + backend=default_backend()) + encryptor = cipher.encryptor() + img = bytes(self.payload[self.header_size:]) + self.payload[self.header_size:] = \ + encryptor.update(img) + encryptor.finalize() self.payload += prot_tlv.get() self.payload += tlv.get() diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 87eccd99..e3f27751 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -254,6 +254,10 @@ class BasedIntParamType(click.ParamType): type=click.Choice(['128','256']), help='When encrypting the image using AES, select a 128 bit or ' '256 bit key len.') +@click.option('-c', '--clear', required=False, is_flag=True, default=False, + help='Output a non-encrypted image with encryption capabilities,' + 'so it can be installed in the primary slot, and encrypted ' + 'when swapped to the secondary.') @click.option('-e', '--endian', type=click.Choice(['little', 'big']), default='little', help="Select little or big endian") @click.option('--overwrite-only', default=False, is_flag=True, @@ -303,7 +307,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_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, - boot_record, custom_tlv, rom_fixed, max_align): + boot_record, custom_tlv, rom_fixed, max_align, clear): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -350,7 +354,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, custom_tlvs[tag] = value.encode('utf-8') img.create(key, public_key_format, enckey, dependencies, boot_record, - custom_tlvs, int(encrypt_keylen)) + custom_tlvs, int(encrypt_keylen), clear) img.save(outfile, hex_addr)