Hi Manorit

On 05/09/23 13:51, Manorit Chawdhry 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-chawd...@ti.com>
---
  tools/binman/btool/openssl.py   | 16 ++++++++++--
  tools/binman/etype/ti_secure.py | 54 +++++++++++++++++++++++++++++++++++++++++
  tools/binman/etype/x509_cert.py |  3 ++-
  3 files changed, 70 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']}
  ''', 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..a980d10f4197 100644
--- a/tools/binman/etype/ti_secure.py
+++ b/tools/binman/etype/ti_secure.py
@@ -7,9 +7,39 @@
from binman.entry import EntryArg
  from binman.etype.x509_cert import Entry_x509_cert
+from dataclasses import dataclass
from dtoc import fdt_util +def hex_octet(n):
+  x = '%x' % (n,)
+  return ('0' * (len(x) % 2)) + x
+

If this was the only way to grab the address this way, maybe consider adding this as a common fdt_util function?

+@dataclass
+class Firewall():
+    id: int
+    region: int
+    control : int
+    permissions: list[hex]
+    start_address: str
+    end_address: str
+
+    def get_certificate(self) -> str:
+        unique_indentifier = f"{self.id}{self.region}"
+        cert = f"""
+firewallID{unique_indentifier} = INTEGER:{self.id}
+region{unique_indentifier} = INTEGER:{self.region}
+control{unique_indentifier} = INTEGER:{hex(self.control)}
+nPermissionRegs{unique_indentifier} = INTEGER:{len(self.permissions)}
+"""

s/indentifier/identifier ?

+        for index, permission in enumerate(self.permissions):
+            cert += f"""permissions{unique_indentifier}{index} = 
INTEGER:{hex(permission)}
+"""
+        cert += f"""startAddress{unique_indentifier} = 
FORMAT:HEX,OCT:{hex_octet(self.start_address)}
+endAddress{unique_indentifier} = FORMAT:HEX,OCT:{hex_octet(self.end_address)}
+"""
+        return cert
+
  class Entry_ti_secure(Entry_x509_cert):
      """Entry containing a TI x509 certificate binary
@@ -32,11 +62,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")
+        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 +85,21 @@ class Entry_ti_secure(Entry_x509_cert):
                  'CN': 'TI Support',
                  'emailAddress': 'supp...@ti.com'}
+ def ReadFirewallNode(self):
+        self.firewall_cert_data['certificate'] = ""
+        self.firewall_cert_data['num_firewalls'] = 0
+        for node in self._node.subnodes:
+            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'),
+            )
+            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,

For v1:
- ti-secure node should contain the documentation of how to use this firewall sub-node, basically whatever you've put in x509_cert_sysfw()
- add test(s) for complete test coverage

--
Thanking You
Neha Malcom Francis

Reply via email to