[PATCH 1/5] tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing

Jérémie Dautheribes (Schneider Electric) via U-Bo ot <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
Add a new binman etype which allows signing both the SPL and U-Boot proper
sections of i.MX93 flash.bin using CST.
The implementation is largely derived from the nxp_imx8mcst etype, as the
signing procedures for both platforms are quite similar.

Signed-off-by: Jérémie Dautheribes (Schneider Electric) <[email protected]>
---
 .gitignore                         |   2 +
 tools/binman/etype/nxp_imx93cst.py | 143 +++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)

diff --git a/.gitignore b/.gitignore
index 0e09715cc60..5cb135fc58c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,6 +82,8 @@ fit-dtb.blob*
 /keep-syms-lto.*
 /*imx8mimage*
 /*imx8mcst*
+/*imx9image*
+/*imx93cst*
 /*rcar4-sa0*
 /drivers/video/u_boot_logo.bmp.S
 /test/fdt_overlay/test-fdt-overlay-stacked.dtbo.S
diff --git a/tools/binman/etype/nxp_imx93cst.py b/tools/binman/etype/nxp_imx93cst.py
new file mode 100644
index 00000000000..e1528b13102
--- /dev/null
+++ b/tools/binman/etype/nxp_imx93cst.py
@@ -0,0 +1,143 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2026 (C) Bootlin
+# Author: Jérémie Dautheribes <[email protected]>
+#
+# Derived from nxp_imx8mcst.py
+# Copyright 2023-2024 Marek Vasut <[email protected]>
+
+
+# Entry-type module for generating the i.MX93 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 binman.etype.mkimage import Entry_mkimage
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+CONTAINER_HDR_TAG = 0x87
+SPL_CONTAINER_OFFSET = 1024  # 0x400
+CONTAINER_HDR_SIZE = 16
+AHAB_IMAGE_ENTRY_FLAGS_OFFSET = 24
+ELE_IMAGE_CORE_AND_TYPE = 0x66
+
+KEY_NAME = "sha384_secp384r1_v3_usr_crt"
+
+CSF_CONFIG_TEMPLATE = f"""
+[Header]
+  Target = AHAB
+  Version = 1.0
+
+[Install SRK]
+  File = "SRK_1_2_3_4_table.bin"
+  Source = "SRK1_{KEY_NAME}.pem"
+  Source index = 0
+  Source set = OEM
+  Revocations = 0x0
+
+[Authenticate Data]
+  File = "data.bin"
+  Offsets	= 0x400	       0x490
+
+"""
+
+
+class Entry_nxp_imx93cst(Entry_mkimage):
+    """NXP i.MX93 CST .cfg file generator and cst invoker"""
+
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+
+    def ReadNode(self):
+        super().ReadNode()
+        self.srk_table = os.getenv(
+            "SRK_TABLE",
+            fdt_util.GetString(self._node, "nxp,srk-table", "SRK_1_2_3_4_table.bin"),
+        )
+        self.srk_crt = os.getenv(
+            "SRK_KEY",
+            fdt_util.GetString(self._node, "nxp,srk-crt", f"SRK1_{KEY_NAME}.pem"),
+        )
+        self.ReadEntries()
+
+    def BuildSectionData(self, required):
+        data, input_fname, uniq = self.collect_contents_to_file(
+            self._entries.values(), "input"
+        )
+
+        if struct.unpack("<B", data[3:4])[0] != CONTAINER_HDR_TAG:
+            # Unknown section type, pass input data through.
+            return data
+
+        hdr_addr = 0
+
+        # The SPL AHAB image can optionally contain and start with the ELE FW,
+        # which is already signed by NXP.
+        # In this case, the SPL container header address is not 0x0.
+
+        flags_offset = CONTAINER_HDR_SIZE + AHAB_IMAGE_ENTRY_FLAGS_OFFSET
+        image_flags = struct.unpack("<I", data[flags_offset : flags_offset + 4])[0]
+        # Detect the ELE FW from the core/type fields of its image entries
+        if (image_flags & 0xFF) == ELE_IMAGE_CORE_AND_TYPE:
+            hdr_addr = SPL_CONTAINER_OFFSET
+
+        # Extract the signing offset from the i.MX container
+        signoffset = struct.unpack("<H", data[hdr_addr + 12 : hdr_addr + 14])[0]
+
+        # The signing offset is relative to the container header address,
+        # so compute the absolute signing offset address
+        signoffset = signoffset + hdr_addr
+
+        # Write out customized data to be signed
+        output_dname = tools.get_output_filename(f"nxp.cst-input-data.{uniq}")
+        tools.write_file(output_dname, data)
+
+        # Generate CST configuration file used to sign payload
+        cfg_fname = tools.get_output_filename(f"nxp.csf-config-txt.{uniq}")
+        config = configparser.ConfigParser()
+        # Do not make key names lowercase
+        config.optionxform = str
+        # Load configuration template and modify keys of interest
+        config.read_string(CSF_CONFIG_TEMPLATE)
+        config["Install SRK"]["File"] = f'"{self.srk_table}"'
+        config["Install SRK"]["Source"] = f'"{self.srk_crt}"'
+        config["Authenticate Data"]["File"] = f'"{output_dname}"'
+        config["Authenticate Data"]["Offsets"] = f"{hdr_addr:#x} {signoffset:#x}"
+
+        with open(cfg_fname, "w") as cfgf:
+            config.write(cfgf)
+
+        output_fname = tools.get_output_filename(f"nxp.csf-output-blob.{uniq}")
+        args = ["-i", cfg_fname, "-o", output_fname]
+        if self.cst.run_cmd(*args) is not None:
+            outdata = tools.read_file(output_fname)
+            return outdata
+        else:
+            # Bintool is missing; just use the input data as the output
+            self.record_missing_bintool(self.cst)
+            return data
+
+    def SetImagePos(self, image_pos):
+        # Customized SoC specific SetImagePos which skips the mkimage etype
+        # implementation and removes the 0x48 offset introduced there. That
+        # offset is only used for uImage/fitImage, which is not the case in
+        # here.
+        upto = 0x00
+        for entry in super().GetEntries().values():
+            entry.SetOffsetSize(upto, None)
+
+            # Give up if any entries lack a size
+            if entry.size is None:
+                return
+            upto += entry.size
+
+        Entry_section.SetImagePos(self, image_pos)
+
+    def AddBintools(self, btools):
+        super().AddBintools(btools)
+        self.cst = self.AddBintool(btools, "cst")

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.