[PATCH] binman: Example for csf signing

Simon Glass sjg at chromium.org
Thu Aug 4 04:43:36 CEST 2022


This is a starting point for running a csf tool to sign some sections of
the image and add the signature in.

It is missing the test in ftest.py

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 arch/arm/dts/imx8mm-u-boot.dtsi  | 96 +++++++++++++++++++++-----------
 tools/binman/btool/csf.py        | 87 +++++++++++++++++++++++++++++
 tools/binman/etype/imx8mm_csf.py | 81 +++++++++++++++++++++++++++
 3 files changed, 230 insertions(+), 34 deletions(-)
 create mode 100644 tools/binman/btool/csf.py
 create mode 100644 tools/binman/etype/imx8mm_csf.py

diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi
index f792b421e89..8188d4b8db2 100644
--- a/arch/arm/dts/imx8mm-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-u-boot.dtsi
@@ -28,54 +28,82 @@
 };
 
 &binman {
-	u-boot-spl-ddr {
-		align = <4>;
-		align-size = <4>;
-		filename = "u-boot-spl-ddr.bin";
-		pad-byte = <0xff>;
-
-		u-boot-spl {
-			align-end = <4>;
-			filename = "u-boot-spl.bin";
+	secure-boot {
+		filename = "secure-boot.bin";
+		type = "section";
+		/* Image Vector Table - not sure what goes in here */
+		vector_table: vector-table {
+			type = "fill";
+			size = <0x20>;
 		};
 
-		ddr-1d-imem-fw {
-			filename = "lpddr4_pmu_train_1d_imem.bin";
-			align-end = <4>;
-			type = "blob-ext";
+		/* Something in here? Fixed size? */
+		boot_data: boot-data {
+			type = "fill";
+			size = <0x20>;
 		};
 
-		ddr-1d-dmem-fw {
-			filename = "lpddr4_pmu_train_1d_dmem.bin";
-			align-end = <4>;
-			type = "blob-ext";
-		};
+		/* Starts at 0x40 - *entry */
+		ddr: u-boot-spl-ddr {
+			type = "section";
+			align = <4>;
+			align-size = <4>;
+			filename = "u-boot-spl-ddr.bin";
+			pad-byte = <0xff>;
+
+			u-boot-spl {
+				align-end = <4>;
+				filename = "u-boot-spl.bin";
+			};
 
-		ddr-2d-imem-fw {
-			filename = "lpddr4_pmu_train_2d_imem.bin";
-			align-end = <4>;
-			type = "blob-ext";
-		};
+			ddr-1d-imem-fw {
+				filename = "lpddr4_pmu_train_1d_imem.bin";
+				align-end = <4>;
+				type = "blob-ext";
+			};
 
-		ddr-2d-dmem-fw {
-			filename = "lpddr4_pmu_train_2d_dmem.bin";
-			align-end = <4>;
-			type = "blob-ext";
+			ddr-1d-dmem-fw {
+				filename = "lpddr4_pmu_train_1d_dmem.bin";
+				align-end = <4>;
+				type = "blob-ext";
+			};
+
+			ddr-2d-imem-fw {
+				filename = "lpddr4_pmu_train_2d_imem.bin";
+				align-end = <4>;
+				type = "blob-ext";
+			};
+
+			ddr-2d-dmem-fw {
+				filename = "lpddr4_pmu_train_2d_dmem.bin";
+				align-end = <4>;
+				type = "blob-ext";
+			};
 		};
-	};
 
-	spl {
-		filename = "spl.bin";
+		spl: spl {
+			type = "section";
+			filename = "spl.bin";
+
+			/* need padding after this entry */
+			align-end = <0x10000>;
 
-		mkimage {
-			args = "-n spl/u-boot-spl.cfgout -T imx8mimage -e 0x7e1000";
+			mkimage {
+				args = "-n spl/u-boot-spl.cfgout -T imx8mimage -e 0x7e1000";
 
-			blob {
-				filename = "u-boot-spl-ddr.bin";
+				blob {
+					filename = "u-boot-spl-ddr.bin";
+				};
 			};
 		};
+
+		imx8mm-csf {
+			content = <&vector_table &boot_data &ddr &spl>;
+                        align-end = <0x1000>;   /* padding? */
+		};
 	};
 
+
 	itb {
 		filename = "u-boot.itb";
 
diff --git a/tools/binman/btool/csf.py b/tools/binman/btool/csf.py
new file mode 100644
index 00000000000..fc86d1021af
--- /dev/null
+++ b/tools/binman/btool/csf.py
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for csf
+
+comments here
+see 'csv' for what is needed
+"""
+
+from binman import bintool
+
+class Bintoolcsf(bintool.Bintool):
+    """Handles the 'csf' tool
+
+    docs here
+    """
+    def __init__(self, name):
+        super().__init__(name, 'Chromium OS firmware utility')
+
+    def gbb_create(self, fname, sizes):
+        """Create a new Google Binary Block
+
+        Args:
+            fname (str): Filename to write to
+            sizes (list of int): Sizes of each regions:
+               hwid_size, rootkey_size, bmpfv_size, recoverykey_size
+
+        Returns:
+            str: Tool output
+        """
+        args = [
+            'gbb_utility',
+            '-c',
+            ','.join(['%#x' % size for size in sizes]),
+            fname
+            ]
+        return self.run_cmd(*args)
+
+    def sign_firmware(self, outfile, firmware,):
+        """Sign firmware to create a csf file
+
+        Args:
+            outfile (str): Filename to write the csf to
+            firmware (str): Filename of firmware binary to sign
+
+        Returns:
+            str: Tool output
+        """
+        # run the command-line tool and get the output
+        args = [
+            'csf',
+            '--outfile', outfile,
+            '--firmware', firmware,
+            ]
+        return self.run_cmd(*args)
+
+    def fetch(self, method):
+        """Fetch handler for csv
+
+        This installs csv using a binary download.
+
+        Args:
+            method (FETCH_...): Method to use
+
+        Returns:
+            True if the file was fetched, None if a method other than FETCH_BIN
+            was requested
+
+        Raises:
+            Valuerror: Fetching could not be completed
+        """
+        if method != bintool.FETCH_BIN:
+            return None
+        fname, tmpdir = self.fetch_from_drive(
+            'something here')
+        return fname, tmpdir
+
+    def version(self):
+        """Version handler for csv
+
+        Returns:
+            str: Version string for csv
+        """
+        out = self.run_cmd('version').strip()
+        if not out:
+            return super().version()
+        return out
diff --git a/tools/binman/etype/imx8mm_csf.py b/tools/binman/etype/imx8mm_csf.py
new file mode 100644
index 00000000000..7c005ed1523
--- /dev/null
+++ b/tools/binman/etype/imx8mm_csf.py
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+# Test code only, for Marek Vasut
+#
+
+# Support for iMX8mm signing
+
+from collections import OrderedDict
+import os
+
+from binman.entry import EntryArg
+from binman.etype.collection import Entry_collection
+
+from dtoc import fdt_util
+from patman import tools
+
+class Entry_imx8mm_csf(Entry_collection):
+    """An entry which contains ...
+
+    Properties / Entry arguments:
+        - content: List of phandles to entries to sign
+        - other properties here
+
+    Output files:
+        - input.<unique_name> - input file passed to csf
+        - csf.<unique_name> - output file generated by csf_util
+
+    blurb here about what this does
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self.csf = None
+        #(self.arg1, self.arg2) = self.GetEntryArgsOrProps([
+            #EntryArg('keydir', str),
+            #EntryArg('keyblock', str))
+
+    def GetCsf(self, required):
+        """Get the contents of this entry
+
+        Args:
+            required: True if the data must be present, False if it is OK to
+                return None
+
+        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 input_data is None:
+            return None
+
+        uniq = self.GetUniqueName()
+        output_fname = tools.get_output_filename('csf.%s' % uniq)
+        input_fname = tools.get_output_filename('input.%s' % uniq)
+        tools.write_file(input_fname, input_data)
+        stdout = self.csf.sign_firmware(
+            outfile=output_fname,
+            firmware=input_fname)
+        if stdout is not None:
+            data = tools.read_file(output_fname)
+        else:
+            # Bintool is missing; just use 4KB of zero data
+            self.record_missing_bintool(self.csf)
+            data = tools.get_bytes(0, 4096)
+        return data
+
+    def ObtainContents(self):
+        data = self.GetCsf(False)
+        if data is None:
+            return False
+        self.SetContents(data)
+        return True
+
+    def ProcessContents(self):
+        # The blob may have changed due to WriteSymbols()
+        data = self.GetCsf(True)
+        return self.ProcessContentsUpdate(data)
+
+    def AddBintools(self, btools):
+        self.csf = self.AddBintool(btools, 'csf')
-- 
2.37.1.455.g008518b4e5-goog



More information about the U-Boot mailing list