aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/binman/btool/openssl.py244
-rw-r--r--tools/binman/entries.rst113
-rw-r--r--tools/binman/etype/ti_board_config.py259
-rw-r--r--tools/binman/etype/ti_secure.py78
-rw-r--r--tools/binman/etype/ti_secure_rom.py249
-rw-r--r--tools/binman/etype/x509_cert.py87
-rw-r--r--tools/binman/ftest.py90
-rw-r--r--tools/binman/image.py2
-rw-r--r--tools/binman/test/277_ti_board_cfg.dts14
-rw-r--r--tools/binman/test/278_ti_board_cfg_combined.dts25
-rw-r--r--tools/binman/test/279_ti_board_cfg_no_type.dts11
-rw-r--r--tools/binman/test/279_ti_secure.dts17
-rw-r--r--tools/binman/test/280_ti_secure_rom.dts17
-rw-r--r--tools/binman/test/281_ti_secure_rom_combined.dts25
-rw-r--r--tools/binman/test/288_ti_secure_rom_a.dts19
-rw-r--r--tools/binman/test/289_ti_secure_rom_b.dts18
-rw-r--r--tools/binman/test/yaml/config.yaml18
-rw-r--r--tools/binman/test/yaml/schema.yaml49
-rw-r--r--tools/binman/test/yaml/schema_notype.yaml38
-rw-r--r--tools/buildman/requirements.txt2
-rwxr-xr-xtools/k3_fit_atf.sh123
-rwxr-xr-xtools/k3_gen_x509_cert.sh262
22 files changed, 1365 insertions, 395 deletions
diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
index 3a4dbdd6d7..aad3b61ae2 100644
--- a/tools/binman/btool/openssl.py
+++ b/tools/binman/btool/openssl.py
@@ -15,6 +15,13 @@ import hashlib
from binman import bintool
from u_boot_pylib import tools
+
+VALID_SHAS = [256, 384, 512, 224]
+SHA_OIDS = {256:'2.16.840.1.101.3.4.2.1',
+ 384:'2.16.840.1.101.3.4.2.2',
+ 512:'2.16.840.1.101.3.4.2.3',
+ 224:'2.16.840.1.101.3.4.2.4'}
+
class Bintoolopenssl(bintool.Bintool):
"""openssl tool
@@ -74,6 +81,243 @@ imageSize = INTEGER:{len(indata)}
'-sha512']
return self.run_cmd(*args)
+ def x509_cert_sysfw(self, cert_fname, input_fname, key_fname, sw_rev,
+ config_fname, req_dist_name_dict):
+ """Create a certificate to be booted by system firmware
+
+ Args:
+ cert_fname (str): Filename of certificate to create
+ input_fname (str): Filename containing data to sign
+ key_fname (str): Filename of .pem file
+ sw_rev (int): Software revision
+ config_fname (str): Filename to write fconfig into
+ req_dist_name_dict (dict): Dictionary containing key-value pairs of
+ req_distinguished_name section extensions, must contain extensions for
+ C, ST, L, O, OU, CN and emailAddress
+
+ Returns:
+ str: Tool output
+ """
+ indata = tools.read_file(input_fname)
+ hashval = hashlib.sha512(indata).hexdigest()
+ with open(config_fname, 'w', encoding='utf-8') as outf:
+ print(f'''[ req ]
+distinguished_name = req_distinguished_name
+x509_extensions = v3_ca
+prompt = no
+dirstring_type = nobmp
+
+[ req_distinguished_name ]
+C = {req_dist_name_dict['C']}
+ST = {req_dist_name_dict['ST']}
+L = {req_dist_name_dict['L']}
+O = {req_dist_name_dict['O']}
+OU = {req_dist_name_dict['OU']}
+CN = {req_dist_name_dict['CN']}
+emailAddress = {req_dist_name_dict['emailAddress']}
+
+[ v3_ca ]
+basicConstraints = CA:true
+1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
+1.3.6.1.4.1.294.1.34 = ASN1:SEQUENCE:sysfw_image_integrity
+1.3.6.1.4.1.294.1.35 = ASN1:SEQUENCE:sysfw_image_load
+
+[ swrv ]
+swrv = INTEGER:{sw_rev}
+
+[ sysfw_image_integrity ]
+shaType = OID:2.16.840.1.101.3.4.2.3
+shaValue = FORMAT:HEX,OCT:{hashval}
+imageSize = INTEGER:{len(indata)}
+
+[ sysfw_image_load ]
+destAddr = FORMAT:HEX,OCT:00000000
+authInPlace = INTEGER:2
+''', file=outf)
+ args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
+ '-outform', 'DER', '-out', cert_fname, '-config', config_fname,
+ '-sha512']
+ return self.run_cmd(*args)
+
+ def x509_cert_rom(self, cert_fname, input_fname, key_fname, sw_rev,
+ config_fname, req_dist_name_dict, cert_type, bootcore,
+ bootcore_opts, load_addr, sha):
+ """Create a certificate
+
+ Args:
+ cert_fname (str): Filename of certificate to create
+ input_fname (str): Filename containing data to sign
+ key_fname (str): Filename of .pem file
+ sw_rev (int): Software revision
+ config_fname (str): Filename to write fconfig into
+ req_dist_name_dict (dict): Dictionary containing key-value pairs of
+ req_distinguished_name section extensions, must contain extensions for
+ C, ST, L, O, OU, CN and emailAddress
+ cert_type (int): Certification type
+ bootcore (int): Booting core
+ load_addr (int): Load address of image
+ sha (int): Hash function
+
+ Returns:
+ str: Tool output
+ """
+ indata = tools.read_file(input_fname)
+ hashval = hashlib.sha512(indata).hexdigest()
+ with open(config_fname, 'w', encoding='utf-8') as outf:
+ print(f'''
+[ req ]
+ distinguished_name = req_distinguished_name
+ x509_extensions = v3_ca
+ prompt = no
+ dirstring_type = nobmp
+
+ [ req_distinguished_name ]
+C = {req_dist_name_dict['C']}
+ST = {req_dist_name_dict['ST']}
+L = {req_dist_name_dict['L']}
+O = {req_dist_name_dict['O']}
+OU = {req_dist_name_dict['OU']}
+CN = {req_dist_name_dict['CN']}
+emailAddress = {req_dist_name_dict['emailAddress']}
+
+ [ v3_ca ]
+ basicConstraints = CA:true
+ 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
+ 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
+ 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
+# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
+ 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug
+
+ [ boot_seq ]
+ certType = INTEGER:{cert_type}
+ bootCore = INTEGER:{bootcore}
+ bootCoreOpts = INTEGER:{bootcore_opts}
+ destAddr = FORMAT:HEX,OCT:{load_addr:08x}
+ imageSize = INTEGER:{len(indata)}
+
+ [ image_integrity ]
+ shaType = OID:{SHA_OIDS[sha]}
+ shaValue = FORMAT:HEX,OCT:{hashval}
+
+ [ swrv ]
+ swrv = INTEGER:{sw_rev}
+
+# [ encryption ]
+# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
+# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
+# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
+# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
+
+ [ debug ]
+ debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
+ debugType = INTEGER:4
+ coreDbgEn = INTEGER:0
+ coreDbgSecEn = INTEGER:0
+''', file=outf)
+ args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
+ '-outform', 'DER', '-out', cert_fname, '-config', config_fname,
+ '-sha512']
+ return self.run_cmd(*args)
+
+ def x509_cert_rom_combined(self, cert_fname, input_fname, key_fname, sw_rev,
+ config_fname, req_dist_name_dict, load_addr, sha, total_size, num_comps,
+ sysfw_inner_cert_ext_boot_sequence_string, dm_data_ext_boot_sequence_string,
+ imagesize_sbl, hashval_sbl, load_addr_sysfw, imagesize_sysfw,
+ hashval_sysfw, load_addr_sysfw_data, imagesize_sysfw_data,
+ hashval_sysfw_data, sysfw_inner_cert_ext_boot_block,
+ dm_data_ext_boot_block):
+ """Create a certificate
+
+ Args:
+ cert_fname (str): Filename of certificate to create
+ input_fname (str): Filename containing data to sign
+ key_fname (str): Filename of .pem file
+ sw_rev (int): Software revision
+ config_fname (str): Filename to write fconfig into
+ req_dist_name_dict (dict): Dictionary containing key-value pairs of
+ req_distinguished_name section extensions, must contain extensions for
+ C, ST, L, O, OU, CN and emailAddress
+ cert_type (int): Certification type
+ bootcore (int): Booting core
+ load_addr (int): Load address of image
+ sha (int): Hash function
+
+ Returns:
+ str: Tool output
+ """
+ indata = tools.read_file(input_fname)
+ hashval = hashlib.sha512(indata).hexdigest()
+ sha_type = SHA_OIDS[sha]
+ with open(config_fname, 'w', encoding='utf-8') as outf:
+ print(f'''
+[ req ]
+distinguished_name = req_distinguished_name
+x509_extensions = v3_ca
+prompt = no
+dirstring_type = nobmp
+
+[ req_distinguished_name ]
+C = {req_dist_name_dict['C']}
+ST = {req_dist_name_dict['ST']}
+L = {req_dist_name_dict['L']}
+O = {req_dist_name_dict['O']}
+OU = {req_dist_name_dict['OU']}
+CN = {req_dist_name_dict['CN']}
+emailAddress = {req_dist_name_dict['emailAddress']}
+
+[ v3_ca ]
+basicConstraints = CA:true
+1.3.6.1.4.1.294.1.3=ASN1:SEQUENCE:swrv
+1.3.6.1.4.1.294.1.9=ASN1:SEQUENCE:ext_boot_info
+
+[swrv]
+swrv=INTEGER:{sw_rev}
+
+[ext_boot_info]
+extImgSize=INTEGER:{total_size}
+numComp=INTEGER:{num_comps}
+sbl=SEQUENCE:sbl
+sysfw=SEQUENCE:sysfw
+sysfw_data=SEQUENCE:sysfw_data
+{sysfw_inner_cert_ext_boot_sequence_string}
+{dm_data_ext_boot_sequence_string}
+
+[sbl]
+compType = INTEGER:1
+bootCore = INTEGER:16
+compOpts = INTEGER:0
+destAddr = FORMAT:HEX,OCT:{load_addr:08x}
+compSize = INTEGER:{imagesize_sbl}
+shaType = OID:{sha_type}
+shaValue = FORMAT:HEX,OCT:{hashval_sbl}
+
+[sysfw]
+compType = INTEGER:2
+bootCore = INTEGER:0
+compOpts = INTEGER:0
+destAddr = FORMAT:HEX,OCT:{load_addr_sysfw:08x}
+compSize = INTEGER:{imagesize_sysfw}
+shaType = OID:{sha_type}
+shaValue = FORMAT:HEX,OCT:{hashval_sysfw}
+
+[sysfw_data]
+compType = INTEGER:18
+bootCore = INTEGER:0
+compOpts = INTEGER:0
+destAddr = FORMAT:HEX,OCT:{load_addr_sysfw_data:08x}
+compSize = INTEGER:{imagesize_sysfw_data}
+shaType = OID:{sha_type}
+shaValue = FORMAT:HEX,OCT:{hashval_sysfw_data}
+
+{sysfw_inner_cert_ext_boot_block}
+
+{dm_data_ext_boot_block}
+ ''', file=outf)
+ args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
+ '-outform', 'DER', '-out', cert_fname, '-config', config_fname,
+ '-sha512']
+ return self.run_cmd(*args)
+
def fetch(self, method):
"""Fetch handler for openssl
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index b55f424620..1621ff30ca 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1664,6 +1664,119 @@ by setting the size of the entry to something larger than the text.
+.. _etype_ti_board_config:
+
+Entry: ti-board-config: An entry containing a TI schema validated board config binary
+-------------------------------------------------------------------------------------
+
+This etype supports generation of two kinds of board configuration
+binaries: singular board config binary as well as combined board config
+binary.
+
+Properties / Entry arguments:
+ - config-file: File containing board configuration data in YAML
+ - schema-file: File containing board configuration YAML schema against
+ which the config file is validated
+
+Output files:
+ - board config binary: File containing board configuration binary
+
+These above parameters are used only when the generated binary is
+intended to be a single board configuration binary. Example::
+
+ my-ti-board-config {
+ ti-board-config {
+ config = "board-config.yaml";
+ schema = "schema.yaml";
+ };
+ };
+
+To generate a combined board configuration binary, we pack the
+needed individual binaries into a ti-board-config binary. In this case,
+the available supported subnode names are board-cfg, pm-cfg, sec-cfg and
+rm-cfg. The final binary is prepended with a header containing details about
+the included board config binaries. Example::
+
+ my-combined-ti-board-config {
+ ti-board-config {
+ board-cfg {
+ config = "board-cfg.yaml";
+ schema = "schema.yaml";
+ };
+ sec-cfg {
+ config = "sec-cfg.yaml";
+ schema = "schema.yaml";
+ };
+ }
+ }
+
+
+
+.. _etype_ti_secure:
+
+Entry: ti-secure: Entry containing a TI x509 certificate binary
+---------------------------------------------------------------
+
+Properties / Entry arguments:
+ - content: List of phandles to entries to sign
+ - keyfile: Filename of file containing key to sign binary with
+ - sha: Hash function to be used for signing
+
+Output files:
+ - input.<unique_name> - input file passed to openssl
+ - config.<unique_name> - input file generated for openssl (which is
+ used as the config file)
+ - cert.<unique_name> - output file generated by openssl (which is
+ used as the entry contents)
+
+openssl signs the provided data, using the TI templated config file and
+writes the signature in this entry. This allows verification that the
+data is genuine.
+
+
+
+.. _etype_ti_secure_rom:
+
+Entry: ti-secure-rom: Entry containing a TI x509 certificate binary for images booted by ROM
+--------------------------------------------------------------------------------------------
+
+Properties / Entry arguments:
+ - keyfile: Filename of file containing key to sign binary with
+ - combined: boolean if device follows combined boot flow
+ - countersign: boolean if device contains countersigned system firmware
+ - load: load address of SPL
+ - sw-rev: software revision
+ - sha: Hash function to be used for signing
+ - core: core on which bootloader runs, valid cores are 'secure' and 'public'
+ - content: phandle of SPL in case of legacy bootflow or phandles of component binaries
+ in case of combined bootflow
+
+The following properties are only for generating a combined bootflow binary:
+ - sysfw-inner-cert: boolean if binary contains sysfw inner certificate
+ - dm-data: boolean if binary contains dm-data binary
+ - content-sbl: phandle of SPL binary
+ - content-sysfw: phandle of sysfw binary
+ - content-sysfw-data: phandle of sysfw-data or tifs-data binary
+ - content-sysfw-inner-cert (optional): phandle of sysfw inner certificate binary
+ - content-dm-data (optional): phandle of dm-data binary
+ - load-sysfw: load address of sysfw binary
+ - load-sysfw-data: load address of sysfw-data or tifs-data binary
+ - load-sysfw-inner-cert (optional): load address of sysfw inner certificate binary
+ - load-dm-data (optional): load address of dm-data binary
+
+Output files:
+ - input.<unique_name> - input file passed to openssl
+ - config.<unique_name> - input file generated for openssl (which is
+ used as the config file)
+ - cert.<unique_name> - output file generated by openssl (which is
+ used as the entry contents)
+
+openssl signs the provided data, using the TI templated config file and
+writes the signature in this entry. This allows verification that the
+data is genuine.
+
+
+
.. _etype_u_boot:
Entry: u-boot: U-Boot flat binary
diff --git a/tools/binman/etype/ti_board_config.py b/tools/binman/etype/ti_board_config.py
new file mode 100644
index 0000000000..94f894c281
--- /dev/null
+++ b/tools/binman/etype/ti_board_config.py
@@ -0,0 +1,259 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+# Written by Neha Malcom Francis <n-francis@ti.com>
+#
+# Entry-type module for generating schema validated TI board
+# configuration binary
+#
+
+import os
+import struct
+import yaml
+
+from collections import OrderedDict
+from jsonschema import validate
+from shutil import copyfileobj
+
+from binman.entry import Entry
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+BOARDCFG = 0xB
+BOARDCFG_SEC = 0xD
+BOARDCFG_PM = 0xE
+BOARDCFG_RM = 0xC
+BOARDCFG_NUM_ELEMS = 4
+
+class Entry_ti_board_config(Entry_section):
+ """An entry containing a TI schema validated board config binary
+
+ This etype supports generation of two kinds of board configuration
+ binaries: singular board config binary as well as combined board config
+ binary.
+
+ Properties / Entry arguments:
+ - config-file: File containing board configuration data in YAML
+ - schema-file: File containing board configuration YAML schema against
+ which the config file is validated
+
+ Output files:
+ - board config binary: File containing board configuration binary
+
+ These above parameters are used only when the generated binary is
+ intended to be a single board configuration binary. Example::
+
+ my-ti-board-config {
+ ti-board-config {
+ config = "board-config.yaml";
+ schema = "schema.yaml";
+ };
+ };
+
+ To generate a combined board configuration binary, we pack the
+ needed individual binaries into a ti-board-config binary. In this case,
+ the available supported subnode names are board-cfg, pm-cfg, sec-cfg and
+ rm-cfg. The final binary is prepended with a header containing details about
+ the included board config binaries. Example::
+
+ my-combined-ti-board-config {
+ ti-board-config {
+ board-cfg {
+ config = "board-cfg.yaml";
+ schema = "schema.yaml";
+ };
+ sec-cfg {
+ config = "sec-cfg.yaml";
+ schema = "schema.yaml";
+ };
+ }
+ }
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self._config = None
+ self._schema = None
+ self._entries = OrderedDict()
+ self._num_elems = BOARDCFG_NUM_ELEMS
+ self._fmt = '<HHHBB'
+ self._index = 0
+ self._binary_offset = 0
+ self._sw_rev = 1
+ self._devgrp = 0
+
+ def ReadNode(self):
+ super().ReadNode()
+ self._config = fdt_util.GetString(self._node, 'config')
+ self._schema = fdt_util.GetString(self._node, 'schema')
+ # Depending on whether config file is present in node, we determine
+ # whether it is a combined board config binary or not
+ if self._config is None:
+ self.ReadEntries()
+ else:
+ self._config_file = tools.get_input_filename(self._config)
+ self._schema_file = tools.get_input_filename(self._schema)
+
+ def ReadEntries(self):
+ """Read the subnodes to find out what should go in this image
+ """
+ for node in self._node.subnodes:
+ if 'type' not in node.props:
+ entry = Entry.Create(self, node, 'ti-board-config')
+ entry.ReadNode()
+ cfg_data = entry.BuildSectionData(True)
+ entry._cfg_data = cfg_data
+ self._entries[entry.name] = entry
+ self._num_elems = len(self._node.subnodes)
+
+ def _convert_to_byte_chunk(self, val, data_type):
+ """Convert value into byte array
+
+ Args:
+ val: value to convert into byte array
+ data_type: data type used in schema, supported data types are u8,
+ u16 and u32
+
+ Returns:
+ array of bytes representing value
+ """
+ size = 0
+ if (data_type == '#/definitions/u8'):
+ size = 1
+ elif (data_type == '#/definitions/u16'):
+ size = 2
+ else:
+ size = 4
+ if type(val) == int:
+ br = val.to_bytes(size, byteorder='little')
+ return br
+
+ def _compile_yaml(self, schema_yaml, file_yaml):
+ """Convert YAML file into byte array based on YAML schema
+
+ Args:
+ schema_yaml: file containing YAML schema
+ file_yaml: file containing config to compile
+
+ Returns:
+ array of bytes repesenting YAML file against YAML schema
+ """
+ br = bytearray()
+ for key, node in file_yaml.items():
+ node_schema = schema_yaml['properties'][key]
+ node_type = node_schema.get('type')
+ if not 'type' in node_schema:
+ br += self._convert_to_byte_chunk(node,
+ node_schema.get('$ref'))
+ elif node_type == 'object':
+ br += self._compile_yaml(node_schema, node)
+ elif node_type == 'array':
+ for item in node:
+ if not isinstance(item, dict):
+ br += self._convert_to_byte_chunk(
+ item, schema_yaml['properties'][key]['items']['$ref'])
+ else:
+ br += self._compile_yaml(node_schema.get('items'), item)
+ return br
+
+ def _generate_binaries(self):
+ """Generate config binary artifacts from the loaded YAML configuration file
+
+ Returns:
+ byte array containing config binary artifacts
+ or None if generation fails
+ """
+ cfg_binary = bytearray()
+ for key, node in self.file_yaml.items():
+ node_schema = self.schema_yaml['properties'][key]
+ br = self._compile_yaml(node_schema, node)
+ cfg_binary += br
+ return cfg_binary
+
+ def _add_boardcfg(self, bcfgtype, bcfgdata):
+ """Add board config to combined board config binary
+
+ Args:
+ bcfgtype (int): board config type
+ bcfgdata (byte array): board config data
+ """
+ size = len(bcfgdata)
+ desc = struct.pack(self._fmt, bcfgtype,
+ self._binary_offset, size, self._devgrp, 0)
+ with open(self.descfile, 'ab+') as desc_fh:
+ desc_fh.write(desc)
+ with open(self.bcfgfile, 'ab+') as bcfg_fh:
+ bcfg_fh.write(bcfgdata)
+ self._binary_offset += size
+ self._index += 1
+
+ def _finalize(self):
+ """Generate final combined board config binary
+
+ Returns:
+ byte array containing combined board config data
+ or None if unable to generate
+ """
+ with open(self.descfile, 'rb') as desc_fh:
+ with open(self.bcfgfile, 'rb') as bcfg_fh:
+ with open(self.fh_file, 'ab+') as fh:
+ copyfileobj(desc_fh, fh)
+ copyfileobj(bcfg_fh, fh)
+ data = tools.read_file(self.fh_file)
+ return data
+
+ def BuildSectionData(self, required):
+ if self._config is None:
+ self._binary_offset = 0
+ uniq = self.GetUniqueName()
+ self.fh_file = tools.get_output_filename('fh.%s' % uniq)
+ self.descfile = tools.get_output_filename('desc.%s' % uniq)
+ self.bcfgfile = tools.get_output_filename('bcfg.%s' % uniq)
+
+ # when binman runs again make sure we start clean
+ if os.path.exists(self.fh_file):
+ os.remove(self.fh_file)
+ if os.path.exists(self.descfile):
+ os.remove(self.descfile)
+ if os.path.exists(self.bcfgfile):
+ os.remove(self.bcfgfile)
+
+ with open(self.fh_file, 'wb') as f:
+ t_bytes = f.write(struct.pack(
+ '<BB', self._num_elems, self._sw_rev))
+ self._binary_offset += t_bytes
+ self._binary_offset += self._num_elems * struct.calcsize(self._fmt)
+
+ if 'board-cfg' in self._entries:
+ self._add_boardcfg(BOARDCFG, self._entries['board-cfg']._cfg_data)
+
+ if 'sec-cfg' in self._entries:
+ self._add_boardcfg(BOARDCFG_SEC, self._entries['sec-cfg']._cfg_data)
+
+ if 'pm-cfg' in self._entries:
+ self._add_boardcfg(BOARDCFG_PM, self._entries['pm-cfg']._cfg_data)
+
+ if 'rm-cfg' in self._entries:
+ self._add_boardcfg(BOARDCFG_RM, self._entries['rm-cfg']._cfg_data)
+
+ data = self._finalize()
+ return data
+
+ else:
+ with open(self._config_file, 'r') as f:
+ self.file_yaml = yaml.safe_load(f)
+ with open(self._schema_file, 'r') as sch:
+ self.schema_yaml = yaml.safe_load(sch)
+
+ try:
+ validate(self.file_yaml, self.schema_yaml)
+ except Exception as e:
+ self.Raise(f"Schema validation error: {e}")
+
+ data = self._generate_binaries()
+ return data
+
+ def SetImagePos(self, image_pos):
+ Entry.SetImagePos(self, image_pos)
+
+ def CheckEntries(self):
+ Entry.CheckEntries(self)
diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
new file mode 100644
index 0000000000..d939dce571
--- /dev/null
+++ b/tools/binman/etype/ti_secure.py
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+# Written by Neha Malcom Francis <n-francis@ti.com>
+#
+
+# Support for generation of TI secured binary blobs
+
+from binman.entry import EntryArg
+from binman.etype.x509_cert import Entry_x509_cert
+
+from dtoc import fdt_util
+
+class Entry_ti_secure(Entry_x509_cert):
+ """Entry containing a TI x509 certificate binary
+
+ Properties / Entry arguments:
+ - content: List of phandles to entries to sign
+ - keyfile: Filename of file containing key to sign binary with
+ - sha: Hash function to be used for signing
+
+ Output files:
+ - input.<unique_name> - input file passed to openssl
+ - config.<unique_name> - input file generated for openssl (which is
+ used as the config file)
+ - cert.<unique_name> - output file generated by openssl (which is
+ used as the entry contents)
+
+ openssl signs the provided data, using the TI templated config file and
+ writes the signature in this entry. This allows verification that the
+ data is genuine.
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.openssl = None
+
+ def ReadNode(self):
+ super().ReadNode()
+ self.key_fname = self.GetEntryArgsOrProps([
+ EntryArg('keyfile', str)], required=True)[0]
+ self.sha = fdt_util.GetInt(self._node, 'sha', 512)
+ self.req_dist_name = {'C': 'US',
+ 'ST': 'TX',
+ 'L': 'Dallas',
+ 'O': 'Texas Instruments Incorporated',
+ 'OU': 'Processors',
+ 'CN': 'TI Support',
+ 'emailAddress': 'support@ti.com'}
+
+ def GetCertificate(self, required):
+ """Get the contents of this entry
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry, which is the certificate binary for the
+ provided data
+ """
+ return super().GetCertificate(required=required, type='sysfw')
+
+ def ObtainContents(self):
+ data = self.data
+ if data is None:
+ data = self.GetCertificate(False)
+ if data is None:
+ return False
+ self.SetContents(data)
+ return True
+
+ def ProcessContents(self):
+ # The blob may have changed due to WriteSymbols()
+ data = self.data
+ return self.ProcessContentsUpdate(data)
+
+ def AddBintools(self, btools):
+ super().AddBintools(btools)
+ self.openssl = self.AddBintool(btools, 'openssl')
diff --git a/tools/binman/etype/ti_secure_rom.py b/tools/binman/etype/ti_secure_rom.py
new file mode 100644
index 0000000000..9a7ac9e9e0
--- /dev/null
+++ b/tools/binman/etype/ti_secure_rom.py
@@ -0,0 +1,249 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+# Written by Neha Malcom Francis <n-francis@ti.com>
+#
+
+# Support for generation of TI secured bootloaders booted by ROM
+
+from binman.entry import EntryArg
+from binman.etype.x509_cert import Entry_x509_cert
+
+import hashlib
+
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+VALID_SHAS = [256, 384, 512, 224]
+SHA_OIDS = {256:'2.16.840.1.101.3.4.2.1',
+ 384:'2.16.840.1.101.3.4.2.2',
+ 512:'2.16.840.1.101.3.4.2.3',
+ 224:'2.16.840.1.101.3.4.2.4'}
+
+class Entry_ti_secure_rom(Entry_x509_cert):
+ """Entry containing a TI x509 certificate binary for images booted by ROM
+
+ Properties / Entry arguments:
+ - keyfile: Filename of file containing key to sign binary with
+ - combined: boolean if device follows combined boot flow
+ - countersign: boolean if device contains countersigned system firmware
+ - load: load address of SPL
+ - sw-rev: software revision
+ - sha: Hash function to be used for signing
+ - core: core on which bootloader runs, valid cores are 'secure' and 'public'
+ - content: phandle of SPL in case of legacy bootflow or phandles of component binaries
+ in case of combined bootflow
+
+ The following properties are only for generating a combined bootflow binary:
+ - sysfw-inner-cert: boolean if binary contains sysfw inner certificate
+ - dm-data: boolean if binary contains dm-data binary
+ - content-sbl: phandle of SPL binary
+ - content-sysfw: phandle of sysfw binary
+ - content-sysfw-data: phandle of sysfw-data or tifs-data binary
+ - content-sysfw-inner-cert (optional): phandle of sysfw inner certificate binary
+ - content-dm-data (optional): phandle of dm-data binary
+ - load-sysfw: load address of sysfw binary
+ - load-sysfw-data: load address of sysfw-data or tifs-data binary
+ - load-sysfw-inner-cert (optional): load address of sysfw inner certificate binary
+ - load-dm-data (optional): load address of dm-data binary
+
+ Output files:
+ - input.<unique_name> - input file passed to openssl
+ - config.<unique_name> - input file generated for openssl (which is
+ used as the config file)
+ - cert.<unique_name> - output file generated by openssl (which is
+ used as the entry contents)
+
+ openssl signs the provided data, using the TI templated config file and
+ writes the signature in this entry. This allows verification that the
+ data is genuine.
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.openssl = None
+
+ def ReadNode(self):
+ super().ReadNode()
+ self.combined = fdt_util.GetBool(self._node, 'combined', False)
+ self.countersign = fdt_util.GetBool(self._node, 'countersign', False)
+ self.load_addr = fdt_util.GetInt(self._node, 'load', 0x00000000)
+ self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
+ self.sha = fdt_util.GetInt(self._node, 'sha', 512)
+ self.core = fdt_util.GetString(self._node, 'core', 'secure')
+ self.key_fname = self.GetEntryArgsOrProps([
+ EntryArg('keyfile', str)], required=True)[0]
+ if self.combined:
+ self.sysfw_inner_cert = fdt_util.GetBool(self._node, 'sysfw-inner-cert', False)
+ self.load_addr_sysfw = fdt_util.GetInt(self._node, 'load-sysfw', 0x00000000)
+ self.load_addr_sysfw_data = fdt_util.GetInt(self._node, 'load-sysfw-data', 0x00000000)
+ self.dm_data = fdt_util.GetBool(self._node, 'dm-data', False)
+ if self.dm_data:
+ self.load_addr_dm_data = fdt_util.GetInt(self._node, 'load-dm-data', 0x00000000)
+ self.req_dist_name = {'C': 'US',
+ 'ST': 'TX',
+ 'L': 'Dallas',
+ 'O': 'Texas Instruments Incorporated',
+ 'OU': 'Processors',
+ 'CN': 'TI Support',
+ 'emailAddress': 'support@ti.com'}
+
+ def NonCombinedGetCertificate(self, required):
+ """Generate certificate for legacy boot flow
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry, which is the certificate binary for the
+ provided data
+ """
+ if self.core == 'secure':
+ if self.countersign:
+ self.cert_type = 3
+ else:
+ self.cert_type = 2
+ self.bootcore = 0
+ self.bootcore_opts = 32
+ else:
+ self.cert_type = 1
+ self.bootcore = 16
+ self.bootcore_opts = 0
+ return super().GetCertificate(required=required, type='rom')
+
+ def CombinedGetCertificate(self, required):
+ """Generate certificate for combined boot flow
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry, which is the certificate binary for the
+ provided data
+ """
+ uniq = self.GetUniqueName()
+
+ self.num_comps = 3
+ self.sha_type = SHA_OIDS[self.sha]
+
+ # sbl
+ self.content = fdt_util.GetPhandleList(self._node, 'content-sbl')
+ input_data_sbl = self.GetContents(required)
+ if input_data_sbl is None:
+ return None
+
+ input_fname_sbl = tools.get_output_filename('input.%s' % uniq)
+ tools.write_file(input_fname_sbl, input_data_sbl)
+
+ indata_sbl = tools.read_file(input_fname_sbl)
+ self.hashval_sbl = hashlib.sha512(indata_sbl).hexdigest()
+ self.imagesize_sbl = len(indata_sbl)
+
+ # sysfw
+ self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw')
+ input_data_sysfw = self.GetContents(required)
+
+ input_fname_sysfw = tools.get_output_filename('input.%s' % uniq)
+ tools.write_file(input_fname_sysfw, input_data_sysfw)
+
+ indata_sysfw = tools.read_file(input_fname_sysfw)
+ self.hashval_sysfw = hashlib.sha512(indata_sysfw).hexdigest()
+ self.imagesize_sysfw = len(indata_sysfw)
+
+ # sysfw data
+ self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw-data')
+ input_data_sysfw_data = self.GetContents(required)
+
+ input_fname_sysfw_data = tools.get_output_filename('input.%s' % uniq)
+ tools.write_file(input_fname_sysfw_data, input_data_sysfw_data)
+
+ indata_sysfw_data = tools.read_file(input_fname_sysfw_data)
+ self.hashval_sysfw_data = hashlib.sha512(indata_sysfw_data).hexdigest()
+ self.imagesize_sysfw_data = len(indata_sysfw_data)
+
+ # sysfw inner cert
+ self.sysfw_inner_cert_ext_boot_block = ""
+ self.sysfw_inner_cert_ext_boot_sequence_string = ""
+ imagesize_sysfw_inner_cert = 0
+ if self.sysfw_inner_cert:
+ self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw-inner-cert')
+ input_data_sysfw_inner_cert = self.GetContents(required)
+
+ input_fname_sysfw_inner_cert = tools.get_output_filename('input.%s' % uniq)
+ tools.write_file(input_fname_sysfw_inner_cert, input_data_sysfw_inner_cert)
+
+ indata_sysfw_inner_cert = tools.read_file(input_fname_sysfw_inner_cert)
+ hashval_sysfw_inner_cert = hashlib.sha512(indata_sysfw_inner_cert).hexdigest()
+ imagesize_sysfw_inner_cert = len(indata_sysfw_inner_cert)
+ self.num_comps += 1
+ self.sysfw_inner_cert_ext_boot_sequence_string = "sysfw_inner_cert=SEQUENCE:sysfw_inner_cert"
+ self.sysfw_inner_cert_ext_boot_block = f"""[sysfw_inner_cert]
+compType = INTEGER:3
+bootCore = INTEGER:0
+compOpts = INTEGER:0
+destAddr = FORMAT:HEX,OCT:00000000
+compSize = INTEGER:{imagesize_sysfw_inner_cert}
+shaType = OID:{self.sha_type}
+shaValue = FORMAT:HEX,OCT:{hashval_sysfw_inner_cert}"""
+
+ # dm data
+ self.dm_data_ext_boot_sequence_string = ""
+ self.dm_data_ext_boot_block = ""
+ imagesize_dm_data = 0
+ if self.dm_data:
+ self.content = fdt_util.GetPhandleList(self._node, 'content-dm-data')
+ input_data_dm_data = self.GetContents(required)
+
+ input_fname_dm_data = tools.get_output_filename('input.%s' % uniq)
+ tools.write_file(input_fname_dm_data, input_data_dm_data)
+
+ indata_dm_data = tools.read_file(input_fname_dm_data)
+ hashval_dm_data = hashlib.sha512(indata_dm_data).hexdigest()
+ imagesize_dm_data = len(indata_dm_data)
+ self.num_comps += 1
+ self.dm_data_ext_boot_sequence_string = "dm_data=SEQUENCE:dm_data"
+ self.dm_data_ext_boot_block = f"""[dm_data]
+compType = INTEGER:17
+bootCore = INTEGER:16
+compOpts = INTEGER:0
+destAddr = FORMAT:HEX,OCT:{self.load_addr_dm_data:08x}
+compSize = INTEGER:{imagesize_dm_data}
+shaType = OID:{self.sha_type}
+shaValue = FORMAT:HEX,OCT:{hashval_dm_data}"""
+
+ self.total_size = self.imagesize_sbl + self.imagesize_sysfw + self.imagesize_sysfw_data + imagesize_sysfw_inner_cert + imagesize_dm_data
+ return super().GetCertificate(required=required, type='rom-combined')
+
+ def GetCertificate(self, required):
+ """Get the contents of this entry
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry, which is the certificate binary for the
+ provided data
+ """
+ if self.combined:
+ return self.CombinedGetCertificate(required)
+ else:
+ return self.NonCombinedGetCertificate(required)
+
+ def ObtainContents(self):
+ data = self.data
+ if data is None:
+ data = self.GetCertificate(False)
+ if data is None:
+ return False
+ self.SetContents(data)
+ return True
+
+ def ProcessContents(self):
+ # The blob may have changed due to WriteSymbols()
+ data = self.data
+ return self.ProcessContentsUpdate(data)
+
+ def AddBintools(self, btools):
+ super().AddBintools(btools)
+ self.openssl = self.AddBintool(btools, 'openssl')
diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py
index f80a6ec2d1..d028cfe38c 100644
--- a/tools/binman/etype/x509_cert.py
+++ b/tools/binman/etype/x509_cert.py
@@ -31,6 +31,26 @@ class Entry_x509_cert(Entry_collection):
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
self.openssl = None
+ self.req_dist_name = None
+ self.cert_type = None
+ self.bootcore = None
+ self.bootcore_opts = None
+ self.load_addr = None
+ self.sha = None
+ self.total_size = None
+ self.num_comps = None
+ self.sysfw_inner_cert_ext_boot_sequence_string = None
+ self.dm_data_ext_boot_sequence_string = None
+ self.imagesize_sbl = None
+ self.hashval_sbl = None
+ self.load_addr_sysfw = None
+ self.imagesize_sysfw = None
+ self.hashval_sysfw = None
+ self.load_addr_sysfw_data = None
+ self.imagesize_sysfw_data = None
+ self.hashval_sysfw_data = None
+ self.sysfw_inner_cert_ext_boot_block = None
+ self.dm_data_ext_boot_block = None
def ReadNode(self):
super().ReadNode()
@@ -38,13 +58,16 @@ class Entry_x509_cert(Entry_collection):
self._cert_rev = fdt_util.GetInt(self._node, 'cert-revision-int', 0)
self.key_fname = self.GetEntryArgsOrProps([
EntryArg('keyfile', str)], required=True)[0]
+ self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
- def GetCertificate(self, required):
+ def GetCertificate(self, required, type='generic'):
"""Get the contents of this entry
Args:
required: True if the data must be present, False if it is OK to
return None
+ type: Type of x509 certificate to generate, current supported ones are
+ 'generic', 'sysfw', 'rom'
Returns:
bytes content of the entry, which is the signed vblock for the
@@ -60,13 +83,61 @@ class Entry_x509_cert(Entry_collection):
input_fname = tools.get_output_filename('input.%s' % uniq)
config_fname = tools.get_output_filename('config.%s' % uniq)
tools.write_file(input_fname, input_data)
- stdout = self.openssl.x509_cert(
- cert_fname=output_fname,
- input_fname=input_fname,
- key_fname=self.key_fname,
- cn=self._cert_ca,
- revision=self._cert_rev,
- config_fname=config_fname)
+ if type == 'generic':
+ stdout = self.openssl.x509_cert(
+ cert_fname=output_fname,
+ input_fname=input_fname,
+ key_fname=self.key_fname,
+ cn=self._cert_ca,
+ revision=self._cert_rev,
+ config_fname=config_fname)
+ elif type == 'sysfw':
+ stdout = self.openssl.x509_cert_sysfw(
+ cert_fname=output_fname,
+ input_fname=input_fname,
+ key_fname=self.key_fname,
+ config_fname=config_fname,
+ sw_rev=self.sw_rev,
+ req_dist_name_dict=self.req_dist_name)
+ elif type == 'rom':
+ stdout = self.openssl.x509_cert_rom(
+ cert_fname=output_fname,
+ input_fname=input_fname,
+ key_fname=self.key_fname,
+ config_fname=config_fname,
+ sw_rev=self.sw_rev,
+ req_dist_name_dict=self.req_dist_name,
+ cert_type=self.cert_type,
+ bootcore=self.bootcore,
+ bootcore_opts=self.bootcore_opts,
+ load_addr=self.load_addr,
+ sha=self.sha
+ )
+ elif type == 'rom-combined':
+ stdout = self.openssl.x509_cert_rom_combined(
+ cert_fname=output_fname,
+ input_fname=input_fname,
+ key_fname=self.key_fname,
+ config_fname=config_fname,
+ sw_rev=self.sw_rev,
+ req_dist_name_dict=self.req_dist_name,
+ load_addr=self.load_addr,
+ sha=self.sha,
+ total_size=self.total_size,
+ num_comps=self.num_comps,
+ sysfw_inner_cert_ext_boot_sequence_string=self.sysfw_inner_cert_ext_boot_sequence_string,
+ dm_data_ext_boot_sequence_string=self.dm_data_ext_boot_sequence_string,
+ imagesize_sbl=self.imagesize_sbl,
+ hashval_sbl=self.hashval_sbl,
+ load_addr_sysfw=self.load_addr_sysfw,
+ imagesize_sysfw=self.imagesize_sysfw,
+ hashval_sysfw=self.hashval_sysfw,
+ load_addr_sysfw_data=self.load_addr_sysfw_data,
+ imagesize_sysfw_data=self.imagesize_sysfw_data,
+ hashval_sysfw_data=self.hashval_sysfw_data,
+ sysfw_inner_cert_ext_boot_block=self.sysfw_inner_cert_ext_boot_block,
+ dm_data_ext_boot_block=self.dm_data_ext_boot_block
+ )
if stdout is not None:
data = tools.read_file(output_fname)
else:
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index e53181afb7..3e8091e832 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -97,6 +97,8 @@ ENV_DATA = b'var1=1\nvar2="2"'
PRE_LOAD_MAGIC = b'UBSH'
PRE_LOAD_VERSION = 0x11223344.to_bytes(4, 'big')
PRE_LOAD_HDR_SIZE = 0x00001000.to_bytes(4, 'big')
+TI_BOARD_CONFIG_DATA = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+TI_UNSECURE_DATA = b'unsecuredata'
# Subdirectory of the input dir to use to put test FDTs
TEST_FDT_SUBDIR = 'fdts'
@@ -199,6 +201,9 @@ class TestFunctional(unittest.TestCase):
shutil.copytree(cls.TestFile('files'),
os.path.join(cls._indir, 'files'))
+ shutil.copytree(cls.TestFile('yaml'),
+ os.path.join(cls._indir, 'yaml'))
+
TestFunctional._MakeInputFile('compress', COMPRESS_DATA)
TestFunctional._MakeInputFile('compress_big', COMPRESS_DATA_BIG)
TestFunctional._MakeInputFile('bl31.bin', ATF_BL31_DATA)
@@ -207,6 +212,7 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('fw_dynamic.bin', OPENSBI_DATA)
TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
TestFunctional._MakeInputFile('rockchip-tpl.bin', ROCKCHIP_TPL_DATA)
+ TestFunctional._MakeInputFile('ti_unsecure.bin', TI_UNSECURE_DATA)
# Add a few .dtb files for testing
TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
@@ -347,7 +353,7 @@ class TestFunctional(unittest.TestCase):
use_expanded=False, verbosity=None, allow_missing=False,
allow_fake_blobs=False, extra_indirs=None, threads=None,
test_section_timeout=False, update_fdt_in_elf=None,
- force_missing_bintools='', ignore_missing=False):
+ force_missing_bintools='', ignore_missing=False, output_dir=None):
"""Run binman with a given test file
Args:
@@ -378,6 +384,7 @@ class TestFunctional(unittest.TestCase):
update_fdt_in_elf: Value to pass with --update-fdt-in-elf=xxx
force_missing_tools (str): comma-separated list of bintools to
regard as missing
+ output_dir: Specific output directory to use for image using -O
Returns:
int return code, 0 on success
@@ -424,6 +431,8 @@ class TestFunctional(unittest.TestCase):
if extra_indirs:
for indir in extra_indirs:
args += ['-I', indir]
+ if output_dir:
+ args += ['-O', output_dir]
return self._DoBinman(*args)
def _SetupDtb(self, fname, outfile='u-boot.dtb'):
@@ -6168,7 +6177,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
str(e.exception))
def testSymlink(self):
- """Test that image files can be named"""
+ """Test that image files can be symlinked"""
retcode = self._DoTestFile('259_symlink.dts', debug=True, map=True)
self.assertEqual(0, retcode)
image = control.images['test_image']
@@ -6177,6 +6186,17 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertTrue(os.path.islink(sname))
self.assertEqual(os.readlink(sname), fname)
+ def testSymlinkOverwrite(self):
+ """Test that symlinked images can be overwritten"""
+ testdir = TestFunctional._MakeInputDir('symlinktest')
+ self._DoTestFile('259_symlink.dts', debug=True, map=True, output_dir=testdir)
+ # build the same image again in the same directory so that existing symlink is present
+ self._DoTestFile('259_symlink.dts', debug=True, map=True, output_dir=testdir)
+ fname = tools.get_output_filename('test_image.bin')
+ sname = tools.get_output_filename('symlink_to_test.bin')
+ self.assertTrue(os.path.islink(sname))
+ self.assertEqual(os.readlink(sname), fname)
+
def testSymbolsElf(self):
"""Test binman can assign symbols embedded in an ELF file"""
if not elf.ELF_TOOLS:
@@ -6884,6 +6904,72 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
# Move to next
spl_data = content[:0x18]
+ def testTIBoardConfig(self):
+ """Test that a schema validated board config file can be generated"""
+ data = self._DoReadFile('277_ti_board_cfg.dts')
+ self.assertEqual(TI_BOARD_CONFIG_DATA, data)
+
+ def testTIBoardConfigCombined(self):
+ """Test that a schema validated combined board config file can be generated"""
+ data = self._DoReadFile('278_ti_board_cfg_combined.dts')
+ configlen_noheader = TI_BOARD_CONFIG_DATA * 4
+ self.assertGreater(data, configlen_noheader)
+
+ def testTIBoardConfigNoDataType(self):
+ """Test that error is thrown when data type is not supported"""
+ with self.assertRaises(ValueError) as e:
+ data = self._DoReadFile('279_ti_board_cfg_no_type.dts')
+ self.assertIn("Schema validation error", str(e.exception))
+
+ def testPackTiSecure(self):
+ """Test that an image with a TI secured binary can be created"""
+ keyfile = self.TestFile('key.key')
+ entry_args = {
+ 'keyfile': keyfile,
+ }
+ data = self._DoReadFileDtb('279_ti_secure.dts',
+ entry_args=entry_args)[0]
+ self.assertGreater(len(data), len(TI_UNSECURE_DATA))
+
+ def testPackTiSecureMissingTool(self):
+ """Test that an image with a TI secured binary (non-functional) can be created
+ when openssl is missing"""
+ keyfile = self.TestFile('key.key')
+ entry_args = {
+ 'keyfile': keyfile,
+ }
+ with test_util.capture_sys_output() as (_, stderr):
+ self._DoTestFile('279_ti_secure.dts',
+ force_missing_bintools='openssl',
+ entry_args=entry_args)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: openssl")
+
+ def testPackTiSecureROM(self):
+ """Test that a ROM image with a TI secured binary can be created"""
+ keyfile = self.TestFile('key.key')
+ entry_args = {
+ 'keyfile': keyfile,
+ }
+ data = self._DoReadFileDtb('280_ti_secure_rom.dts',
+ entry_args=entry_args)[0]
+ data_a = self._DoReadFileDtb('288_ti_secure_rom_a.dts',
+ entry_args=entry_args)[0]
+ data_b = self._DoReadFileDtb('289_ti_secure_rom_b.dts',
+ entry_args=entry_args)[0]
+ self.assertGreater(len(data), len(TI_UNSECURE_DATA))
+ self.assertGreater(len(data_a), len(TI_UNSECURE_DATA))
+ self.assertGreater(len(data_b), len(TI_UNSECURE_DATA))
+
+ def testPackTiSecureROMCombined(self):
+ """Test that a ROM image with a TI secured binary can be created"""
+ keyfile = self.TestFile('key.key')
+ entry_args = {
+ 'keyfile': keyfile,
+ }
+ data = self._DoReadFileDtb('281_ti_secure_rom_combined.dts',
+ entry_args=entry_args)[0]
+ self.assertGreater(len(data), len(TI_UNSECURE_DATA))
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 8ebf71d61a..e77b5d0d97 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -182,6 +182,8 @@ class Image(section.Entry_section):
# Create symlink to file if symlink given
if self._symlink is not None:
sname = tools.get_output_filename(self._symlink)
+ if os.path.islink(sname):
+ os.remove(sname)
os.symlink(fname, sname)
def WriteMap(self):
diff --git a/tools/binman/test/277_ti_board_cfg.dts b/tools/binman/test/277_ti_board_cfg.dts
new file mode 100644
index 0000000000..cda024c1b8
--- /dev/null
+++ b/tools/binman/test/277_ti_board_cfg.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-board-config {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema.yaml";
+ };
+ };
+};
diff --git a/tools/binman/test/278_ti_board_cfg_combined.dts b/tools/binman/test/278_ti_board_cfg_combined.dts
new file mode 100644
index 0000000000..95ef449cbf
--- /dev/null
+++ b/tools/binman/test/278_ti_board_cfg_combined.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ ti-board-config {
+ board-cfg {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema.yaml";
+ };
+ sec-cfg {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema.yaml";
+ };
+ rm-cfg {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema.yaml";
+ };
+ pm-cfg {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema.yaml";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/279_ti_board_cfg_no_type.dts b/tools/binman/test/279_ti_board_cfg_no_type.dts
new file mode 100644
index 0000000000..584b7acc5a
--- /dev/null
+++ b/tools/binman/test/279_ti_board_cfg_no_type.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ ti-board-config {
+ config = "yaml/config.yaml";
+ schema = "yaml/schema_notype.yaml";
+ };
+ };
+};
diff --git a/tools/binman/test/279_ti_secure.dts b/tools/binman/test/279_ti_secure.dts
new file mode 100644
index 0000000000..941d0ab4ca
--- /dev/null
+++ b/tools/binman/test/279_ti_secure.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-secure {
+ content = <&unsecure_binary>;
+ };
+ unsecure_binary: blob-ext {
+ filename = "ti_unsecure.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/280_ti_secure_rom.dts b/tools/binman/test/280_ti_secure_rom.dts
new file mode 100644
index 0000000000..d1313769f4
--- /dev/null
+++ b/tools/binman/test/280_ti_secure_rom.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-secure-rom {
+ content = <&unsecure_binary>;
+ };
+ unsecure_binary: blob-ext {
+ filename = "ti_unsecure.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/281_ti_secure_rom_combined.dts b/tools/binman/test/281_ti_secure_rom_combined.dts
new file mode 100644
index 0000000000..bf872739bc
--- /dev/null
+++ b/tools/binman/test/281_ti_secure_rom_combined.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-secure-rom {
+ content = <&unsecure_binary>;
+ content-sbl = <&unsecure_binary>;
+ content-sysfw = <&unsecure_binary>;
+ content-sysfw-data = <&unsecure_binary>;
+ content-sysfw-inner-cert = <&unsecure_binary>;
+ content-dm-data = <&unsecure_binary>;
+ combined;
+ sysfw-inner-cert;
+ dm-data;
+ };
+ unsecure_binary: blob-ext {
+ filename = "ti_unsecure.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/288_ti_secure_rom_a.dts b/tools/binman/test/288_ti_secure_rom_a.dts
new file mode 100644
index 0000000000..887138f0e4
--- /dev/null
+++ b/tools/binman/test/288_ti_secure_rom_a.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-secure-rom {
+ content = <&unsecure_binary>;
+ core = "secure";
+ countersign;
+ };
+ unsecure_binary: blob-ext {
+ filename = "ti_unsecure.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/289_ti_secure_rom_b.dts b/tools/binman/test/289_ti_secure_rom_b.dts
new file mode 100644
index 0000000000..c6d6182158
--- /dev/null
+++ b/tools/binman/test/289_ti_secure_rom_b.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ ti-secure-rom {
+ content = <&unsecure_binary>;
+ core = "public";
+ };
+ unsecure_binary: blob-ext {
+ filename = "ti_unsecure.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/yaml/config.yaml b/tools/binman/test/yaml/config.yaml
new file mode 100644
index 0000000000..5f799a6e3a
--- /dev/null
+++ b/tools/binman/test/yaml/config.yaml
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Test config
+#
+---
+
+main-branch:
+ obj:
+ a: 0x0
+ b: 0
+ arr: [0, 0, 0, 0]
+ another-arr:
+ - #1
+ c: 0
+ d: 0
+ - #2
+ c: 0
+ d: 0
diff --git a/tools/binman/test/yaml/schema.yaml b/tools/binman/test/yaml/schema.yaml
new file mode 100644
index 0000000000..8aa03f3c8e
--- /dev/null
+++ b/tools/binman/test/yaml/schema.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Test schema
+#
+---
+
+definitions:
+ u8:
+ type: integer
+ minimum: 0
+ maximum: 0xff
+ u16:
+ type: integer
+ minimum: 0
+ maximum: 0xffff
+ u32:
+ type: integer
+ minimum: 0
+ maximum: 0xffffffff
+
+type: object
+properties:
+ main-branch:
+ type: object
+ properties:
+ obj:
+ type: object
+ properties:
+ a:
+ $ref: "#/definitions/u32"
+ b:
+ $ref: "#/definitions/u16"
+ arr:
+ type: array
+ minItems: 4
+ maxItems: 4
+ items:
+ $ref: "#/definitions/u8"
+ another-arr:
+ type: array
+ minItems: 2
+ maxItems: 2
+ items:
+ type: object
+ properties:
+ c:
+ $ref: "#/definitions/u8"
+ d:
+ $ref: "#/definitions/u8"
diff --git a/tools/binman/test/yaml/schema_notype.yaml b/tools/binman/test/yaml/schema_notype.yaml
new file mode 100644
index 0000000000..6b4d98ffa1
--- /dev/null
+++ b/tools/binman/test/yaml/schema_notype.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Test schema
+#
+---
+
+definitions:
+ u8:
+ type: integer
+ minimum: 0
+ maximum: 0xff
+ u16:
+ type: integer
+ minimum: 0
+ maximum: 0xffff
+ u32:
+ type: integer
+ minimum: 0
+ maximum: 0xffffffff
+
+type: object
+properties:
+ main-branch:
+ type: object
+ properties:
+ obj:
+ type: object
+ properties:
+ a:
+ $ref: "#/definitions/u4"
+ b:
+ $ref: "#/definitions/u16"
+ arr:
+ type: array
+ minItems: 4
+ maxItems: 4
+ items:
+ $ref: "#/definitions/u8"
diff --git a/tools/buildman/requirements.txt b/tools/buildman/requirements.txt
new file mode 100644
index 0000000000..a1efcb9d4b
--- /dev/null
+++ b/tools/buildman/requirements.txt
@@ -0,0 +1,2 @@
+jsonschema==4.17.3
+pyyaml==6.0
diff --git a/tools/k3_fit_atf.sh b/tools/k3_fit_atf.sh
deleted file mode 100755
index 7bc07ad074..0000000000
--- a/tools/k3_fit_atf.sh
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0+
-#
-# script to generate FIT image source for K3 Family boards with
-# ATF, OPTEE, SPL and multiple device trees (given on the command line).
-# Inspired from board/sunxi/mksunxi_fit_atf.sh
-#
-# usage: $0 <atf_load_addr> <dt_name> [<dt_name> [<dt_name] ...]
-
-[ -z "$ATF" ] && ATF="bl31.bin"
-
-if [ ! -f $ATF ]; then
- echo "WARNING ATF file $ATF NOT found, resulting binary is non-functional" >&2
- ATF=/dev/null
-fi
-
-[ -z "$TEE" ] && TEE="bl32.bin"
-
-if [ ! -f $TEE ]; then
- echo "WARNING OPTEE file $TEE NOT found, resulting might be non-functional" >&2
- TEE=/dev/null
-fi
-
-[ -z "$DM" ] && DM="dm.bin"
-
-if [ ! -e $DM ]; then
- echo "WARNING DM file $DM NOT found, resulting might be non-functional" >&2
- DM=/dev/null
-fi
-
-if [ ! -z "$IS_HS" ]; then
- HS_APPEND=_HS
-fi
-
-cat << __HEADER_EOF
-/dts-v1/;
-
-/ {
- description = "Configuration to load ATF and SPL";
- #address-cells = <1>;
-
- images {
- atf {
- description = "ARM Trusted Firmware";
- data = /incbin/("$ATF");
- type = "firmware";
- arch = "arm64";
- compression = "none";
- os = "arm-trusted-firmware";
- load = <$1>;
- entry = <$1>;
- };
- tee {
- description = "OPTEE";
- data = /incbin/("$TEE");
- type = "tee";
- arch = "arm64";
- compression = "none";
- os = "tee";
- load = <0x9e800000>;
- entry = <0x9e800000>;
- };
- dm {
- description = "DM binary";
- data = /incbin/("$DM");
- type = "firmware";
- arch = "arm32";
- compression = "none";
- os = "DM";
- load = <0x89000000>;
- entry = <0x89000000>;
- };
- spl {
- description = "SPL (64-bit)";
- data = /incbin/("spl/u-boot-spl-nodtb.bin$HS_APPEND");
- type = "standalone";
- os = "U-Boot";
- arch = "arm64";
- compression = "none";
- load = <0x80080000>;
- entry = <0x80080000>;
- };
-__HEADER_EOF
-
-# shift through ATF load address in the command line arguments
-shift
-
-for dtname in $*
-do
- cat << __FDT_IMAGE_EOF
- $(basename $dtname) {
- description = "$(basename $dtname .dtb)";
- data = /incbin/("$dtname$HS_APPEND");
- type = "flat_dt";
- arch = "arm";
- compression = "none";
- };
-__FDT_IMAGE_EOF
-done
-
-cat << __CONF_HEADER_EOF
- };
- configurations {
- default = "$(basename $1)";
-
-__CONF_HEADER_EOF
-
-for dtname in $*
-do
- cat << __CONF_SECTION_EOF
- $(basename $dtname) {
- description = "$(basename $dtname .dtb)";
- firmware = "atf";
- loadables = "tee", "dm", "spl";
- fdt = "$(basename $dtname)";
- };
-__CONF_SECTION_EOF
-done
-
-cat << __ITS_EOF
- };
-};
-__ITS_EOF
diff --git a/tools/k3_gen_x509_cert.sh b/tools/k3_gen_x509_cert.sh
deleted file mode 100755
index d9cde07417..0000000000
--- a/tools/k3_gen_x509_cert.sh
+++ /dev/null
@@ -1,262 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
-#
-# Script to add K3 specific x509 cetificate to a binary.
-#
-
-# Variables
-OUTPUT=tiboot3.bin
-TEMP_X509=x509-temp.cert
-CERT=certificate.bin
-RAND_KEY=eckey.pem
-LOADADDR=0x41c00000
-BOOTCORE_OPTS=0
-BOOTCORE=16
-DEBUG_TYPE=0
-SWRV=1
-
-gen_degen_template() {
-cat << 'EOF' > degen-template.txt
-
-asn1=SEQUENCE:rsa_key
-
-[rsa_key]
-version=INTEGER:0
-modulus=INTEGER:0xDEGEN_MODULUS
-pubExp=INTEGER:1
-privExp=INTEGER:1
-p=INTEGER:0xDEGEN_P
-q=INTEGER:0xDEGEN_Q
-e1=INTEGER:1
-e2=INTEGER:1
-coeff=INTEGER:0xDEGEN_COEFF
-EOF
-}
-
-# Generate x509 Template
-gen_template() {
-cat << 'EOF' > x509-template.txt
- [ req ]
- distinguished_name = req_distinguished_name
- x509_extensions = v3_ca
- prompt = no
- dirstring_type = nobmp
-
- [ req_distinguished_name ]
- C = US
- ST = TX
- L = Dallas
- O = Texas Instruments Incorporated
- OU = Processors
- CN = TI support
- emailAddress = support@ti.com
-
- [ v3_ca ]
- basicConstraints = CA:true
- 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
- 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
- 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
-# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
- 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug
-
- [ boot_seq ]
- certType = INTEGER:TEST_CERT_TYPE
- bootCore = INTEGER:TEST_BOOT_CORE
- bootCoreOpts = INTEGER:TEST_BOOT_CORE_OPTS
- destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR
- imageSize = INTEGER:TEST_IMAGE_LENGTH
-
- [ image_integrity ]
- shaType = OID:2.16.840.1.101.3.4.2.3
- shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL
-
- [ swrv ]
- swrv = INTEGER:TEST_SWRV
-
-# [ encryption ]
-# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
-# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
-# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
-# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
-
- [ debug ]
- debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
- debugType = INTEGER:TEST_DEBUG_TYPE
- coreDbgEn = INTEGER:0
- coreDbgSecEn = INTEGER:0
-EOF
-}
-
-parse_key() {
- sed '/ /s/://g' key.txt | \
- awk '!/ / {printf("\n%s\n", $0)}; / / {printf("%s", $0)}' | \
- sed 's/ //g' | \
- awk "/$1:/{getline; print}"
-}
-
-gen_degen_key() {
-# Generate a 4096 bit RSA Key
- openssl genrsa -out key.pem 1024 >>/dev/null 2>&1
- openssl rsa -in key.pem -text -out key.txt >>/dev/null 2>&1
- DEGEN_MODULUS=$( parse_key 'modulus' )
- DEGEN_P=$( parse_key 'prime1' )
- DEGEN_Q=$( parse_key 'prime2' )
- DEGEN_COEFF=$( parse_key 'coefficient' )
- gen_degen_template
-
- sed -e "s/DEGEN_MODULUS/$DEGEN_MODULUS/"\
- -e "s/DEGEN_P/$DEGEN_P/" \
- -e "s/DEGEN_Q/$DEGEN_Q/" \
- -e "s/DEGEN_COEFF/$DEGEN_COEFF/" \
- degen-template.txt > degenerateKey.txt
-
- openssl asn1parse -genconf degenerateKey.txt -out degenerateKey.der >>/dev/null 2>&1
- openssl rsa -in degenerateKey.der -inform DER -outform PEM -out $RAND_KEY >>/dev/null 2>&1
- KEY=$RAND_KEY
- rm key.pem key.txt degen-template.txt degenerateKey.txt degenerateKey.der
-}
-
-declare -A options_help
-usage() {
- if [ -n "$*" ]; then
- echo "ERROR: $*"
- fi
- echo -n "Usage: $0 "
- for option in "${!options_help[@]}"
- do
- arg=`echo ${options_help[$option]}|cut -d ':' -f1`
- if [ -n "$arg" ]; then
- arg=" $arg"
- fi
- echo -n "[-$option$arg] "
- done
- echo
- echo -e "\nWhere:"
- for option in "${!options_help[@]}"
- do
- arg=`echo ${options_help[$option]}|cut -d ':' -f1`
- txt=`echo ${options_help[$option]}|cut -d ':' -f2`
- tb="\t\t\t"
- if [ -n "$arg" ]; then
- arg=" $arg"
- tb="\t"
- fi
- echo -e " -$option$arg:$tb$txt"
- done
- echo
- echo "Examples of usage:-"
- echo "# Example of signing the SYSFW binary with rsa degenerate key"
- echo " $0 -c 0 -b ti-sci-firmware-am6x.bin -o sysfw.bin -l 0x40000"
- echo "# Example of signing the SPL binary with rsa degenerate key"
- echo " $0 -c 16 -b spl/u-boot-spl.bin -o tiboot3.bin -l 0x41c00000"
-}
-
-options_help[b]="bin_file:Bin file that needs to be signed"
-options_help[k]="key_file:file with key inside it. If not provided script generates a rsa degenerate key."
-options_help[o]="output_file:Name of the final output file. default to $OUTPUT"
-options_help[c]="core_id:target core id on which the image would be running. Default to $BOOTCORE"
-options_help[l]="loadaddr: Target load address of the binary in hex. Default to $LOADADDR"
-options_help[d]="debug_type: Debug type, set to 4 to enable early JTAG. Default to $DEBUG_TYPE"
-options_help[r]="SWRV: Software Rev for X509 certificate"
-
-while getopts "b:k:o:c:l:d:h:r:" opt
-do
- case $opt in
- b)
- BIN=$OPTARG
- ;;
- k)
- KEY=$OPTARG
- ;;
- o)
- OUTPUT=$OPTARG
- ;;
- l)
- LOADADDR=$OPTARG
- ;;
- c)
- BOOTCORE=$OPTARG
- ;;
- d)
- DEBUG_TYPE=$OPTARG
- ;;
- r)
- SWRV=$OPTARG
- ;;
- h)
- usage
- exit 0
- ;;
- \?)
- usage "Invalid Option '-$OPTARG'"
- exit 1
- ;;
- :)
- usage "Option '-$OPTARG' Needs an argument."
- exit 1
- ;;
- esac
-done
-
-if [ "$#" -eq 0 ]; then
- usage "Arguments missing"
- exit 1
-fi
-
-if [ -z "$BIN" ]; then
- usage "Bin file missing in arguments"
- exit 1
-fi
-
-# Generate rsa degenerate key if user doesn't provide a key
-if [ -z "$KEY" ]; then
- gen_degen_key
-fi
-
-if [ $BOOTCORE == 0 ]; then # BOOTCORE M3, loaded by ROM
- CERTTYPE=2
-elif [ $BOOTCORE == 16 ]; then # BOOTCORE R5, loaded by ROM
- CERTTYPE=1
-else # Non BOOTCORE, loaded by SYSFW
- BOOTCORE_OPTS_VER=$(printf "%01x" 1)
- # Add input args option for SET and CLR flags.
- BOOTCORE_OPTS_SETFLAG=$(printf "%08x" 0)
- BOOTCORE_OPTS_CLRFLAG=$(printf "%08x" 0x100) # Clear FLAG_ARMV8_AARCH32
- BOOTCORE_OPTS="0x$BOOTCORE_OPTS_VER$BOOTCORE_OPTS_SETFLAG$BOOTCORE_OPTS_CLRFLAG"
- # Set the cert type to zero.
- # We are not using public/private key store now
- CERTTYPE=$(printf "0x%08x" 0)
-fi
-
-SHA_VAL=`openssl dgst -sha512 -hex $BIN | sed -e "s/^.*= //g"`
-BIN_SIZE=`cat $BIN | wc -c`
-ADDR=`printf "%08x" $LOADADDR`
-
-gen_cert() {
- #echo "Certificate being generated :"
- #echo " LOADADDR = 0x$ADDR"
- #echo " IMAGE_SIZE = $BIN_SIZE"
- #echo " CERT_TYPE = $CERTTYPE"
- #echo " DEBUG_TYPE = $DEBUG_TYPE"
- #echo " SWRV = $SWRV"
- sed -e "s/TEST_IMAGE_LENGTH/$BIN_SIZE/" \
- -e "s/TEST_IMAGE_SHA_VAL/$SHA_VAL/" \
- -e "s/TEST_CERT_TYPE/$CERTTYPE/" \
- -e "s/TEST_BOOT_CORE_OPTS/$BOOTCORE_OPTS/" \
- -e "s/TEST_BOOT_CORE/$BOOTCORE/" \
- -e "s/TEST_BOOT_ADDR/$ADDR/" \
- -e "s/TEST_DEBUG_TYPE/$DEBUG_TYPE/" \
- -e "s/TEST_SWRV/$SWRV/" \
- x509-template.txt > $TEMP_X509
- openssl req -new -x509 -key $KEY -nodes -outform DER -out $CERT -config $TEMP_X509 -sha512
-}
-
-gen_template
-gen_cert
-cat $CERT $BIN > $OUTPUT
-
-# Remove all intermediate files
-rm $TEMP_X509 $CERT x509-template.txt
-if [ "$KEY" == "$RAND_KEY" ]; then
- rm $RAND_KEY
-fi