Skip to content

Commit 6850192

Browse files
committed
tools: tfm: Update bin_utils
1 parent 3d17e16 commit 6850192

File tree

6 files changed

+67
-28
lines changed

6 files changed

+67
-28
lines changed

tools/psa/tfm/bin_utils/imgtool/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
imgtool_version = "1.7.0rc1"
17+
imgtool_version = "1.7.0"

tools/psa/tfm/bin_utils/imgtool/image.py

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright 2018 Nordic Semiconductor ASA
22
# Copyright 2017-2020 Linaro Limited
3-
# Copyright 2019-2020 Arm Limited
3+
# Copyright 2019-2021 Arm Limited
44
#
55
# SPDX-License-Identifier: Apache-2.0
66
#
@@ -51,9 +51,11 @@
5151
# Image header flags.
5252
IMAGE_F = {
5353
'PIC': 0x0000001,
54+
'ENCRYPTED_AES128': 0x0000004,
55+
'ENCRYPTED_AES256': 0x0000008,
5456
'NON_BOOTABLE': 0x0000010,
5557
'RAM_LOAD': 0x0000020,
56-
'ENCRYPTED': 0x0000004,
58+
'ROM_FIXED': 0x0000100,
5759
}
5860

5961
TLV_VALUES = {
@@ -66,7 +68,7 @@
6668
'RSA3072': 0x23,
6769
'ED25519': 0x24,
6870
'ENCRSA2048': 0x30,
69-
'ENCKW128': 0x31,
71+
'ENCKW': 0x31,
7072
'ENCEC256': 0x32,
7173
'ENCX25519': 0x33,
7274
'DEPENDENCY': 0x40,
@@ -132,7 +134,12 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
132134
pad_header=False, pad=False, confirm=False, align=1,
133135
slot_size=0, max_sectors=DEFAULT_MAX_SECTORS,
134136
overwrite_only=False, endian="little", load_addr=0,
135-
erased_val=None, save_enctlv=False, security_counter=None):
137+
rom_fixed=None, erased_val=None, save_enctlv=False,
138+
security_counter=None):
139+
140+
if load_addr and rom_fixed:
141+
raise click.UsageError("Can not set rom_fixed and load_addr at the same time")
142+
136143
self.version = version or versmod.decode_version("0")
137144
self.header_size = header_size
138145
self.pad_header = pad_header
@@ -145,6 +152,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
145152
self.endian = endian
146153
self.base_addr = None
147154
self.load_addr = 0 if load_addr is None else load_addr
155+
self.rom_fixed = rom_fixed
148156
self.erased_val = 0xff if erased_val is None else int(erased_val, 0)
149157
self.payload = []
150158
self.enckey = None
@@ -281,7 +289,7 @@ def ecies_hkdf(self, enckey, plainkey):
281289
return cipherkey, ciphermac, pubk
282290

283291
def create(self, key, public_key_format, enckey, dependencies=None,
284-
sw_type=None, custom_tlvs=None):
292+
sw_type=None, custom_tlvs=None, encrypt_keylen=128):
285293
self.enckey = enckey
286294

287295
# Calculate the hash of the public key
@@ -347,10 +355,17 @@ def create(self, key, public_key_format, enckey, dependencies=None,
347355
if self.enckey is not None:
348356
pad_len = len(self.payload) % 16
349357
if pad_len > 0:
350-
self.payload += bytes(16 - pad_len)
358+
pad = bytes(16 - pad_len)
359+
if isinstance(self.payload, bytes):
360+
self.payload += pad
361+
else:
362+
self.payload.extend(pad)
351363

352364
# This adds the header to the payload as well
353-
self.add_header(enckey, protected_tlv_size)
365+
if encrypt_keylen == 256:
366+
self.add_header(enckey, protected_tlv_size, 256)
367+
else:
368+
self.add_header(enckey, protected_tlv_size)
354369

355370
prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC)
356371

