[PATCH v3 1/6] binman: ti-secure: Add support for firewalling entities
Simon Glass
sjg at chromium.org
Sun Oct 8 01:10:06 CEST 2023
Hi Manorit,
On Wed, 4 Oct 2023 at 06:32, Manorit Chawdhry <m-chawdhry at ti.com> wrote:
>
> We can now firewall entities while loading them through our secure
> entity TIFS, the required information should be present in the
> certificate that is being parsed by TIFS.
>
> The following commit adds the support to enable the certificates to be
> generated if the firewall configurations are present in the binman dtsi
> nodes.
>
> Signed-off-by: Manorit Chawdhry <m-chawdhry at ti.com>
> ---
> tools/binman/btool/openssl.py | 16 +++++++-
> tools/binman/etype/ti_secure.py | 85 +++++++++++++++++++++++++++++++++++++++++
> tools/binman/etype/x509_cert.py | 3 +-
> 3 files changed, 101 insertions(+), 3 deletions(-)
>
> diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
> index aad3b61ae27c..dff439df211f 100644
> --- a/tools/binman/btool/openssl.py
> +++ b/tools/binman/btool/openssl.py
> @@ -82,7 +82,7 @@ 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):
> + config_fname, req_dist_name_dict, firewall_cert_data):
> """Create a certificate to be booted by system firmware
>
> Args:
> @@ -94,6 +94,13 @@ imageSize = INTEGER:{len(indata)}
> 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
> + firewall_cert_data (dict):
> + - auth_in_place (int): The Priv ID for copying as the
> + specific host in firewall protected region
> + - num_firewalls (int): The number of firewalls in the
> + extended certificate
> + - certificate (str): Extended firewall certificate with
> + the information for the firewall configurations.
>
> Returns:
> str: Tool output
> @@ -121,6 +128,7 @@ 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
> +1.3.6.1.4.1.294.1.37 = ASN1:SEQUENCE:firewall
>
> [ swrv ]
> swrv = INTEGER:{sw_rev}
> @@ -132,7 +140,11 @@ imageSize = INTEGER:{len(indata)}
>
> [ sysfw_image_load ]
> destAddr = FORMAT:HEX,OCT:00000000
> -authInPlace = INTEGER:2
> +authInPlace = INTEGER:{hex(firewall_cert_data['auth_in_place'])}
> +
> +[ firewall ]
> +numFirewallRegions = INTEGER:{firewall_cert_data['num_firewalls']}
> +{firewall_cert_data['certificate']}
Do we want the text above if there is no firewall info?
> ''', file=outf)
> args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
> '-outform', 'DER', '-out', cert_fname, '-config', config_fname,
> diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
> index d939dce57139..a7409023fa55 100644
> --- a/tools/binman/etype/ti_secure.py
> +++ b/tools/binman/etype/ti_secure.py
> @@ -7,9 +7,35 @@
>
> from binman.entry import EntryArg
> from binman.etype.x509_cert import Entry_x509_cert
> +from dataclasses import dataclass
>
> from dtoc import fdt_util
>
> + at dataclass
> +class Firewall():
> + id: int
> + region: int
> + control : int
> + permissions: list[hex]
> + start_address: str
> + end_address: str
> +
> + def get_certificate(self) -> str:
> + unique_identifier = f"{self.id}{self.region}"
> + cert = f"""
> +firewallID{unique_identifier} = INTEGER:{self.id}
> +region{unique_identifier} = INTEGER:{self.region}
> +control{unique_identifier} = INTEGER:{hex(self.control)}
> +nPermissionRegs{unique_identifier} = INTEGER:{len(self.permissions)}
> +"""
> + for index, permission in enumerate(self.permissions):
> + cert += f"""permissions{unique_identifier}{index} = INTEGER:{hex(permission)}
> +"""
> + cert += f"""startAddress{unique_identifier} = FORMAT:HEX,OCT:{self.start_address:02x}
> +endAddress{unique_identifier} = FORMAT:HEX,OCT:{self.end_address:02x}
> +"""
> + return cert
> +
> class Entry_ti_secure(Entry_x509_cert):
> """Entry containing a TI x509 certificate binary
>
> @@ -17,6 +43,11 @@ class Entry_ti_secure(Entry_x509_cert):
> - 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
> + - auth_in_place: This is an integer field that contains two pieces
> + of information
> + Lower Byte - Remains 0x02 as per our use case
> + ( 0x02: Move the authenticated binary back to the header )
> + Upper Byte - The Host ID of the core owning the firewall
>
> Output files:
> - input.<unique_name> - input file passed to openssl
> @@ -25,6 +56,35 @@ class Entry_ti_secure(Entry_x509_cert):
> - cert.<unique_name> - output file generated by openssl (which is
> used as the entry contents)
>
> + Depending on auth_in_place information in the inputs, we read the
> + firewall nodes that describe the configurations of firewall that TIFS
> + will be doing after reading the certificate.
> +
> + The syntax of the firewall nodes are as such:
> +
> + firewall-257-0 {
> + id = <257>; /* The ID of the firewall being configured */
> + region = <0>; /* Region number to configure */
> +
> + control = /* The control register */
> + <(FWCTRL_EN | FWCTRL_LOCK | FWCTRL_BG | FWCTRL_CACHE)>;
> +
> + permissions = /* The permission registers */
> + <((FWPRIVID_ALL << FWPRIVID_SHIFT) |
> + FWPERM_SECURE_PRIV_RWCD |
> + FWPERM_SECURE_USER_RWCD |
> + FWPERM_NON_SECURE_PRIV_RWCD |
> + FWPERM_NON_SECURE_USER_RWCD)>;
> +
> + /* More defines can be found in k3-security.h */
> +
> + start_address = /* The Start Address of the firewall */
> + <0x0 0x0>;
> + end_address = /* The End Address of the firewall */
> + <0xff 0xffffffff>;
> + };
> +
> +
> 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.
> @@ -32,11 +92,20 @@ class Entry_ti_secure(Entry_x509_cert):
> def __init__(self, section, etype, node):
> super().__init__(section, etype, node)
> self.openssl = None
> + self.firewall_cert_data: dict = {
> + 'auth_in_place': 0x02,
> + 'num_firewalls': 0,
> + 'certificate': "",
> + }
>
> def ReadNode(self):
> super().ReadNode()
> self.key_fname = self.GetEntryArgsOrProps([
> EntryArg('keyfile', str)], required=True)[0]
> + auth_in_place = fdt_util.GetInt(self._node, "auth_in_place")
Please use hyphens in properties. If that is a bool, use GetBool()
> + if auth_in_place:
> + self.firewall_cert_data['auth_in_place'] = auth_in_place
> + self.ReadFirewallNode()
> self.sha = fdt_util.GetInt(self._node, 'sha', 512)
> self.req_dist_name = {'C': 'US',
> 'ST': 'TX',
> @@ -46,6 +115,22 @@ class Entry_ti_secure(Entry_x509_cert):
> 'CN': 'TI Support',
> 'emailAddress': 'support at ti.com'}
>
> + def ReadFirewallNode(self):
> + self.firewall_cert_data['certificate'] = ""
> + self.firewall_cert_data['num_firewalls'] = 0
> + for node in self._node.subnodes:
> + if 'firewall' in node.name:
> + firewall = Firewall(
> + fdt_util.GetInt(node, 'id'),
> + fdt_util.GetInt(node, 'region'),
> + fdt_util.GetInt(node, 'control'),
> + fdt_util.GetPhandleList(node, 'permissions'),
> + fdt_util.GetInt64(node, 'start_address'),
> + fdt_util.GetInt64(node, 'end_address'),
What happens if some of these properties are missing?
> + )
> + self.firewall_cert_data['num_firewalls'] += 1
> + self.firewall_cert_data['certificate'] += firewall.get_certificate()
> +
> def GetCertificate(self, required):
> """Get the contents of this entry
>
> diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py
> index d028cfe38cd9..9e1cf479023b 100644
> --- a/tools/binman/etype/x509_cert.py
> +++ b/tools/binman/etype/x509_cert.py
> @@ -98,7 +98,8 @@ class Entry_x509_cert(Entry_collection):
> key_fname=self.key_fname,
> config_fname=config_fname,
> sw_rev=self.sw_rev,
> - req_dist_name_dict=self.req_dist_name)
> + req_dist_name_dict=self.req_dist_name,
> + firewall_cert_data=self.firewall_cert_data)
> elif type == 'rom':
> stdout = self.openssl.x509_cert_rom(
> cert_fname=output_fname,
>
> --
> 2.41.0
>
Regards,
Simon
More information about the U-Boot
mailing list