[PATCH] binman: Example for csf signing

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@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')
participants (1)
-
Simon Glass