[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