[PATCH RFC 2/3] WIP: getting signing nodes to work in FIT generator node

Neha Malcom Francis n-francis at ti.com
Thu Jul 27 14:12:04 CEST 2023


They need to get the contents of the FIT section beforehand, process
them and prepend the signing certificate to the FIT contents

Signed-off-by: Neha Malcom Francis <n-francis at ti.com>
---
 tools/binman/etype/collection.py | 38 +++++++++++++++++++++++---------
 tools/binman/etype/fit.py        |  1 +
 tools/binman/etype/ti_secure.py  | 13 ++++++++---
 tools/binman/etype/x509_cert.py  |  9 ++++++--
 4 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e..206d793a0d 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -10,6 +10,7 @@ import os
 
 from binman.entry import Entry
 from dtoc import fdt_util
+from u_boot_pylib import tools
 
 class Entry_collection(Entry):
     """An entry which contains a collection of other entries
@@ -28,8 +29,8 @@ class Entry_collection(Entry):
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
         self.content = fdt_util.GetPhandleList(self._node, 'content')
-        if not self.content:
-            self.Raise("Collection must have a 'content' property")
+        if not self.content and 'fit' not in self._node.path:
+            self.Raise("Collection must have a 'content' property unless it is in a fit, in which case it must have the entry contents")
 
     def GetContents(self, required):
         """Get the contents of this entry
@@ -44,19 +45,36 @@ class Entry_collection(Entry):
         # Join up all the data
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
-        for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
-            if not required and entry_data is None:
-                self.Info('Contents not available yet')
-                # Data not available yet
-                return None
-            data += entry_data
+        if self.content:
+            for entry_phandle in self.content:
+                entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
+                                                            required)
+                if not required and entry_data is None:
+                    self.Info('Contents not available yet')
+                    # Data not available yet
+                    return None
+                data += entry_data
+        else:
+            # it's part of FIT generated node
+            for seq, fdt_fname in enumerate(self.section.section._fdts):
+                # WIP: if fdt_fname corresponds to current processing node
+                if self.section.section._fit_indir:
+                    fname = tools.get_input_filename(fdt_fname + '.dtb', specific_indir=self.section.section._fit_indir)
+                else:
+                    fname = tools.get_input_filename(fdt_fname + '.dtb')
+                f = fname
+            sign_entry = Entry.Create(self.section.section, self._node, self.name)
+            dat = tools.read_file(f)
+            sign_entry.ReadNode()
+            sign_entry.AddBintools(sign_entry.bintools)
+            sign_entry.data = sign_entry.GetCertificate(True, dat)
+            data += sign_entry.data + dat
 
         self.Info('Returning contents size %x' % len(data))
 
         return data
 
+
     def ObtainContents(self):
         data = self.GetContents(False)
         if data is None:
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index 46db816370..7a433aa797 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -14,6 +14,7 @@ from dtoc import fdt_util
 from dtoc.fdt import Fdt
 from u_boot_pylib import tools
 
+signature_etypes = ['ti-secure', 'vblock']
 # Supported operations, with the fit,operation property
 OP_GEN_FDT_NODES, OP_SPLIT_ELF = range(2)
 OPERATIONS = {
diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
index d939dce571..0d08d0e4cc 100644
--- a/tools/binman/etype/ti_secure.py
+++ b/tools/binman/etype/ti_secure.py
@@ -38,6 +38,7 @@ class Entry_ti_secure(Entry_x509_cert):
         self.key_fname = self.GetEntryArgsOrProps([
             EntryArg('keyfile', str)], required=True)[0]
         self.sha = fdt_util.GetInt(self._node, 'sha', 512)
+        self.dat = None
         self.req_dist_name = {'C': 'US',
                 'ST': 'TX',
                 'L': 'Dallas',
@@ -46,23 +47,29 @@ class Entry_ti_secure(Entry_x509_cert):
                 'CN': 'TI Support',
                 'emailAddress': 'support at ti.com'}
 
-    def GetCertificate(self, required):
+    def GetCertificate(self, required, dat=None):
         """Get the contents of this entry
 
         Args:
             required: True if the data must be present, False if it is OK to
                 return None
+            dat: contents to sign if required instead of phandle
 
         Returns:
             bytes content of the entry, which is the certificate binary for the
                 provided data
         """
-        return super().GetCertificate(required=required, type='sysfw')
+        if dat is not None:
+            self.dat = dat
+        return super().GetCertificate(required=required, type='sysfw', dat=dat)
 
     def ObtainContents(self):
         data = self.data
         if data is None:
-            data = self.GetCertificate(False)
+            if self.dat is None:
+                data = self.GetCertificate(False)
+            else:
+                data = self.GetCertificate(False, self.dat)
         if data is None:
             return False
         self.SetContents(data)
diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py
index d028cfe38c..82299ec9bc 100644
--- a/tools/binman/etype/x509_cert.py
+++ b/tools/binman/etype/x509_cert.py
@@ -60,7 +60,7 @@ class Entry_x509_cert(Entry_collection):
             EntryArg('keyfile', str)], required=True)[0]
         self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
 
-    def GetCertificate(self, required, type='generic'):
+    def GetCertificate(self, required, type='generic', dat=None):
         """Get the contents of this entry
 
         Args:
@@ -68,13 +68,18 @@ class Entry_x509_cert(Entry_collection):
                 return None
             type: Type of x509 certificate to generate, current supported ones are
             'generic', 'sysfw', 'rom'
+            content: Bytes to consider as contents to be signed, helpful in case of
+            FIT image signing
 
         Returns:
             bytes content of the entry, which is the signed vblock for the
                 provided data
         """
         # Join up the data files to be signed
-        input_data = self.GetContents(required)
+        if dat is None:
+            input_data = self.GetContents(required)
+        else:
+            input_data = dat
         if input_data is None:
             return None
 
-- 
2.34.1



More information about the U-Boot mailing list