From bc6beae7c55f3adc1fc520ff8c3f4ec986f7c2ef Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 21 May 2024 12:48:23 +0200 Subject: binman: Add nxp_imx8mcst etype for i.MX8M flash.bin signing Add new binman etype which allows signing both the SPL and fitImage sections of i.MX8M flash.bin using CST. There are multiple DT properties which govern the signing process, nxp,loader-address is the only mandatory one which sets the SPL signature start address without the imx8mimage header, this should be SPL text base. The key material can be configured using optional DT properties nxp,srk-table, nxp,csf-crt, nxp,img-crt, all of which default the key material names generated by CST tool scripts. The nxp,unlock property can be used to unlock CAAM access in SPL section. Reviewed-by: Tim Harvey Signed-off-by: Marek Vasut --- tools/binman/btool/cst.py | 48 +++++++++++ tools/binman/etype/nxp_imx8mcst.py | 164 +++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 tools/binman/btool/cst.py create mode 100644 tools/binman/etype/nxp_imx8mcst.py (limited to 'tools') diff --git a/tools/binman/btool/cst.py b/tools/binman/btool/cst.py new file mode 100644 index 0000000..30e78bd --- /dev/null +++ b/tools/binman/btool/cst.py @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2024 Marek Vasut +# +"""Bintool implementation for cst""" + +import re + +from binman import bintool + +class Bintoolcst(bintool.Bintool): + """Image generation for U-Boot + + This bintool supports running `cst` with some basic parameters as + needed by binman. + """ + def __init__(self, name): + super().__init__(name, 'Sign NXP i.MX image') + + # pylint: disable=R0913 + def run(self, output_fname=None): + """Run cst + + Args: + output_fname: Output filename to write to + """ + args = [] + if output_fname: + args += ['-o', output_fname] + return self.run_cmd(*args) + + def fetch(self, method): + """Fetch handler for cst + + This installs cst using the apt utility. + + Args: + method (FETCH_...): Method to use + + Returns: + True if the file was fetched and now installed, None if a method + other than FETCH_BIN was requested + + Raises: + Valuerror: Fetching could not be completed + """ + if method != bintool.FETCH_BIN: + return None + return self.apt_install('imx-code-signing-tool') diff --git a/tools/binman/etype/nxp_imx8mcst.py b/tools/binman/etype/nxp_imx8mcst.py new file mode 100644 index 0000000..8221517 --- /dev/null +++ b/tools/binman/etype/nxp_imx8mcst.py @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2023-2024 Marek Vasut +# Written with much help from Simon Glass +# +# Entry-type module for generating the i.MX8M code signing tool +# input configuration file and invocation of cst on generated +# input configuration file and input data to be signed. +# + +import configparser +import os +import struct + +from collections import OrderedDict + +from binman.entry import Entry +from binman.etype.mkimage import Entry_mkimage +from binman.etype.section import Entry_section +from binman import elf +from dtoc import fdt_util +from u_boot_pylib import tools + +MAGIC_NXP_IMX_IVT = 0x412000d1 +MAGIC_FITIMAGE = 0xedfe0dd0 + +csf_config_template = """ +[Header] + Version = 4.3 + Hash Algorithm = sha256 + Engine = CAAM + Engine Configuration = 0 + Certificate Format = X509 + Signature Format = CMS + +[Install SRK] + File = "SRK_1_2_3_4_table.bin" + Source index = 0 + +[Install CSFK] + File = "CSF1_1_sha256_4096_65537_v3_usr_crt.pem" + +[Authenticate CSF] + +[Unlock] + Engine = CAAM + Features = MID + +[Install Key] + Verification index = 0 + Target Index = 2 + File = "IMG1_1_sha256_4096_65537_v3_usr_crt.pem" + +[Authenticate Data] + Verification index = 2 + Blocks = 0x1234 0x78 0xabcd "data.bin" +""" + +class Entry_nxp_imx8mcst(Entry_mkimage): + """NXP i.MX8M CST .cfg file generator and cst invoker + + Properties / Entry arguments: + - nxp,loader-address - loader address (SPL text base) + """ + + def __init__(self, section, etype, node): + super().__init__(section, etype, node) + self.required_props = ['nxp,loader-address'] + + def ReadNode(self): + super().ReadNode() + self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address') + self.srk_table = os.getenv('SRK_TABLE', fdt_util.GetString(self._node, 'nxp,srk-table', 'SRK_1_2_3_4_table.bin')) + self.csf_crt = os.getenv('CSF_KEY', fdt_util.GetString(self._node, 'nxp,csf-crt', 'CSF1_1_sha256_4096_65537_v3_usr_crt.pem')) + self.img_crt = os.getenv('IMG_KEY', fdt_util.GetString(self._node, 'nxp,img-crt', 'IMG1_1_sha256_4096_65537_v3_usr_crt.pem')) + self.unlock = fdt_util.GetBool(self._node, 'nxp,unlock') + self.ReadEntries() + + def BuildSectionData(self, required): + data, input_fname, uniq = self.collect_contents_to_file( + self._entries.values(), 'input') + + # Parse the input data and figure out what it is that is being signed. + # - If it is mkimage'd imx8mimage, then extract to be signed data size + # from imx8mimage header, and calculate CSF blob offset right past + # the SPL from this information. + # - If it is fitImage, then pad the image to 4k, add generated IVT and + # sign the whole payload, then append CSF blob at the end right past + # the IVT. + signtype = struct.unpack('