[PATCH v3 07/11] binman: openssl: Add boot and load extensions to x509 cert

Beleswar Prasad Padhi b-padhi at ti.com
Tue Jan 6 11:52:24 CET 2026


Hi Simon,

On 06/01/26 05:00, Simon Glass wrote:
> 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.


Thanks for pointing out. I will add a test for the same in v4.

Thanks,
Beleswar

>
>>      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