mirror of https://github.com/ARMmbed/mbed-os.git
tools: tfm: Update bin_utils
parent
3d17e1646c
commit
6850192508
|
@ -14,4 +14,4 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
imgtool_version = "1.7.0rc1"
|
imgtool_version = "1.7.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Copyright 2018 Nordic Semiconductor ASA
|
# Copyright 2018 Nordic Semiconductor ASA
|
||||||
# Copyright 2017-2020 Linaro Limited
|
# Copyright 2017-2020 Linaro Limited
|
||||||
# Copyright 2019-2020 Arm Limited
|
# Copyright 2019-2021 Arm Limited
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -51,9 +51,11 @@ MAX_SW_TYPE_LENGTH = 12 # Bytes
|
||||||
# Image header flags.
|
# Image header flags.
|
||||||
IMAGE_F = {
|
IMAGE_F = {
|
||||||
'PIC': 0x0000001,
|
'PIC': 0x0000001,
|
||||||
|
'ENCRYPTED_AES128': 0x0000004,
|
||||||
|
'ENCRYPTED_AES256': 0x0000008,
|
||||||
'NON_BOOTABLE': 0x0000010,
|
'NON_BOOTABLE': 0x0000010,
|
||||||
'RAM_LOAD': 0x0000020,
|
'RAM_LOAD': 0x0000020,
|
||||||
'ENCRYPTED': 0x0000004,
|
'ROM_FIXED': 0x0000100,
|
||||||
}
|
}
|
||||||
|
|
||||||
TLV_VALUES = {
|
TLV_VALUES = {
|
||||||
|
@ -66,7 +68,7 @@ TLV_VALUES = {
|
||||||
'RSA3072': 0x23,
|
'RSA3072': 0x23,
|
||||||
'ED25519': 0x24,
|
'ED25519': 0x24,
|
||||||
'ENCRSA2048': 0x30,
|
'ENCRSA2048': 0x30,
|
||||||
'ENCKW128': 0x31,
|
'ENCKW': 0x31,
|
||||||
'ENCEC256': 0x32,
|
'ENCEC256': 0x32,
|
||||||
'ENCX25519': 0x33,
|
'ENCX25519': 0x33,
|
||||||
'DEPENDENCY': 0x40,
|
'DEPENDENCY': 0x40,
|
||||||
|
@ -132,7 +134,12 @@ class Image():
|
||||||
pad_header=False, pad=False, confirm=False, align=1,
|
pad_header=False, pad=False, confirm=False, align=1,
|
||||||
slot_size=0, max_sectors=DEFAULT_MAX_SECTORS,
|
slot_size=0, max_sectors=DEFAULT_MAX_SECTORS,
|
||||||
overwrite_only=False, endian="little", load_addr=0,
|
overwrite_only=False, endian="little", load_addr=0,
|
||||||
erased_val=None, save_enctlv=False, security_counter=None):
|
rom_fixed=None, erased_val=None, save_enctlv=False,
|
||||||
|
security_counter=None):
|
||||||
|
|
||||||
|
if load_addr and rom_fixed:
|
||||||
|
raise click.UsageError("Can not set rom_fixed and load_addr at the same time")
|
||||||
|
|
||||||
self.version = version or versmod.decode_version("0")
|
self.version = version or versmod.decode_version("0")
|
||||||
self.header_size = header_size
|
self.header_size = header_size
|
||||||
self.pad_header = pad_header
|
self.pad_header = pad_header
|
||||||
|
@ -145,6 +152,7 @@ class Image():
|
||||||
self.endian = endian
|
self.endian = endian
|
||||||
self.base_addr = None
|
self.base_addr = None
|
||||||
self.load_addr = 0 if load_addr is None else load_addr
|
self.load_addr = 0 if load_addr is None else load_addr
|
||||||
|
self.rom_fixed = rom_fixed
|
||||||
self.erased_val = 0xff if erased_val is None else int(erased_val, 0)
|
self.erased_val = 0xff if erased_val is None else int(erased_val, 0)
|
||||||
self.payload = []
|
self.payload = []
|
||||||
self.enckey = None
|
self.enckey = None
|
||||||
|
@ -281,7 +289,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):
|
sw_type=None, custom_tlvs=None, encrypt_keylen=128):
|
||||||
self.enckey = enckey
|
self.enckey = enckey
|
||||||
|
|
||||||
# Calculate the hash of the public key
|
# Calculate the hash of the public key
|
||||||
|
@ -347,9 +355,16 @@ class Image():
|
||||||
if self.enckey is not None:
|
if self.enckey is not None:
|
||||||
pad_len = len(self.payload) % 16
|
pad_len = len(self.payload) % 16
|
||||||
if pad_len > 0:
|
if pad_len > 0:
|
||||||
self.payload += bytes(16 - pad_len)
|
pad = bytes(16 - pad_len)
|
||||||
|
if isinstance(self.payload, bytes):
|
||||||
|
self.payload += pad
|
||||||
|
else:
|
||||||
|
self.payload.extend(pad)
|
||||||
|
|
||||||
# This adds the header to the payload as well
|
# This adds the header to the payload as well
|
||||||
|
if encrypt_keylen == 256:
|
||||||
|
self.add_header(enckey, protected_tlv_size, 256)
|
||||||
|
else:
|
||||||
self.add_header(enckey, protected_tlv_size)
|
self.add_header(enckey, protected_tlv_size)
|
||||||
|
|
||||||
prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC)
|
prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC)
|
||||||
|
@ -418,6 +433,9 @@ class Image():
|
||||||
self.payload = self.payload[:protected_tlv_off]
|
self.payload = self.payload[:protected_tlv_off]
|
||||||
|
|
||||||
if enckey is not None:
|
if enckey is not None:
|
||||||
|
if encrypt_keylen == 256:
|
||||||
|
plainkey = os.urandom(32)
|
||||||
|
else:
|
||||||
plainkey = os.urandom(16)
|
plainkey = os.urandom(16)
|
||||||
|
|
||||||
if isinstance(enckey, rsa.RSAPublic):
|
if isinstance(enckey, rsa.RSAPublic):
|
||||||
|
@ -451,16 +469,21 @@ class Image():
|
||||||
|
|
||||||
self.check_trailer()
|
self.check_trailer()
|
||||||
|
|
||||||
def add_header(self, enckey, protected_tlv_size):
|
def add_header(self, enckey, protected_tlv_size, aes_length=128):
|
||||||
"""Install the image header."""
|
"""Install the image header."""
|
||||||
|
|
||||||
flags = 0
|
flags = 0
|
||||||
if enckey is not None:
|
if enckey is not None:
|
||||||
flags |= IMAGE_F['ENCRYPTED']
|
if aes_length == 128:
|
||||||
|
flags |= IMAGE_F['ENCRYPTED_AES128']
|
||||||
|
else:
|
||||||
|
flags |= IMAGE_F['ENCRYPTED_AES256']
|
||||||
if self.load_addr != 0:
|
if self.load_addr != 0:
|
||||||
# Indicates that this image should be loaded into RAM
|
# Indicates that this image should be loaded into RAM
|
||||||
# instead of run directly from flash.
|
# instead of run directly from flash.
|
||||||
flags |= IMAGE_F['RAM_LOAD']
|
flags |= IMAGE_F['RAM_LOAD']
|
||||||
|
if self.rom_fixed:
|
||||||
|
flags |= IMAGE_F['ROM_FIXED']
|
||||||
|
|
||||||
e = STRUCT_ENDIAN_DICT[self.endian]
|
e = STRUCT_ENDIAN_DICT[self.endian]
|
||||||
fmt = (e +
|
fmt = (e +
|
||||||
|
@ -477,7 +500,7 @@ class Image():
|
||||||
assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE
|
assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE
|
||||||
header = struct.pack(fmt,
|
header = struct.pack(fmt,
|
||||||
IMAGE_MAGIC,
|
IMAGE_MAGIC,
|
||||||
self.load_addr,
|
self.rom_fixed or self.load_addr,
|
||||||
self.header_size,
|
self.header_size,
|
||||||
protected_tlv_size, # TLV Info header + Protected TLVs
|
protected_tlv_size, # TLV Info header + Protected TLVs
|
||||||
len(self.payload) - self.header_size, # ImageSz
|
len(self.payload) - self.header_size, # ImageSz
|
||||||
|
@ -537,16 +560,22 @@ class Image():
|
||||||
if magic != IMAGE_MAGIC:
|
if magic != IMAGE_MAGIC:
|
||||||
return VerifyResult.INVALID_MAGIC, None, None
|
return VerifyResult.INVALID_MAGIC, None, None
|
||||||
|
|
||||||
tlv_info = b[header_size+img_size:header_size+img_size+TLV_INFO_SIZE]
|
tlv_off = header_size + img_size
|
||||||
|
tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE]
|
||||||
magic, tlv_tot = struct.unpack('HH', tlv_info)
|
magic, tlv_tot = struct.unpack('HH', tlv_info)
|
||||||
|
if magic == TLV_PROT_INFO_MAGIC:
|
||||||
|
tlv_off += tlv_tot
|
||||||
|
tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE]
|
||||||
|
magic, tlv_tot = struct.unpack('HH', tlv_info)
|
||||||
|
|
||||||
if magic != TLV_INFO_MAGIC:
|
if magic != TLV_INFO_MAGIC:
|
||||||
return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None
|
return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None
|
||||||
|
|
||||||
sha = hashlib.sha256()
|
sha = hashlib.sha256()
|
||||||
sha.update(b[:header_size+img_size])
|
prot_tlv_size = tlv_off
|
||||||
|
sha.update(b[:prot_tlv_size])
|
||||||
digest = sha.digest()
|
digest = sha.digest()
|
||||||
|
|
||||||
tlv_off = header_size + img_size
|
|
||||||
tlv_end = tlv_off + tlv_tot
|
tlv_end = tlv_off + tlv_tot
|
||||||
tlv_off += TLV_INFO_SIZE # skip tlv info
|
tlv_off += TLV_INFO_SIZE # skip tlv info
|
||||||
while tlv_off < tlv_end:
|
while tlv_off < tlv_end:
|
||||||
|
@ -562,7 +591,7 @@ class Image():
|
||||||
elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]:
|
elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]:
|
||||||
off = tlv_off + TLV_SIZE
|
off = tlv_off + TLV_SIZE
|
||||||
tlv_sig = b[off:off+tlv_len]
|
tlv_sig = b[off:off+tlv_len]
|
||||||
payload = b[:header_size+img_size]
|
payload = b[:prot_tlv_size]
|
||||||
try:
|
try:
|
||||||
if hasattr(key, 'verify'):
|
if hasattr(key, 'verify'):
|
||||||
key.verify(tlv_sig, payload)
|
key.verify(tlv_sig, payload)
|
||||||
|
|
|
@ -46,7 +46,7 @@ class KeyClass(object):
|
||||||
|
|
||||||
def emit_rust_public(self, file=sys.stdout):
|
def emit_rust_public(self, file=sys.stdout):
|
||||||
self._emit(
|
self._emit(
|
||||||
header="static {}_PUB_KEY: &'static [u8] = &[".format(self.shortname().upper()),
|
header="static {}_PUB_KEY: &[u8] = &[".format(self.shortname().upper()),
|
||||||
trailer="];",
|
trailer="];",
|
||||||
encoded_bytes=self.get_public_bytes(),
|
encoded_bytes=self.get_public_bytes(),
|
||||||
indent=" ",
|
indent=" ",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2017-2020 Linaro Limited
|
# Copyright 2017-2020 Linaro Limited
|
||||||
# Copyright 2019-2020 Arm Limited
|
# Copyright 2019-2021 Arm Limited
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -241,6 +241,8 @@ class BasedIntParamType(click.ParamType):
|
||||||
help='Adjust address in hex output file.')
|
help='Adjust address in hex output file.')
|
||||||
@click.option('-L', '--load-addr', type=BasedIntParamType(), required=False,
|
@click.option('-L', '--load-addr', type=BasedIntParamType(), required=False,
|
||||||
help='Load address for image when it should run from RAM.')
|
help='Load address for image when it should run from RAM.')
|
||||||
|
@click.option('-F', '--rom-fixed', type=BasedIntParamType(), required=False,
|
||||||
|
help='Set flash address the image is built for.')
|
||||||
@click.option('--save-enctlv', default=False, is_flag=True,
|
@click.option('--save-enctlv', default=False, is_flag=True,
|
||||||
help='When upgrading, save encrypted key TLVs instead of plain '
|
help='When upgrading, save encrypted key TLVs instead of plain '
|
||||||
'keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option '
|
'keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option '
|
||||||
|
@ -248,6 +250,10 @@ class BasedIntParamType(click.ParamType):
|
||||||
@click.option('-E', '--encrypt', metavar='filename',
|
@click.option('-E', '--encrypt', metavar='filename',
|
||||||
help='Encrypt image using the provided public key. '
|
help='Encrypt image using the provided public key. '
|
||||||
'(Not supported in direct-xip or ram-load mode.)')
|
'(Not supported in direct-xip or ram-load mode.)')
|
||||||
|
@click.option('--encrypt-keylen', default='128',
|
||||||
|
type=click.Choice(['128','256']),
|
||||||
|
help='When encrypting the image using AES, select a 128 bit or '
|
||||||
|
'256 bit key len.')
|
||||||
@click.option('-e', '--endian', type=click.Choice(['little', 'big']),
|
@click.option('-e', '--endian', type=click.Choice(['little', 'big']),
|
||||||
default='little', help="Select little or big endian")
|
default='little', help="Select little or big endian")
|
||||||
@click.option('--overwrite-only', default=False, is_flag=True,
|
@click.option('--overwrite-only', default=False, is_flag=True,
|
||||||
|
@ -293,8 +299,9 @@ class BasedIntParamType(click.ParamType):
|
||||||
.hex extension, otherwise binary format is used''')
|
.hex extension, otherwise binary format is used''')
|
||||||
def sign(key, public_key_format, align, version, pad_sig, header_size,
|
def sign(key, public_key_format, align, version, pad_sig, header_size,
|
||||||
pad_header, slot_size, pad, confirm, max_sectors, overwrite_only,
|
pad_header, slot_size, pad, confirm, max_sectors, overwrite_only,
|
||||||
endian, encrypt, infile, outfile, dependencies, load_addr, hex_addr,
|
endian, encrypt_keylen, encrypt, infile, outfile, dependencies,
|
||||||
erased_val, save_enctlv, security_counter, boot_record, custom_tlv):
|
load_addr, hex_addr, erased_val, save_enctlv, security_counter,
|
||||||
|
boot_record, custom_tlv, rom_fixed):
|
||||||
|
|
||||||
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
|
||||||
|
@ -304,8 +311,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
|
||||||
pad_header=pad_header, pad=pad, confirm=confirm,
|
pad_header=pad_header, pad=pad, confirm=confirm,
|
||||||
align=int(align), slot_size=slot_size,
|
align=int(align), slot_size=slot_size,
|
||||||
max_sectors=max_sectors, overwrite_only=overwrite_only,
|
max_sectors=max_sectors, overwrite_only=overwrite_only,
|
||||||
endian=endian, load_addr=load_addr, erased_val=erased_val,
|
endian=endian, load_addr=load_addr, rom_fixed=rom_fixed,
|
||||||
save_enctlv=save_enctlv,
|
erased_val=erased_val, save_enctlv=save_enctlv,
|
||||||
security_counter=security_counter)
|
security_counter=security_counter)
|
||||||
img.load(infile)
|
img.load(infile)
|
||||||
key = load_key(key) if key else None
|
key = load_key(key) if key else None
|
||||||
|
@ -341,7 +348,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size,
|
||||||
custom_tlvs[tag] = value.encode('utf-8')
|
custom_tlvs[tag] = value.encode('utf-8')
|
||||||
|
|
||||||
img.create(key, public_key_format, enckey, dependencies, boot_record,
|
img.create(key, public_key_format, enckey, dependencies, boot_record,
|
||||||
custom_tlvs)
|
custom_tlvs, int(encrypt_keylen))
|
||||||
img.save(outfile, hex_addr)
|
img.save(outfile, hex_addr)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
#
|
#
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Copyright (c) 2019, Arm Limited. All rights reserved.
|
# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -11,7 +11,8 @@
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
expression_re = re.compile(r"[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?")
|
# Match (((x) + (y))) mode and ((x) + (y)) mode. x, y can be HEX or DEC value.
|
||||||
|
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*)*)[)]?[)]?[)]?)")
|
||||||
|
|
||||||
# Simple parser that takes a string and evaluates an expression from it.
|
# Simple parser that takes a string and evaluates an expression from it.
|
||||||
# The expression might contain additions and subtractions amongst numbers that
|
# The expression might contain additions and subtractions amongst numbers that
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
#
|
#
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Copyright (c) 2020, Arm Limited. All rights reserved.
|
# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -26,6 +26,7 @@ import macro_parser
|
||||||
|
|
||||||
sign_bin_size_re = re.compile(r"^\s*RE_SIGN_BIN_SIZE\s*=\s*(.*)")
|
sign_bin_size_re = re.compile(r"^\s*RE_SIGN_BIN_SIZE\s*=\s*(.*)")
|
||||||
load_addr_re = re.compile(r"^\s*RE_IMAGE_LOAD_ADDRESS\s*=\s*(.*)")
|
load_addr_re = re.compile(r"^\s*RE_IMAGE_LOAD_ADDRESS\s*=\s*(.*)")
|
||||||
|
rom_fixed_re = re.compile(r"^\s*RE_IMAGE_ROM_FIXED\s*=\s*(.*)")
|
||||||
|
|
||||||
#This works around Python 2 and Python 3 handling character encodings
|
#This works around Python 2 and Python 3 handling character encodings
|
||||||
#differently. More information about this issue at
|
#differently. More information about this issue at
|
||||||
|
@ -91,7 +92,7 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm,
|
||||||
|
|
||||||
slot_size = macro_parser.evaluate_macro(layout, sign_bin_size_re, 0, 1)
|
slot_size = macro_parser.evaluate_macro(layout, sign_bin_size_re, 0, 1)
|
||||||
load_addr = macro_parser.evaluate_macro(layout, load_addr_re, 0, 1)
|
load_addr = macro_parser.evaluate_macro(layout, load_addr_re, 0, 1)
|
||||||
|
rom_fixed = macro_parser.evaluate_macro(layout, rom_fixed_re, 0, 1)
|
||||||
if "_s" in layout:
|
if "_s" in layout:
|
||||||
boot_record = "SPE"
|
boot_record = "SPE"
|
||||||
elif "_ns" in layout:
|
elif "_ns" in layout:
|
||||||
|
@ -104,7 +105,8 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm,
|
||||||
pad=pad, confirm=confirm, align=int(align),
|
pad=pad, confirm=confirm, align=int(align),
|
||||||
slot_size=slot_size, max_sectors=max_sectors,
|
slot_size=slot_size, max_sectors=max_sectors,
|
||||||
overwrite_only=overwrite_only, endian=endian,
|
overwrite_only=overwrite_only, endian=endian,
|
||||||
load_addr=load_addr, erased_val=erased_val,
|
load_addr=load_addr, rom_fixed=rom_fixed,
|
||||||
|
erased_val=erased_val,
|
||||||
save_enctlv=save_enctlv,
|
save_enctlv=save_enctlv,
|
||||||
security_counter=security_counter)
|
security_counter=security_counter)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue