[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