@@ -418,7 +433,10 @@ def create(self, key, public_key_format, enckey, dependencies=None,
418433
self.payload = self.payload[:protected_tlv_off]
419434

420435
if enckey is not None:
421-
plainkey = os.urandom(16)
436+
if encrypt_keylen == 256:
437+
plainkey = os.urandom(32)
438+
else:
439+
plainkey = os.urandom(16)
422440

423441
if isinstance(enckey, rsa.RSAPublic):
424442
cipherkey = enckey._get_public().encrypt(
@@ -451,16 +469,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
451469

452470
self.check_trailer()
453471

454-
def add_header(self, enckey, protected_tlv_size):
472+
def add_header(self, enckey, protected_tlv_size, aes_length=128):
455473
"""Install the image header."""
456474

457475
flags = 0
458476
if enckey is not None:
459-
flags |= IMAGE_F['ENCRYPTED']
477+
if aes_length == 128:
478+
flags |= IMAGE_F['ENCRYPTED_AES128']
479+
else:
480+
flags |= IMAGE_F['ENCRYPTED_AES256']
460481
if self.load_addr != 0:
461482
# Indicates that this image should be loaded into RAM
462483
# instead of run directly from flash.
463484
flags |= IMAGE_F['RAM_LOAD']
485+
if self.rom_fixed:
486+
flags |= IMAGE_F['ROM_FIXED']
464487

465488
e = STRUCT_ENDIAN_DICT[self.endian]
466489
fmt = (e +
@@ -477,7 +500,7 @@ def add_header(self, enckey, protected_tlv_size):
477500
assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE
478501
header = struct.pack(fmt,
479502
IMAGE_MAGIC,
480-
self.load_addr,
503+
self.rom_fixed or self.load_addr,
481504
self.header_size,
482505
protected_tlv_size, # TLV Info header + Protected TLVs
483506
len(self.payload) - self.header_size, # ImageSz
@@ -537,16 +560,22 @@ def verify(imgfile, key):
537560
if magic != IMAGE_MAGIC:
538561
return VerifyResult.INVALID_MAGIC, None, None
539562

540-
tlv_info = b[header_size+img_size:header_size+img_size+TLV_INFO_SIZE]
563+
tlv_off = header_size + img_size
564+
tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE]
541565
magic, tlv_tot = struct.unpack('HH', tlv_info)
566+
if magic == TLV_PROT_INFO_MAGIC:
567+
tlv_off += tlv_tot
568+
tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE]
569+
magic, tlv_tot = struct.unpack('HH', tlv_info)
570+
542571
if magic != TLV_INFO_MAGIC:
543572
return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None
544573

545574
sha = hashlib.sha256()
546-
sha.update(b[:header_size+img_size])
575+
prot_tlv_size = tlv_off
576+
sha.update(b[:prot_tlv_size])
547577
digest = sha.digest()
548578

549-
tlv_off = header_size + img_size
550579
tlv_end = tlv_off + tlv_tot
551580
tlv_off += TLV_INFO_SIZE # skip tlv info
552581
while tlv_off < tlv_end:
@@ -562,7 +591,7 @@ def verify(imgfile, key):
562591
elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]:
563592
off = tlv_off + TLV_SIZE
564593
tlv_sig = b[off:off+tlv_len]
565-
payload = b[:header_size+img_size]
594+
payload = b[:prot_tlv_size]
566595
try:
567596
if hasattr(key, 'verify'):
568597
key.verify(tlv_sig, payload)

tools/psa/tfm/bin_utils/imgtool/keys/general.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def emit_c_public(self, file=sys.stdout):
4646

4747
def emit_rust_public(self, file=sys.stdout):
4848
self._emit(
49-
header="static {}_PUB_KEY: &'static [u8] = &[".format(self.shortname().upper()),
49+
header="static {}_PUB_KEY: &[u8] = &[".format(self.shortname().upper()),
5050
trailer="];",
5151
encoded_bytes=self.get_public_bytes(),
5252
indent=" ",

tools/psa/tfm/bin_utils/imgtool/main.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#! /usr/bin/env python3
22
#
33
# Copyright 2017-2020 Linaro Limited
4-
# Copyright 2019-2020 Arm Limited
4+
# Copyright 2019-2021 Arm Limited
55
#
66
# SPDX-License-Identifier: Apache-2.0
77
#
@@ -241,13 +241,19 @@ def convert(self, value, param, ctx):
241241
help='Adjust address in hex output file.')
242242
@click.option('-L', '--load-addr', type=BasedIntParamType(), required=False,
243243
help='Load address for image when it should run from RAM.')
244+
@click.option('-F', '--rom-fixed', type=BasedIntParamType(), required=False,
245+
help='Set flash address the image is built for.')
244246
@click.option('--save-enctlv', default=False, is_flag=True,
245247
help='When upgrading, save encrypted key TLVs instead of plain '
246248
'keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option '
247249
'was set.')
248250
@click.option('-E', '--encrypt', metavar='filename',
249251
help='Encrypt image using the provided public key. '
250252
'(Not supported in direct-xip or ram-load mode.)')
253+
@click.option('--encrypt-keylen', default='128',
254+
type=click.Choice(['128','256']),
255+
help='When encrypting the image using AES, select a 128 bit or '
256+
'256 bit key len.')
251257
@click.option('-e', '--endian', type=click.Choice(['little', 'big']),
252258
default='little', help="Select little or big endian")
253259
@click.option('--overwrite-only', default=False, is_flag=True,
@@ -293,8 +299,9 @@ def convert(self, value, param, ctx):
293299
.hex extension, otherwise binary format is used''')
294300
def sign(key, public_key_format, align, version, pad_sig, header_size,
295301
pad_header, slot_size, pad, confirm, max_sectors, overwrite_only,
296-
endian, encrypt, infile, outfile, dependencies, load_addr, hex_addr,
297-
erased_val, save_enctlv, security_counter, boot_record, custom_tlv):
302+
endian, encrypt_keylen, encrypt, infile, outfile, dependencies,
303+
load_addr, hex_addr, erased_val, save_enctlv, security_counter,
304+
boot_record, custom_tlv, rom_fixed):
298305

299306
if confirm:
300307
# Confirmed but non-padded images don't make much sense, because
@@ -304,8 +311,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
304311
pad_header=pad_header, pad=pad, confirm=confirm,
305312
align=int(align), slot_size=slot_size,
306313
max_sectors=max_sectors, overwrite_only=overwrite_only,
307-
endian=endian, load_addr=load_addr, erased_val=erased_val,
308-
save_enctlv=save_enctlv,
314+
endian=endian, load_addr=load_addr, rom_fixed=rom_fixed,
315+
erased_val=erased_val, save_enctlv=save_enctlv,
309316
security_counter=security_counter)
310317
img.load(infile)
311318
key = load_key(key) if key else None
@@ -341,7 +348,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
341348
custom_tlvs[tag] = value.encode('utf-8')
342349

343350
img.create(key, public_key_format, enckey, dependencies, boot_record,
344-
custom_tlvs)
351+
custom_tlvs, int(encrypt_keylen))
345352
img.save(outfile, hex_addr)
346353

347354

tools/psa/tfm/bin_utils/macro_parser.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#! /usr/bin/env python3
22
#
33
# -----------------------------------------------------------------------------
4-
# Copyright (c) 2019, Arm Limited. All rights reserved.
4+
# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
55
#
66
# SPDX-License-Identifier: BSD-3-Clause
77
#
@@ -11,7 +11,8 @@
1111
import re
1212
import os
1313

14-
expression_re = re.compile(r"[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?")
14+
# Match (((x) + (y))) mode and ((x) + (y)) mode. x, y can be HEX or DEC value.
15+
expression_re = re.compile(r"([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?\s*([\+\-])\s*[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)|([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)")
1516

1617
# Simple parser that takes a string and evaluates an expression from it.
1718
# The expression might contain additions and subtractions amongst numbers that

tools/psa/tfm/bin_utils/wrapper.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#! /usr/bin/env python3
22
#
33
# -----------------------------------------------------------------------------
4-
# Copyright (c) 2020, Arm Limited. All rights reserved.
4+
# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
55
#
66
# SPDX-License-Identifier: BSD-3-Clause
77
#
@@ -26,6 +26,7 @@
2626

2727
sign_bin_size_re = re.compile(r"^\s*RE_SIGN_BIN_SIZE\s*=\s*(.*)")
2828
load_addr_re = re.compile(r"^\s*RE_IMAGE_LOAD_ADDRESS\s*=\s*(.*)")
29+
rom_fixed_re = re.compile(r"^\s*RE_IMAGE_ROM_FIXED\s*=\s*(.*)")
2930

3031
#This works around Python 2 and Python 3 handling character encodings
3132
#differently. More information about this issue at
@@ -91,7 +92,7 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm,
9192

9293
slot_size = macro_parser.evaluate_macro(layout, sign_bin_size_re, 0, 1)
9394
load_addr = macro_parser.evaluate_macro(layout, load_addr_re, 0, 1)
94-
95+
rom_fixed = macro_parser.evaluate_macro(layout, rom_fixed_re, 0, 1)
9596
if "_s" in layout:
9697
boot_record = "SPE"
9798
elif "_ns" in layout:
@@ -104,7 +105,8 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm,
104105
pad=pad, confirm=confirm, align=int(align),
105106
slot_size=slot_size, max_sectors=max_sectors,
106107
overwrite_only=overwrite_only, endian=endian,
107-
load_addr=load_addr, erased_val=erased_val,
108+
load_addr=load_addr, rom_fixed=rom_fixed,
109+
erased_val=erased_val,
108110
save_enctlv=save_enctlv,
109111
security_counter=security_counter)
110112

0 commit comments

Comments
 (0)