[PATCH v3 07/11] binman: openssl: Add boot and load extensions to x509 cert
Simon Glass
sjg at chromium.org
Tue Jan 6 00:30:24 CET 2026
Hi Beleswar,
On Wed, 31 Dec 2025 at 10:37, Beleswar Padhi <b-padhi at ti.com> wrote:
>
> The boot and load extensions in the x509 certificate are required for
> requesting the secure entity (TIFS) to boot a core. These fields are
> defined in the binman node for each core that must be booted by TIFS
> and must be included when generating the signed certificate.
>
> Add support to parse the boot and load extension properties from the
> binman node and populate them into the certificate. If any of the
> mandatory properties for an extension are missing, that respective
> extension section is NOT added to the certificate.
>
> Signed-off-by: Beleswar Padhi <b-padhi at ti.com>
> ---
> v3: Changelog:
> 1. New patch. Add support to sign HSM firmware here in U-Boot.
>
> tools/binman/btool/openssl.py | 49 ++++++++++++++++++++++++++++++---
> tools/binman/etype/ti_secure.py | 18 ++++++++++++
> tools/binman/etype/x509_cert.py | 4 ++-
> 3 files changed, 66 insertions(+), 5 deletions(-)
>
> diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
> index b26f087c447..35898aa488b 100644
> --- a/tools/binman/btool/openssl.py
> +++ b/tools/binman/btool/openssl.py
> @@ -82,7 +82,8 @@ imageSize = INTEGER:{len(indata)}
> return self.run_cmd(*args)
>
> def x509_cert_sysfw(self, cert_fname, input_fname, key_fname, sw_rev,
> - config_fname, req_dist_name_dict, firewall_cert_data):
> + config_fname, req_dist_name_dict, firewall_cert_data,
> + boot_ext_data, load_ext_data):
> """Create a certificate to be booted by system firmware
>
> Args:
> @@ -101,12 +102,52 @@ imageSize = INTEGER:{len(indata)}
> extended certificate
> - certificate (str): Extended firewall certificate with
> the information for the firewall configurations.
> + boot_ext_data (dict):
> + - proc_id (int): The processor ID of core being booted
> + - flags_set (int): The config flags to set for core being booted
> + - flags_clr (int): The config flags to clear for core being booted
> + - reset_vector (int): The location of reset vector for core being
> + booted
> + load_ext_data (dict):
> + - dest_addr (int): The address to which image has to be copied
> + - auth_type (int): Contains the host ID for core being booted and
> + how the image is to be copied
>
> Returns:
> str: Tool output
> """
> indata = tools.read_file(input_fname)
> hashval = hashlib.sha512(indata).hexdigest()
> +
> + if boot_ext_data is not None:
> + boot_ext = f'''
> +[ sysfw_boot_seq ]
> +bootCore = INTEGER:{boot_ext_data['proc_id']}
> +bootCoreOpts_set = INTEGER:{boot_ext_data['flags_set']}
> +bootCoreOpts_clr = INTEGER:{boot_ext_data['flags_clr']}
> +resetVec = FORMAT:HEX,OCT:{boot_ext_data['reset_vector']:08x}
> +# Reserved for future use
> +flagsValid = FORMAT:HEX,OCT:00000000
> +rsvd1 = INTEGER:0x00
> +rsdv2 = INTEGER:0x00
> +rsdv3 = INTEGER:0x00
> +'''
> + else:
> + boot_ext = ""
> +
> + if load_ext_data is not None:
> + load_ext = f'''
> +[ sysfw_image_load ]
> +destAddr = FORMAT:HEX,OCT:{load_ext_data['dest_addr']:08x}
> +authInPlace = INTEGER:{load_ext_data['auth_type']}
> +'''
> + else:
> + load_ext = f'''
> +[ sysfw_image_load ]
> +destAddr = FORMAT:HEX,OCT:00000000
> +authInPlace = INTEGER:{hex(firewall_cert_data['auth_in_place'])}
> +'''
> +
> with open(config_fname, 'w', encoding='utf-8') as outf:
> print(f'''[ req ]
> distinguished_name = req_distinguished_name
> @@ -138,9 +179,9 @@ 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:{hex(firewall_cert_data['auth_in_place'])}
> +{boot_ext}
> +
> +{load_ext}
>
> [ firewall ]
> numFirewallRegions = INTEGER:{firewall_cert_data['num_firewalls']}
> diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
> index f6caa0286d9..bc44b684892 100644
> --- a/tools/binman/etype/ti_secure.py
> +++ b/tools/binman/etype/ti_secure.py
> @@ -116,6 +116,7 @@ class Entry_ti_secure(Entry_x509_cert):
> if auth_in_place:
> self.firewall_cert_data['auth_in_place'] = auth_in_place
> self.ReadFirewallNode()
> + self.ReadLoadableCoreNode()
> self.sha = fdt_util.GetInt(self._node, 'sha', 512)
> self.req_dist_name = {'C': 'US',
> 'ST': 'TX',
> @@ -126,6 +127,23 @@ class Entry_ti_secure(Entry_x509_cert):
> 'emailAddress': 'support at ti.com'}
> self.debug = fdt_util.GetBool(self._node, 'debug', False)
>
> + def ReadLoadableCoreNode(self):
> + boot_ext_props = ['proc_id', 'flags_set', 'flags_clr', 'reset_vector']
> + load_ext_props = ['dest_addr', 'auth_type']
> +
> + self.boot_ext = self.ReadDictFromList(boot_ext_props)
> + self.load_ext = self.ReadDictFromList(load_ext_props)
> +
> + def ReadDictFromList(self, props):
> + props_dict = dict.fromkeys(props)
> + for prop in props:
> + val = fdt_util.GetInt(self._node, prop)
> + if val is None:
> + return None
> + else:
> + props_dict[prop] = val
> + return props_dict
> +
It looks like you are adding new code but without a test. Please can
you run 'binman test -T' and ensure you cover all lines.
> def ReadFirewallNode(self):
> self.firewall_cert_data['certificate'] = ""
> self.firewall_cert_data['num_firewalls'] = 0
> diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py
> index b6e8b0b4fb0..b6028f6be84 100644
> --- a/tools/binman/etype/x509_cert.py
> +++ b/tools/binman/etype/x509_cert.py
> @@ -102,7 +102,9 @@ class Entry_x509_cert(Entry_collection):
> config_fname=config_fname,
> sw_rev=self.sw_rev,
> req_dist_name_dict=self.req_dist_name,
> - firewall_cert_data=self.firewall_cert_data)
> + firewall_cert_data=self.firewall_cert_data,
> + boot_ext_data=self.boot_ext,
> + load_ext_data=self.load_ext)
> elif type == 'rom':
> stdout = self.openssl.x509_cert_rom(
> cert_fname=output_fname,
> --
> 2.34.1
>
Regards,
Simon
More information about the U-Boot
mailing list