* [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing
@ 2026-09-02 13:41 Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 1/7] binman: add nxp_imxcst base etype for i.MX CST signing Jérémie Dautheribes (Schneider Electric)
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Hello,
This series adds support for signing i.MX93 images by leveraging binman
and CST, the NXP tool used for secure boot. This introduces a new binman
entry type (etype) for this purpose.
As the implementation is largely similar to the existing i.MX8M support,
this series also introduce a new common nxp_imxcst etype to share the
common functionnalities.
This procedure has been tested on the imx93-evk board, using both ECDSA
and RSA-PSS keys.
Patches 1-2: introduces the new common etype and convert the imx8cst one
Patch 3: introduce the new nxp_imx93cst etype
Patch 4: updates the imx93-u-boot.dtsi description to include the new
signing nodes
Patches 5-6: documentation
Patch 7: adds test coverage
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
Changes in v2:
- Following Simong Glass' feedback:
- Created a new common class shared between the nxp_imx8mcst and the
nxp_imx93cst etypes
- rewrote the doc in reStructuredText and mention binman instead of
imx-mkimage
- took into account the other minor suggestions
- Link to v1: https://patch.msgid.link/20260814-imx93-secureboot-v1-0-0c3c78020d03@bootlin.com
To: "NXP i.MX U-Boot Team" <uboot-imx@nxp.com>
To: u-boot@lists.u-boot-project.org
Cc: Miquèl Raynal <miquel.raynal@bootlin.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Cc: Stefano Babic <sbabic@nabladev.com>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: "Jérémie Dautheribes (Schneider Electric)" <jeremie.dautheribes@bootlin.com>
Cc: Marek Vasut <marex@nabladev.com>
Cc: Denis Mukhin <dmukhin@ford.com>
Cc: Rasmus Villemoes <rv@rasmusvillemoes.dk>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Krzysztof Drobiński <krzysztof@kd-solutions.pl>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Alice Guo <alice.guo@nxp.com>
Cc: Simona Toaca <simona.toaca@nxp.com>
Cc: Ye Li <ye.li@nxp.com>
Cc: Quentin Schulz <quentin.schulz@cherry.de>
Cc: Christophe Guerreiro <christophe.guerreiro@non.se.com>
---
Jérémie Dautheribes (Schneider Electric) (7):
binman: add nxp_imxcst base etype for i.MX CST signing
binman: nxp_imx8mcst: use the nxp_imxcst base etype
tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing
imx93-u-boot: wrap SPL and U-Boot nodes in a CST node if AHAB_BOOT enabled
doc: imx: ahab: add AHAB introduction
doc: imx: ahab: add i.MX93 secure boot guide
binman: test: add code coverage for nxp_imx93cst etype
.gitignore | 2 +
arch/arm/dts/imx93-u-boot.dtsi | 54 ++-
doc/board/nxp/index.rst | 2 +
doc/imx/ahab/guides/mx93_secure_boot.rst | 294 +++++++++++++
doc/imx/ahab/guides/mx93_secure_boot.txt | 269 ++++++++++++
doc/imx/ahab/introduction_ahab.rst | 465 +++++++++++++++++++++
doc/imx/ahab/introduction_ahab.txt | 445 ++++++++++++++++++++
doc/imx/index.rst | 14 +
tools/binman/etype/nxp_imx8mcst.py | 60 +--
tools/binman/etype/nxp_imx93cst.py | 112 +++++
tools/binman/etype/nxp_imxcst.py | 121 ++++++
tools/binman/ftest.py | 85 ++++
tools/binman/test/vendor/nxp_imx93_csf.dts | 18 +
.../binman/test/vendor/nxp_imx93_csf_imagename.dts | 24 ++
14 files changed, 1896 insertions(+), 69 deletions(-)
---
base-commit: 4a4bcb0ada8d43390e2819e62f4baee723631f5d
change-id: 20260814-imx93-secureboot-b914e7b6cbbf
Best regards,
--
Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/7] binman: add nxp_imxcst base etype for i.MX CST signing
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 2/7] binman: nxp_imx8mcst: use the nxp_imxcst base etype Jérémie Dautheribes (Schneider Electric)
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Add a common etype which provides the shared functionality for signing
i.MX images with the NXP Code Signing Tool (CST). This includes the SRK
table property handling, the CST bintool registration, and helpers for
writing the input data and configuration files and for running cst.
The nxp_imx8mcst etype and the upcoming nxp_imx93cst etype will be
converted to use this common base in the following commits.
No functional changes.
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
tools/binman/etype/nxp_imxcst.py | 121 +++++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/tools/binman/etype/nxp_imxcst.py b/tools/binman/etype/nxp_imxcst.py
new file mode 100644
index 00000000000..3f863704b87
--- /dev/null
+++ b/tools/binman/etype/nxp_imxcst.py
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2026 (C) Bootlin
+# Author: Jérémie Dautheribes <jeremie.dautheribes@bootlin.com>
+#
+# Derived from nxp_imx8mcst.py
+# Copyright 2023-2024 Marek Vasut <marex@denx.de>
+
+# Entry-type module for NXP i.MX Code Signing Tool (CST) base class
+#
+
+import configparser
+import os
+
+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
+
+
+class Entry_nxp_imxcst(Entry_mkimage):
+ """NXP i.MX CST .cfg file generator and cst invoker base class
+
+ Properties / Entry arguments:
+ - nxp,srk-table - full path to SRK_1_2_3_4_table.bin
+ """
+
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.cst = None
+ self.srk_table = None
+
+ 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'),
+ )
+
+ 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')
+
+ def write_input_data(self, data, uniq):
+ """Write input data to a temporary file for CST
+
+ Args:
+ data: Data to write
+ uniq: Unique string for naming output files
+
+ Returns:
+ str: Path to the written file
+ """
+ output_dname = tools.get_output_filename(f'nxp.cst-input-data.{uniq}')
+ tools.write_file(output_dname, data)
+ return output_dname
+
+ def get_config(self, template):
+ """Get a ConfigParser loaded with the given template
+
+ Args:
+ template: Configuration template string
+
+ Returns:
+ ConfigParser instance
+ """
+ config = configparser.ConfigParser()
+ # Do not make key names lowercase
+ config.optionxform = str
+ config.read_string(template)
+ return config
+
+ def write_config(self, config, uniq):
+ """Write ConfigParser object to a temporary file for CST
+
+ Args:
+ config: ConfigParser instance
+ uniq: Unique string for naming output files
+
+ Returns:
+ str: Path to the written configuration file
+ """
+ cfg_fname = tools.get_output_filename(f'nxp.csf-config-txt.{uniq}')
+ with open(cfg_fname, 'w') as cfgf:
+ config.write(cfgf)
+ return cfg_fname
+
+ def run_cst(self, cfg_fname, uniq, backend=None):
+ """Run CST tool with given configuration file
+
+ Args:
+ cfg_fname: Filename of the CST configuration file
+ uniq: Unique string for naming output files
+ backend: Optional backend (e.g. 'ssl' or 'pkcs11')
+
+ Returns:
+ bytes: Output data from CST, or None if bintool is missing
+ """
+ output_fname = tools.get_output_filename(f'nxp.csf-output-blob.{uniq}')
+ args = ['-i', cfg_fname, '-o', output_fname]
+ if backend:
+ args.extend(['-b', backend])
+ if self.cst.run_cmd(*args) is not None:
+ return tools.read_file(output_fname)
+ self.record_missing_bintool(self.cst)
+ return None
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/7] binman: nxp_imx8mcst: use the nxp_imxcst base etype
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 1/7] binman: add nxp_imxcst base etype for i.MX CST signing Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 3/7] tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Use the freshly introduced new nxp_imxcst base etype and remove
dupplicated code.
This should not have any functional impact.
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
tools/binman/etype/nxp_imx8mcst.py | 60 +++++++-------------------------------
1 file changed, 10 insertions(+), 50 deletions(-)
diff --git a/tools/binman/etype/nxp_imx8mcst.py b/tools/binman/etype/nxp_imx8mcst.py
index 29a7451678d..3f81b9f83c6 100644
--- a/tools/binman/etype/nxp_imx8mcst.py
+++ b/tools/binman/etype/nxp_imx8mcst.py
@@ -7,16 +7,10 @@
# 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 binman.etype.nxp_imxcst import Entry_nxp_imxcst
from dtoc import fdt_util
from u_boot_pylib import tools
@@ -61,7 +55,8 @@ CSF_CONFIG_TEMPLATE = f'''
Blocks = 0x1234 0x78 0xabcd "data.bin"
'''
-class Entry_nxp_imx8mcst(Entry_mkimage):
+
+class Entry_nxp_imx8mcst(Entry_nxp_imxcst):
"""NXP i.MX8M CST .cfg file generator and cst invoker
Properties / Entry arguments:
@@ -82,9 +77,6 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
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.fast_auth = fdt_util.GetBool(self._node, 'nxp,fast-auth')
if not self.fast_auth:
self.csf_crt = os.getenv(
@@ -158,17 +150,11 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
return data
# 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)
+ output_dname = self.write_input_data(data, uniq)
# 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 = self.get_config(CSF_CONFIG_TEMPLATE)
+ config['Install SRK']['File'] = f'"{self.srk_table}"'
if not self.fast_auth:
config.remove_section('Install NOCAK')
config['Install CSFK']['File'] = f'"{self.csf_crt}"'
@@ -184,8 +170,7 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
if not self.unlock:
config.remove_section('Unlock')
- with open(cfg_fname, 'w') as cfgf:
- config.write(cfgf)
+ cfg_fname = self.write_config(config, uniq)
# SSL is the default backend, PKCS11 backend is optional
if self.backend == "pkcs11":
@@ -193,34 +178,9 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
else:
cst_backend = "ssl"
- output_fname = tools.get_output_filename(f'nxp.csf-output-blob.{uniq}')
- args = ['-i', cfg_fname, '-o', output_fname, '-b', cst_backend]
- if self.cst.run_cmd(*args) is not None:
- outdata = tools.read_file(output_fname)
+ outdata = self.run_cst(cfg_fname, uniq, cst_backend)
+ if outdata is not None:
# fixme: 0x2000 should be CONFIG_CSF_SIZE
outdata += tools.get_bytes(0, 0x2000 - 0x20 - len(outdata))
return data + 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')
+ return data
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/7] tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 1/7] binman: add nxp_imxcst base etype for i.MX CST signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 2/7] binman: nxp_imx8mcst: use the nxp_imxcst base etype Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 4/7] imx93-u-boot: wrap SPL and U-Boot nodes in a CST node if AHAB_BOOT enabled Jérémie Dautheribes (Schneider Electric)
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Add a binman etype which allows signing the SPL and U-Boot proper
sections of the i.MX93 flash.bin using CST and AHAB. The implementation
reuses the shared functionality from the nxp_imxcst base etype.
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
.gitignore | 2 +
tools/binman/etype/nxp_imx93cst.py | 112 +++++++++++++++++++++++++++++++++++++
2 files changed, 114 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..41326728c5d
--- /dev/null
+++ b/tools/binman/etype/nxp_imx93cst.py
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2026 (C) Bootlin
+# Author: Jérémie Dautheribes <jeremie.dautheribes@bootlin.com>
+#
+# Derived from nxp_imx8mcst.py
+# Copyright 2023-2024 Marek Vasut <marex@denx.de>
+
+# 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 os
+import struct
+
+from binman.etype.nxp_imxcst import Entry_nxp_imxcst
+from dtoc import fdt_util
+
+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 = 0x0 0x0
+
+'''
+
+
+class Entry_nxp_imx93cst(Entry_nxp_imxcst):
+ """NXP i.MX93 CST .cfg file generator and cst invoker
+
+ Properties / Entry arguments:
+ - nxp,srk-table - full path to SRK_1_2_3_4_table.bin
+ - nxp,srk-crt - full path to the SRK Key SRK1_sha384_secp384r1_v3_usr_crt.pem
+
+ The nxp,srk-table and nxp,srk-crt properties can be overridden with
+ the SRK_TABLE and SRK_KEY environment variables, respectively.
+ """
+
+ def ReadNode(self):
+ super().ReadNode()
+ 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, _, uniq = self.collect_contents_to_file(self._entries.values(), 'input')
+
+ flags_offset = CONTAINER_HDR_SIZE + AHAB_IMAGE_ENTRY_FLAGS_OFFSET
+
+ # Give up early if the input is too short to contain the container
+ # header fields read below
+ if len(data) < flags_offset + 4:
+ return data
+
+ if data[3] != 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.
+
+ 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 = self.write_input_data(data, uniq)
+
+ # Generate CST configuration file used to sign payload
+ config = self.get_config(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}'
+
+ cfg_fname = self.write_config(config, uniq)
+
+ outdata = self.run_cst(cfg_fname, uniq)
+ if outdata is not None:
+ return outdata
+ return data
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/7] imx93-u-boot: wrap SPL and U-Boot nodes in a CST node if AHAB_BOOT enabled
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
` (2 preceding siblings ...)
2026-09-02 13:41 ` [PATCH v2 3/7] tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 5/7] doc: imx: ahab: add AHAB introduction Jérémie Dautheribes (Schneider Electric)
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
When CONFIG_AHAB_BOOT is enabled, wrap the SPL and U-Boot binman nodes in
a CST node so that binman signs them automatically.
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
arch/arm/dts/imx93-u-boot.dtsi | 54 +++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 19 deletions(-)
diff --git a/arch/arm/dts/imx93-u-boot.dtsi b/arch/arm/dts/imx93-u-boot.dtsi
index bd970c955cf..569b3ef5d9c 100644
--- a/arch/arm/dts/imx93-u-boot.dtsi
+++ b/arch/arm/dts/imx93-u-boot.dtsi
@@ -47,32 +47,48 @@
filename = "flash.bin";
pad-byte = <0x00>;
- spl {
- type = "nxp-imx9image";
- cfg-path = "spl/u-boot-spl.cfgout";
+#ifdef CONFIG_AHAB_BOOT
+ nxp-imx93cst@0 {
+ filename = "spl.signed.bin";
args;
-
- boot-from = "sd";
- soc-type = "IMX9";
- append = "mx93a1-ahab-container.img";
- container;
- image = "a55", "u-boot-spl-ddr.bin", "0x2049A000";
+#endif
+ spl {
+ type = "nxp-imx9image";
+ cfg-path = "spl/u-boot-spl.cfgout";
+ args;
+
+ boot-from = "sd";
+ soc-type = "IMX9";
+ append = "mx93a1-ahab-container.img";
+ container;
+ image = "a55", "u-boot-spl-ddr.bin", "0x2049A000";
+ };
+#ifdef CONFIG_AHAB_BOOT
};
+#endif
- u-boot {
- type = "nxp-imx9image";
- cfg-path = "u-boot-container.cfgout";
+#ifdef CONFIG_AHAB_BOOT
+ nxp-imx93cst@1 {
+ filename = "u-boot-container.signed.bin";
args;
-
- boot-from = "sd";
- soc-type = "IMX9";
- container;
- image0 = "a55", "bl31.bin", "0x204E0000";
- image1 = "a55", "u-boot.bin", "0x80200000";
+#endif
+ u-boot {
+ type = "nxp-imx9image";
+ cfg-path = "u-boot-container.cfgout";
+ args;
+
+ boot-from = "sd";
+ soc-type = "IMX9";
+ container;
+ image0 = "a55", "bl31.bin", "0x204E0000";
+ image1 = "a55", "u-boot.bin", "0x80200000";
#if defined(CONFIG_OPTEE)
- image2 = "a55", "tee.bin", "0x96000000";
+ image2 = "a55", "tee.bin", "0x96000000";
#endif
+ };
+#ifdef CONFIG_AHAB_BOOT
};
+#endif
};
};
};
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/7] doc: imx: ahab: add AHAB introduction
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
` (3 preceding siblings ...)
2026-09-02 13:41 ` [PATCH v2 4/7] imx93-u-boot: wrap SPL and U-Boot nodes in a CST node if AHAB_BOOT enabled Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 6/7] doc: imx: ahab: add i.MX93 secure boot guide Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 7/7] binman: test: add code coverage for nxp_imx93cst etype Jérémie Dautheribes (Schneider Electric)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Add an introductory document describing the AHAB (Advanced High
Assurance Boot) secure and encrypted boot flow, covering the
following topics:
- AHAB architecture overview (SCU, SECO, PKI tree)
- AHAB secure boot and encrypted boot flow
- PKI tree generation (ahab_pki_tree.sh)
- SRK Table and SRK Hash generation (srktool)
- SRK Hash fuse programming and sanity check notes
- i.MX 8ULP/93 secure boot support
This is based on doc/imx/ahab/introduction_ahab.txt from uboot-imx
(lf_v2026.04). Originally written by Breno Lima, with contributions
from Ye Li, Vanessa Maegima, and Utkarsh Gupta upstream in
uboot-imx.
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
doc/board/nxp/index.rst | 2 +
doc/imx/ahab/introduction_ahab.rst | 464 +++++++++++++++++++++++++++++++++++++
doc/imx/ahab/introduction_ahab.txt | 445 +++++++++++++++++++++++++++++++++++
doc/imx/index.rst | 13 ++
4 files changed, 924 insertions(+)
diff --git a/doc/board/nxp/index.rst b/doc/board/nxp/index.rst
index b28e5b6ceb9..29a90297675 100644
--- a/doc/board/nxp/index.rst
+++ b/doc/board/nxp/index.rst
@@ -29,6 +29,8 @@ NXP Semiconductors
mx6sabresd
mx6ul_14x14_evk
mx6ullevk
+
+ i.MX AHAB secure boot <../../imx/index>
rproc
psb
quickboot
diff --git a/doc/imx/ahab/introduction_ahab.rst b/doc/imx/ahab/introduction_ahab.rst
new file mode 100644
index 00000000000..aef75b5e841
--- /dev/null
+++ b/doc/imx/ahab/introduction_ahab.rst
@@ -0,0 +1,464 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+i.MX Secure and Encrypted Boot using AHAB
+=========================================
+
+1. Introduction
+---------------
+
+The i.MX 8/8x/8ULP/9x family of applications processors introduce a new secure
+boot concept. Due to the multi-core architecture, the Security Controller (SECO)
+and System Control Unit (SCU) in i.MX 8/8x, and EdgeLock secure enclave (ELE)
+in i.MX 8ULP/9x are heavily involved in the secure boot process.
+
+Step-by-step guides are available under doc/imx/ahab/guides/ directory,
+users familiar with AHAB architecture and CST PKI tree generation should
+refer to these documents instead.
+
+1.1 The AHAB Secure Boot Architecture
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Advanced High Assurance Boot (AHAB) feature relies in digital signatures to
+prevent unauthorized software execution during the device boot sequence. In
+case a malware takes control of the boot sequence, sensitive data, services and
+network can be impacted.
+
+The AHAB authentication is based on public key cryptography in which image
+data is signed offline using one or more private keys. The resulting signed
+image data is then verified on the i.MX processor using the corresponding
+public keys. The public keys are included in the final binary and the SRK
+Hash is programmed in the SoC fuses for establishing the root of trust.
+
+In i.MX8 and i.MX8x families the SCU is responsible to interface with the boot
+media, managing the process of loading the firmware and software images in
+different partitions of the SoC. The SECO is responsible to authenticate the
+images and authorize the execution of them.
+
+1.1.1 [i.MX 8/8x] The System Control Unit (SCU)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The System Control Unit SCU is a subsystem equipped with a programmable M4
+core, which is responsible to handle the resource allocation, power, clocking,
+IO configuration and muxing.
+
+The SCU is also responsible to interface between the rest of the system. In the
+secure boot flow the SCU interfaces with the Security Controller (SECO),
+requesting the image authentication.
+
+The System Control Unit FW (SCFW) is responsible to control all the
+functionalities of the SCU. This firmware is distributed in a porting kit form.
+Instructions to download the SCFW Porting Kit are available in the Linux BSP
+Release Notes.
+
+Details about SCU can be found in the processors Reference Manual (RM).
+
+1.1.2 [i.MX 8/8x] The Security Controller (SECO)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The SECO is a M0+ core dedicated to handle the SoC security subsystem. The
+controller communicates with SCU domain through a dedicate message unit (MU).
+
+The SECO has a dedicate ROM which is responsible to initialize low level
+security features and to authenticate the SECO firmware previously loaded by
+the SCU ROM.
+
+The SECO firmware provides security services at run-time to different domains
+of the SoC, one of these being the capability of authenticate images.
+
+The SECO firmware is signed and distributed by NXP and is always authenticated
+in OEM open and closed configuration, instructions to download the SECO FW are
+available in the Linux BSP Release Notes.
+
+Details about SECO can be found in the processors Security Reference Manual
+(SRM).
+
+1.1.3 [i.MX 8ULP/9x] The EdgeLock secure enclave
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+EdgeLock Secure Enclave is the security subsystem based on a dedicated core
+(RISC-V) to manage security tasks with a tight control on security resources
+along with other enhancements.
+
+The secure enclave has a dedicate ROM which is responsible to initialize low
+level security features and to authenticate the secure enclave firmware
+previously loaded by the boot management core.
+
+The secure enclave firmware provides security services at run-time to different
+domains of the SoC, one of these being the capability of authenticate images.
+
+The secure enclave firmware is signed and distributed by NXP and is always
+authenticated in OEM open and closed configuration, instructions to download
+this FW are available in the Linux BSP Release Notes.
+
+Details about EdgeLock secure enclave can be found in the processors Security
+Reference Manual (SRM).
+
+.. note::
+
+ The terms Sentinel, S400, and EdgeLock secure enclave (ELE)
+ are used interchangeably throughout the document.
+
+1.2 The image container
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to the new architecture, multiple firmwares and software are required to
+boot AHAB supporting devices. In order to store all the images in a single
+binary the container image structure is used.
+
+At least two containers are needed for the boot process, the first container
+must include only the Security Subsystem FW (SECO/ELE FW provided by NXP).
+Additional containers can contain one or multiple images, depending on the
+users specific application.
+
+The final binary is generated by the binman tool.
+
+1.3 The i.MX8/8x secure boot flow
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned in the introduction, due to the multiple cores architecture the
+i.MX8 boot sequence involves SCU ROM, SCFW, SECO ROM, and SECO FW.
+
+The diagram below illustrate the secure boot flow overview:
+
+.. code-block:: text
+
+ System Controller │ Security Controller │ Cortex-M │ Cortex-A
+ (SCU) │ (SECO) │ │
+ │ │ │
+ ╔═════════════╗ │ ╔═════════════╗ ┌───────────┐ ┌─────────┐
+ ║ SCU INIT ║ │ ║ SECO INIT ║ │ │ │ │ │ │
+ ╚══════╤══════╝ │ ╚══════╤══════╝ │ │ v │ │ v
+ │ │ │ │ │ ┌──────────┐ │ │ ┌────────────┐
+ ╔══════╧══════╗ │ │ │ │ │ Start M4 │ │ │ │ Start AP │
+ ║Load SECO FW ║ │ │ │ │ │ IMG │ │ │ │ IMG │
+ ╚══════╤══════╝ │ ╔══════╧══════╗ │ │ └──────────┘ │ │ └─────┬──────┘
+ ├──────────────>║Auth SECO FW ║ │ │ │ │ │
+ ╔══════╧══════╗ │ ╚══════╤══════╝ │ │ ┌────────────┘ │ │
+ ║ Load SCU FW ║ │ │ │ │ │ │ │
+ ║ and DCD ║ │ │ │ │ │ │ ┌─────┴──────┐
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ Load │
+ ├──────────────>│ Auth SCU FW │ │ │ │ │ │ Add AP IMG │
+ │ │ │ and DCD │ │ │ │ │ └─────┬──────┘
+ ╔══════╧══════╗ │ └──────┬──────┘ │ │ │ │ │
+ ║ Run DCD ║<──────────────┤ │ │ │ │ │
+ ╚══════╤══════╝ │ │ │ │ │ ┌───────────────┤
+ │ │ │ │ │ │ │ │ │
+ ╔══════╧══════╗ │ │ │ │ │ │ │ │
+ ║ Load M4 IMG ║ │ │ │ │ │ │ │ │
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ │
+ ├──────────────>│ Auth M4 IMG │ │ │ │ │ │ │
+ ╔══════╧══════╗ │ └──────┬──────┘ │ │ │ │ │ ┌─────┴──────┐
+ ║ Load AP IMG ║ │ │ │ │ │ │ │ │ Run │
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ │ Add AP IMG │
+ ├──────────────>│ Auth AP IMG │ │ │ │ │ │ └────────────┘
+ ╔══════╧══════╗ │ └─────────────┘ │ │ │ │ │
+ ║Start SCU FW ║ │ ┌──────────────────┘ │ │ │ │
+ ╚══════╤══════╝ │ │ │ │ │ │
+ │ │ │ ┌─────────────────────┘ │ │
+ ┌──────┴──────┐ │ │ │ │ │ │
+ │ Start M4 ├──────┘ │ ┌──────────────────────┘ │
+ └──────┬──────┘ │ │ │ │ │
+ │ │ │ │ │ │
+ ┌──────┴──────┐ │ │ │ │ │
+ │ Start AP ├──────────┘ │ │ │
+ └─────────────┘ │ │ │ │
+ ┌───────────────────────┘ │ │
+ │ │ │ │
+ v │ │ │
+ ┌─────────────┐ │ ┌─────────────┐ │ │
+ │Request SECO ├───────>│ Auth AP IMG │ │ │
+ └─────────────┘ │ └─────────────┘ │ │
+ │ │ │
+
+Notes: All boxes enclosed by double dash (═) are performed at SCU/SECO ROM
+level.
+
+The sequence below explains the i.MX8 and i.MX8x boot flow:
+
+1. At reset, the SCU ROM and SECO ROM both start execution.
+2. The SCU ROM reads the boot configuration and loads the SECO FW (First
+ container) from the boot media to the SECO TCM.
+3. A message is sent by the SCU ROM via MU requesting the SECO ROM to
+ authenticate the SECO FW which is signed using NXP key.
+4. The SCU ROM loads the second container from the boot media, this container
+ must contain at least the SCFW which is signed using the OEM keys.
+5. The SCU ROM loads the SCFW to the SCU TCM, a message is sent via MU
+ requesting the SECO FW to authenticate the SCFW and DCD table.
+6. The SCU ROM configures the DDR and loads the M4 and AP images included in
+ the second container to their respective load addresses.
+7. The SCU ROM request the SECO FW to authenticate the M4 image.
+8. The SCU ROM request the SECO FW to authenticate the AP image. This image
+ is the initial AP core software, depending in the U-Boot target it can
+ be the U-Boot and ATF or only SPL.
+9. The SCFW is initialized and starts the ARM Cortex-M and Cortex-A cores.
+10. From this point additional containers can be loaded by Cortex-M and
+ Cortex-A cores and authenticated by SECO, the AP SW must interface with
+ SCU by calling the sc_misc_seco_authenticate() API function. In current
+ U-Boot implementation the additional image can be the Linux Kernel binary
+ or the U-Boot proper and ATF.
+
+1.4 The i.MX 8ULP/9x secure boot flow
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The secure boot sequence involves multiple cores booting up at same time and
+EdgeLock secure enclave ensure authentication of any boot software being loaded.
+
+The diagram below illustrate the secure boot flow overview for dual boot
+scenario in i.MX 8ULP:
+
+.. code-block:: text
+
+ Cortex-M(CM) │ EdgeLock Secure │ Cortex-A(CA) │ uPower(uP)
+ │ Enclave(ELE) │ │
+ │ │ │ │ │ │ │
+ ┌┬─────┴─────┬┐ │ ┌┬─────┴─────┬┐ │ │ │ ┌┬─────┴─────┬┐
+ ││ INIT ││ │ ││ INIT ││ │ │ │ ││ INIT ││
+ └┴─────┬─────┴┘ │ └┴─────┬─────┴┘ │ │ │ └┴─────┬─────┴┘
+ │ │ │ │ ┌┬─────┴─────┬┐ │ │
+ ┌┬─────┴─────┬┐ │ │ │ ││Load CA FW ││ │ ┌──────┐ │
+ ││Load uP FW ││ │ │ │ └┴─────┬─────┴┘ ││ │ │
+ └┴─────┬─────┴┘ │ │ │ │ ││ ┌┬──v──┴─────┬┐
+ │ │ ┌┬─────┴─────┬┐ │┌────────┤ ││ ││Load &Start││
+ ├─────────────>├│Auth uP FW ││ ││ │ ││ ││ uP FW ││
+ │ │ └┴─────┬─────┴┘ ││ │ ││ └┴───────────┴┘
+ ┌┬─────┴─────┬┐ │ │ ││ │ ││
+ ││Load CM FW││ │ ├────────────────────┼────────┘│
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ │ │
+ ├─────────────>├│Auth CM FW ││ ││ ┌┬─────┴─────┬┐ │
+ │ │ └┴─────┬─────┴┘ ││ ││Start CA FW││ │
+ ┌┬─────┴─────┬┐ │ │ ││ └┴─────┬─────┴┘ │
+ ││Load ELE FW││ │ │ ││ │ │
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ │ │
+ ├─────────────>├│Auth ELE FW││ ││ │ │
+ │ │ └┴─────┬─────┴┘ ││ ┌┬─────┴─────┬┐ │
+ ┌┬─────┴─────┬┐ │ │ ││ ││ Load SPL ││ │
+ ││Start CM FW││ │ │ ││ └┴─────┬─────┴┘ │
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ ┌────┤ │
+ │ │ ││Auth CA FW │┤<───┘ │ │ │
+ │ │ └┴─────┬─────┴┘ │ │ │ │
+ │ │ │ │ │ │ │
+ │ │ ┌┬─────┴─────┬┐ │ │ │ │
+ │ │ ││ Auth SPL │┤<───────┘ │ │
+ │ │ └┴─────┬─────┴┘ │ │ │
+ │ │ ├─────────────────┐ │ │
+ │ │ │ │ │ │ │
+ │ │ │ │ ┌┬──v──v─────┬┐ │
+ │ │ │ │ ││ Run SPL ││ │
+ │ │ │ │ └┴───────────┴┘ │
+
+The diagram below illustrate the secure boot flow overview for single boot
+scenario in i.MX 9x:
+
+.. code-block:: text
+
+ Cortex-A(CA) │ EdgeLock Secure │ Cortex-M(CM)
+ │ Enclave(ELE) │
+ │ │ │ │ │
+ ┌┬─────┴─────┬┐ │ ┌┬─────┴─────┬┐ │ │
+ ││ INIT ││ │ ││ INIT ││ │ │
+ └┴─────┬─────┴┘ │ └┴─────┬─────┴┘ │ │
+ │ │ │ │ ┌┬─────┴─────┬┐
+ │ │ │ │┌>││ INIT ││
+ │ │ │ ││ └┴─────┬─────┴┘
+ ┌┬─────┴─────┬┐ │ │ ││ |
+ ││Load ELE FW││─────────────>│ ││ │
+ └┴─────┬─────┴┘ | | |│ │
+ │ │ ┌┬─────┴─────┬┐ ││ ┌┬─────┴─────┬┐
+ │ │ ├│Auth ELE FW││ ││ ││Start CM FW││
+ │ │ └┴─────┬─────┴┘ ││ └┴─────┬─────┴┘
+ | | | |│ |
+ ┌┬─────┴─────┬┐ │ │ ││ │
+ ││Load CM FW││ │ | ││ │
+ └┴─────┬─────┴┘ │ │ ││ │
+ │ │ ┌┬─────┴─────┬┐ ││ │
+ ├─────────────>├│Auth CM FW ││ ││ │
+ │ │ └┴─────┬─────┴┘ ││ │
+ | │ │ ││ │
+ │ │ |───────────┘ │
+ ┌┬─────┴─────┬┐ │ │ │ │
+ ││Load CA FW││ │ │ │ │
+ └┴─────┬─────┴┘ │ │ │ │
+ │ │ ┌┬─────┴─────┬┐ │ │
+ ├─────────────>├│Auth CA FW││ │ │
+ │ │ └┴─────┬─────┴┘ │ │
+ ┌┬─────┴─────┬┐ │ │ │ │
+ ││Start CA FW││ │ | │ │
+ └┴─────┬─────┴┘ │ │ │ │
+ | │ │ │ │
+ | │ │ │ │
+ | │ │ │ │
+
+More details on the boot flow can be found in respective Security Reference
+Manual (SRM).
+
+2. Generating a PKI tree
+------------------------
+
+The first step is to generate the private keys and public keys certificates.
+The AHAB architecture is based on a Public Key Infrastructure (PKI) tree.
+
+The Code Signing Tools package contains an OpenSSL based key generation script
+under keys/ directory. The ahab_pki_tree.sh script generates a PKI tree
+containing 4 Super Root Keys (SRK), possible to also include a subordinate
+SGK key.
+
+The AHAB supports both RSA and ECC keys, a new PKI tree can be generated by
+following the example below:
+
+- Generating a P384 ECC PKI tree on CST (starting from v3.1.0):
+
+ .. code-block:: console
+
+ $ ./ahab_pki_tree.sh
+ ...
+ Do you want to use an existing CA key (y/n)?: n
+ Do you want to use Elliptic Curve Cryptography (y/n)?: y
+ Enter length for elliptic curve to be used for PKI tree:
+ Possible values p256, p384, p521: p384
+ Enter the digest algorithm to use: sha384
+ Enter PKI tree duration (years): 5
+ Do you want the SRK certificates to have the CA flag set? (y/n)?: n
+
+The diagram below illustrate the PKI tree generated:
+
+.. code-block:: text
+
+ ┌─────────┐
+ │ CA │
+ └────┬────┘
+ │
+ │
+ ┌───────────────┬────────┴────────┬───────────────┐
+ │ │ │ │
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SRK1 │ │ SRK2 │ │ SRK3 │ │ SRK4 │
+ └────────┘ └────────┘ └────────┘ └────────┘
+
+2.1 Generating a PKI tree including a subordinate SGK key
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ahab_pki_tree.sh script is also able to generate a PKI tree containing a
+subordinate key of the SRK, this key can be used to verify the signature
+included in the final signed image.
+
+Users should set the CA flag when generating the SRK certificates.
+
+- Generating a P384 ECC PKI tree with a subordinate SGK key on CST (starting
+ from v3.1.0):
+
+ .. code-block:: console
+
+ $ ./ahab_pki_tree.sh
+ ...
+ Do you want to use an existing CA key (y/n)?: n
+ Do you want to use Elliptic Curve Cryptography (y/n)?: y
+ Enter length for elliptic curve to be used for PKI tree:
+ Possible values p256, p384, p521: p384
+ Enter the digest algorithm to use: sha384
+ Enter PKI tree duration (years): 5
+ Do you want the SRK certificates to have the CA flag set? (y/n)?: y
+
+The diagram below illustrate the PKI tree generated:
+
+.. code-block:: text
+
+ ┌─────────┐
+ │ CA │
+ └────┬────┘
+ │
+ │
+ ┌───────────────┬────────┴────────┬───────────────┐
+ │ │ │ │
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SRK1 │ │ SRK2 │ │ SRK3 │ │ SRK4 │
+ └────┬───┘ └───┬────┘ └────┬───┘ └───┬────┘
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SGK1 │ │ SGK2 │ │ SGK3 │ │ SGK4 │
+ └────────┘ └────────┘ └────────┘ └────────┘
+
+2.2 Generating a SRK Table and SRK Hash
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The next step is to generated the SRK Table and its respective SRK Table Hash
+from the SRK public key certificates created in one of the steps above.
+
+In the AHAB architecture, the SRK Table is included in the signed image and the
+SRK Hash is programmed in the SoC SRK_HASH[511:0]/SRK_HASH[255:0] fuses.
+
+On the target device during the authentication process the AHAB code verify the
+SRK Table against the SoC SRK_HASH fuses, in case the verification is successful
+the root of trust is established and the AHAB code can progress with the image
+authentication.
+
+The srktool can be used to generate the SRK Table and its respective SRK
+Table Hash.
+
+- Generating SRK Table and SRK Hash in Linux 64-bit machines:
+ - In i.MX 8/8x family, the expected SRK HASH is of 512 bit.
+
+ .. code-block:: console
+
+ $ cd ../crts/
+ $ ../linux64/bin/srktool -a -s sha384 -t SRK_1_2_3_4_table.bin \
+ -e SRK_1_2_3_4_fuse.bin -f 1 -c \
+ SRK1_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK2_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK3_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK4_sha384_secp384r1_v3_usr_crt.pem
+
+ - In i.MX 8ULP/9x, the expected SRK HASH is of 256 bit.
+
+ .. code-block:: console
+
+ $ cd ../crts/
+ $ ../linux64/bin/srktool -a -d sha256 -s sha384 -t SRK_1_2_3_4_table.bin \
+ -e SRK_1_2_3_4_fuse.bin -f 1 -c \
+ SRK1_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK2_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK3_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK4_sha384_secp384r1_v3_usr_crt.pem
+
+ Regenerate the SRK HASH (SRK_1_2_3_4_fuse.bin) by using SHA256 with
+ SRK_1_2_3_4_table.bin:
+
+ .. code-block:: console
+
+ $ openssl dgst -binary -sha256 SRK_1_2_3_4_table.bin
+
+- Optionally users can check if the sha512sum/sha256sum of SRK_1_2_3_4_table
+ matches with the SRK_1_2_3_4_fuse.bin:
+
+ .. code-block:: console
+
+ $ od -t x4 --endian=big SRK_1_2_3_4_fuse.bin
+ 0000000 01b04697 0253376b 2066fe56 aaef9a91
+ 0000020 e62e09d8 14fb7e36 d5b38d05 0982edab
+ 0000040 7ada6576 2f6b4f59 1fd9347e 46e7305d
+ 0000060 46e34bf0 89780bd1 c809e714 a17e2f4e
+
+ $ sha512sum SRK_1_2_3_4_table.bin
+ 01b046970253376b2066fe56aaef9a91\
+ e62e09d814fb7e36d5b38d050982edab\
+ 7ada65762f6b4f591fd9347e46e7305d\
+ 46e34bf089780bd1c809e714a17e2f4e\
+ SRK_1_2_3_4_table.bin
+
+.. note::
+
+ The commands above cannot be used as reference to program the SoC
+ SRK_HASH fuses.
+
+3 Known limitations
+-------------------
+
+- Due to a limitation in i.MX8QXP B0 silicon it's not possible to use RSA
+ 4096-bit SRK keys with an additional subordinate SGK key.
diff --git a/doc/imx/ahab/introduction_ahab.txt b/doc/imx/ahab/introduction_ahab.txt
new file mode 100644
index 00000000000..4a5b6f795c4
--- /dev/null
+++ b/doc/imx/ahab/introduction_ahab.txt
@@ -0,0 +1,445 @@
+ +=======================================================+
+ + i.MX Secure and Encrypted Boot using AHAB +
+ +=======================================================+
+
+1. Introduction
+----------------
+
+The i.MX 8/8x/8ULP/9x family of applications processors introduce a new secure
+boot concept. Due to the multi-core architecture, the Security Controller (SECO)
+and System Control Unit (SCU) in i.MX 8/8x, and Edgelock secure enclave (ELE)
+in i.MX 8ULP/9x are heavily involved in the secure boot process.
+
+Step-by-step guides are available under doc/imx/ahab/guides/ directory,
+users familiar with AHAB architecture and CST PKI tree generation should
+refer to these documents instead.
+
+1.1 The AHAB Secure Boot Architecture
+--------------------------------------
+
+The Advanced High Assurance Boot (AHAB) feature relies in digital signatures to
+prevent unauthorized software execution during the device boot sequence. In
+case a malware takes control of the boot sequence, sensitive data, services and
+network can be impacted.
+
+The AHAB authentication is based on public key cryptography in which image
+data is signed offline using one or more private keys. The resulting signed
+image data is then verified on the i.MX processor using the corresponding
+public keys. The public keys are included in the final binary and the SRK
+Hash is programmed in the SoC fuses for establishing the root of trust.
+
+In i.MX8 and i.MX8x families the SCU is responsible to interface with the boot
+media, managing the process of loading the firmware and software images in
+different partitions of the SoC. The SECO is responsible to authenticate the
+images and authorize the execution of them.
+
+1.1.1 [i.MX 8/8x] The System Control Unit (SCU)
+------------------------------------
+
+The System Control Unit SCU is a subsystem equipped with a programmable M4
+core, which is responsible to handle the resource allocation, power, clocking,
+IO configuration and muxing.
+
+The SCU is also responsible to interface between the rest of the system. In the
+secure boot flow the SCU interfaces with the Security Controller (SECO),
+requesting the image authentication.
+
+The System Control Unit FW (SCFW) is responsible to control all the
+functionalities of the SCU. This firmware is distributed in a porting kit form.
+Instructions to download the SCFW Porting Kit are available in the Linux BSP
+Release Notes.
+
+Details about SCU can be found in the processors Reference Manual (RM).
+
+1.1.2 [i.MX 8/8x] The Security Controller (SECO)
+-------------------------------------
+
+The SECO is a M0+ core dedicated to handle the SoC security subsystem. The
+controller communicates with SCU domain through a dedicate message unit (MU).
+
+The SECO has a dedicate ROM which is responsible to initialize low level
+security features and to authenticate the SECO firmware previously loaded by
+the SCU ROM.
+
+The SECO firmware provides security services at run-time to different domains
+of the SoC, one of these being the capability of authenticate images.
+
+The SECO firmware is signed and distributed by NXP and is always authenticated
+in OEM open and closed configuration, instructions to download the SECO FW are
+available in the Linux BSP Release Notes.
+
+Details about SECO can be found in the processors Security Reference Manual
+(SRM).
+
+1.1.3 [i.MX 8ULP/9x] The Edgelock secure enclave
+-------------------------------------
+
+EdgeLock™ Secure Enclave is the security subsystem based on a dedicated core
+(RISC-V) to manage security tasks with a tight control on security resources
+along with other enhancements.
+
+The secure enclave has a dedicate ROM which is responsible to initialize low
+level security features and to authenticate the secure enclave firmware
+previously loaded by the boot management core.
+
+The secure enclave firmware provides security services at run-time to different
+ domains of the SoC, one of these being the capability of authenticate images.
+
+The secure enclave firmware is signed and distributed by NXP and is always
+authenticated in OEM open and closed configuration, instructions to download
+this FW are available in the Linux BSP Release Notes.
+
+Details about Edgelock secure enclave can be found in the processors Security
+Reference Manual (SRM).
+
+NOTE: The terms Sentinel, S400, and EdgeLock secure enclave (ELE), and ELE
+are used interchangeably throughout the document.
+
+1.2 The image container
+------------------------
+
+Due to the new architecture, multiple firmwares and software are required to
+boot AHAB supporting devices. In order to store all the images in a single
+binary the container image structure is used.
+
+At least two containers are needed for the boot process, the first container
+must include only the Security Subsystem FW (SECO/ELE FW provided by NXP).
+Additional containers can contain one or multiple images, depending on the
+users specific application.
+
+The final binary is generated by the imx-mkimage tool.
+
+1.3 The i.MX8/8x secure boot flow
+----------------------------------
+
+As mentioned in the introduction, due to the multiple cores architecture the
+i.MX8 boot sequence involves SCU ROM, SCFW, SECO ROM, and SECO FW.
+
+The diagram below illustrate the secure boot flow overview:
+
+System Controller │ Security Controller │ Cortex-M │ Cortex-A
+ (SCU) │ (SECO) │ │
+ │ │ │
+ ╔═════════════╗ │ ╔═════════════╗ ┌───────────┐ ┌─────────┐
+ ║ SCU INIT ║ │ ║ SECO INIT ║ │ │ │ │ │ │
+ ╚══════╤══════╝ │ ╚══════╤══════╝ │ │ v │ │ v
+ │ │ │ │ │ ┌──────────┐ │ │ ┌────────────┐
+ ╔══════╧══════╗ │ │ │ │ │ Start M4 │ │ │ │ Start AP │
+ ║Load SECO FW ║ │ │ │ │ │ IMG │ │ │ │ IMG │
+ ╚══════╤══════╝ │ ╔══════╧══════╗ │ │ └──────────┘ │ │ └─────┬──────┘
+ ├──────────────>║Auth SECO FW ║ │ │ │ │ │
+ ╔══════╧══════╗ │ ╚══════╤══════╝ │ │ ┌────────────┘ │ │
+ ║ Load SCU FW ║ │ │ │ │ │ │ │
+ ║ and DCD ║ │ │ │ │ │ │ ┌─────┴──────┐
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ Load │
+ ├──────────────>│ Auth SCU FW │ │ │ │ │ │ Add AP IMG │
+ │ │ │ and DCD │ │ │ │ │ └─────┬──────┘
+ ╔══════╧══════╗ │ └──────┬──────┘ │ │ │ │ │
+ ║ Run DCD ║<──────────────┤ │ │ │ │ │
+ ╚══════╤══════╝ │ │ │ │ │ ┌───────────────┤
+ │ │ │ │ │ │ │ │ │
+ ╔══════╧══════╗ │ │ │ │ │ │ │ │
+ ║ Load M4 IMG ║ │ │ │ │ │ │ │ │
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ │
+ ├──────────────>│ Auth M4 IMG │ │ │ │ │ │ │
+ ╔══════╧══════╗ │ └──────┬──────┘ │ │ │ │ │ ┌─────┴──────┐
+ ║ Load AP IMG ║ │ │ │ │ │ │ │ │ Run │
+ ╚══════╤══════╝ │ ┌──────┴──────┐ │ │ │ │ │ │ Add AP IMG │
+ ├──────────────>│ Auth AP IMG │ │ │ │ │ │ └────────────┘
+ ╔══════╧══════╗ │ └─────────────┘ │ │ │ │ │
+ ║Start SCU FW ║ │ ┌──────────────────┘ │ │ │ │
+ ╚══════╤══════╝ │ │ │ │ │ │
+ │ │ │ ┌─────────────────────┘ │ │
+ ┌──────┴──────┐ │ │ │ │ │ │
+ │ Start M4 ├──────┘ │ ┌──────────────────────┘ │
+ └──────┬──────┘ │ │ │ │ │
+ │ │ │ │ │ │
+ ┌──────┴──────┐ │ │ │ │ │
+ │ Start AP ├──────────┘ │ │ │
+ └─────────────┘ │ │ │ │
+ ┌───────────────────────┘ │ │
+ │ │ │ │
+ v │ │ │
+ ┌─────────────┐ │ ┌─────────────┐ │ │
+ │Request SECO ├───────>│ Auth AP IMG │ │ │
+ └─────────────┘ │ └─────────────┘ │ │
+ │ │ │
+
+
+Notes:
+All boxes enclosed by double dash (═) are performed at SCU/SECO ROM level.
+
+The sequence below explains the i.MX8 and i.MX8x boot flow:
+
+1 - At reset, the SCU ROM and SECO ROM both start execution.
+2 - The SCU ROM reads the boot configuration and loads the SECO FW (First
+ container) from the boot media to the SECO TCM.
+3 - A message is sent by the SCU ROM via MU requesting the SECO ROM to
+ authenticate the SECO FW which is signed using NXP key.
+4 - The SCU ROM loads the second container from the boot media, this container
+ must contain at least the SCFW which is signed using the OEM keys.
+5 - The SCU ROM loads the SCFW to the SCU TCM, a message is sent via MU
+ requesting the SECO FW to authenticate the SCFW and DCD table.
+6 - The SCU ROM configures the DDR and loads the M4 and AP images included in
+ the second container to their respective load addresses.
+7 - The SCU ROM request the SECO FW to authenticate the M4 image.
+8 - The SCU ROM request the SECO FW to authenticate the AP image. This image
+ is the initial AP core software, depending in the U-Boot target it can
+ be the U-Boot and ATF or only SPL.
+9 - The SCFW is initialized and starts the ARM Cortex-M and Cortex-A cores.
+10 - From this point additional containers can be loaded by Cortex-M and
+ Cortex-A cores and authenticated by SECO, the AP SW must interface with
+ SCU by calling the sc_misc_seco_authenticate() API function. In current
+ U-Boot implementation the additional image can be the Linux Kernel binary
+ or the U-Boot proper and ATF. Details about current U-Boot implementation
+ can be found in AHAB guides included in doc/imx/ahab/guides/ directory.
+
+1.4 The i.MX 8ULP/9x secure boot flow
+----------------------------------
+
+The secure boot sequence involves multiple cores booting up at same time and
+Edgelock secure enclave ensure authentication of any boot software being loaded.
+
+The diagram below illustrate the secure boot flow overview for dual boot
+scenario in i.MX 8ULP:
+
+
+ Cortex-M(CM) │ Edgelock Secure │ Cortex-A(CA) │ uPower(uP)
+ │ Enclave(ELE) │ │
+ │ │ │ │ │ │ │
+ ┌┬─────┴─────┬┐ │ ┌┬─────┴─────┬┐ │ │ │ ┌┬─────┴─────┬┐
+ ││ INIT ││ │ ││ INIT ││ │ │ │ ││ INIT ││
+ └┴─────┬─────┴┘ │ └┴─────┬─────┴┘ │ │ │ └┴─────┬─────┴┘
+ │ │ │ │ ┌┬─────┴─────┬┐ │ │
+ ┌┬─────┴─────┬┐ │ │ │ ││Load CA FW ││ ┌──────┐ │
+ ││Load uP FW ││ │ │ │ └┴─────┬─────┴┘ ││ │ │
+ └┴─────┬─────┴┘ │ │ │ │ ││ ┌┬──v──┴─────┬┐
+ │ │ ┌┬─────┴─────┬┐ │┌────────┤ ││ ││Load &Start││
+ ├─────────────>├│Auth uP FW ││ ││ │ ││ ││ uP FW ││
+ │ │ └┴─────┬─────┴┘ ││ │ ││ └┴───────────┴┘
+ ┌┬─────┴─────┬┐ │ │ ││ │ ││
+ ││Load CM FW││ │ ├────────────────────┼────────┘│
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ │ │
+ ├─────────────>├│Auth CM FW ││ ││ ┌┬─────┴─────┬┐ │
+ │ │ └┴─────┬─────┴┘ ││ ││Start CA FW││ │
+ ┌┬─────┴─────┬┐ │ │ ││ └┴─────┬─────┴┘ │
+ ││Load ELE FW││ │ │ ││ │ │
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ │ │
+ ├─────────────>├│Auth ELE FW││ ││ │ │
+ │ │ └┴─────┬─────┴┘ ││ ┌┬─────┴─────┬┐ │
+ ┌┬─────┴─────┬┐ │ │ ││ ││ Load SPL ││ │
+ ││Start CM FW││ │ │ ││ └┴─────┬─────┴┘ │
+ └┴─────┬─────┴┘ │ │ ││ │ │
+ │ │ ┌┬─────┴─────┬┐ ││ ┌────┤ │
+ │ │ ││Auth CA FW │┤<───┘ │ │ │
+ │ │ └┴─────┬─────┴┘ │ │ │ │
+ │ │ │ │ │ │ │
+ │ │ ┌┬─────┴─────┬┐ │ │ │ │
+ │ │ ││ Auth SPL │┤<───────┘ │ │
+ │ │ └┴─────┬─────┴┘ │ │ │
+ │ │ ├─────────────────┐ │ │
+ │ │ │ │ │ │ │
+ │ │ │ │ ┌┬──v──v─────┬┐ │
+ │ │ │ │ ││ Run SPL ││ │
+ │ │ │ │ └┴───────────┴┘ │
+
+
+The diagram below illustrate the secure boot flow overview for single boot
+scenario in i.MX 9x:
+
+
+ Cortex-A(CA) │ Edgelock Secure │ Cortex-M(CM)
+ │ Enclave(ELE) │
+ │ │ │ │ │
+ ┌┬─────┴─────┬┐ │ ┌┬─────┴─────┬┐ │ │
+ ││ INIT ││ │ ││ INIT ││ │ │
+ └┴─────┬─────┴┘ │ └┴─────┬─────┴┘ │ │
+ │ │ │ │ ┌┬─────┴─────┬┐
+ │ │ │ │┌>││ INIT ││
+ │ │ │ ││ └┴─────┬─────┴┘
+ ┌┬─────┴─────┬┐ │ │ ││ |
+ ││Load ELE FW││─────────────>│ ││ │
+ └┴─────┬─────┴┘ | | |│ |
+ │ │ ┌┬─────┴─────┬┐ ││ ┌┬─────┴─────┬┐
+ │ │ ├│Auth ELE FW││ ││ ││Start CM FW││
+ │ │ └┴─────┬─────┴┘ ││ └┴─────┬─────┴┘
+ | | | |│ |
+ ┌┬─────┴─────┬┐ │ │ ││ │
+ ││Load CM FW││ │ | ││ │
+ └┴─────┬─────┴┘ │ │ ││ │
+ │ │ ┌┬─────┴─────┬┐ ││ │
+ ├─────────────>├│Auth CM FW ││ ││ │
+ │ │ └┴─────┬─────┴┘ ││ │
+ | │ │ ││ │
+ │ │ |───────────┘ │
+ ┌┬─────┴─────┬┐ │ │ │ │
+ ││Load CA FW││ │ │ │ │
+ └┴─────┬─────┴┘ │ │ │ │
+ │ │ ┌┬─────┴─────┬┐ │ │
+ ├─────────────>├│Auth CA FW││ │ │
+ │ │ └┴─────┬─────┴┘ │ │
+ ┌┬─────┴─────┬┐ │ │ │ │
+ ││Start CA FW││ │ | │ │
+ └┴─────┬─────┴┘ │ │ │ │
+ | │ │ │ │
+ | │ │ │ │
+ | │ │ │ │
+
+More details on the boot flow can be found in respective Security Reference
+Manual (SRM).
+
+
+2. Generating a PKI tree
+-------------------------
+
+The first step is to generate the private keys and public keys certificates.
+The AHAB architecture is based on a Public Key Infrastructure (PKI) tree.
+
+The Code Signing Tools package contains an OpenSSL based key generation script
+under keys/ directory. The ahab_pki_tree.sh script generates a PKI tree
+containing 4 Super Root Keys (SRK), possible to also include a subordinate
+SGK key.
+
+The AHAB supports both RSA and ECC keys, a new PKI tree can be generated by
+following the example below:
+
+- Generating a P384 ECC PKI tree on CST (starting from v3.1.0):
+
+ $ ./ahab_pki_tree.sh
+ ...
+ Do you want to use an existing CA key (y/n)?: n
+ Do you want to use Elliptic Curve Cryptography (y/n)?: y
+ Enter length for elliptic curve to be used for PKI tree:
+ Possible values p256, p384, p521: p384
+ Enter the digest algorithm to use: sha384
+ Enter PKI tree duration (years): 5
+ Do you want the SRK certificates to have the CA flag set? (y/n)?: n
+
+The diagram below illustrate the PKI tree generated:
+
+ ┌─────────┐
+ │ CA │
+ └────┬────┘
+ │
+ │
+ ┌───────────────┬────────┴────────┬───────────────┐
+ │ │ │ │
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SRK1 │ │ SRK2 │ │ SRK3 │ │ SRK4 │
+ └────────┘ └────────┘ └────────┘ └────────┘
+
+2.1 Generating a PKI tree including a subordinate SGK key
+----------------------------------------------------------
+
+The ahab_pki_tree.sh script is also able to generate a PKI tree containing a
+subordinate key of the SRK, this key can be used to verify the signature
+included in the final signed image.
+
+Users should set the CA flag when generating the SRK certificates.
+
+- Generating a P384 ECC PKI tree with a subordinate SGK key on CST (starting
+from v3.1.0):
+
+ $ ./ahab_pki_tree.sh
+ ...
+ Do you want to use an existing CA key (y/n)?: n
+ Do you want to use Elliptic Curve Cryptography (y/n)?: y
+ Enter length for elliptic curve to be used for PKI tree:
+ Possible values p256, p384, p521: p384
+ Enter the digest algorithm to use: sha384
+ Enter PKI tree duration (years): 5
+ Do you want the SRK certificates to have the CA flag set? (y/n)?: y
+
+The diagram below illustrate the PKI tree generated:
+
+ ┌─────────┐
+ │ CA │
+ └────┬────┘
+ │
+ │
+ ┌───────────────┬────────┴────────┬───────────────┐
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SRK1 │ │ SRK2 │ │ SRK3 │ │ SRK4 │
+ └────┬───┘ └───┬────┘ └────┬───┘ └───┬────┘
+ │ │ │ │
+ v v v v
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+ │ SGK1 │ │ SGK2 │ │ SGK3 │ │ SGK4 │
+ └────────┘ └────────┘ └────────┘ └────────┘
+
+2.2 Generating a SRK Table and SRK Hash
+----------------------------------------
+
+The next step is to generated the SRK Table and its respective SRK Table Hash
+from the SRK public key certificates created in one of the steps above.
+
+In the AHAB architecture, the SRK Table is included in the signed image and the
+SRK Hash is programmed in the SoC SRK_HASH[511:0]/SRK_HASH[255:0] fuses.
+
+On the target device during the authentication process the AHAB code verify the
+SRK Table against the SoC SRK_HASH fuses, in case the verification is successful
+the root of trust is established and the AHAB code can progress with the image
+authentication.
+
+The srktool can be used to generate the SRK Table and its respective SRK
+Table Hash.
+
+- Generating SRK Table and SRK Hash in Linux 64-bit machines:
+ - In i.MX 8/8x family, the expected SRK HASH is of 512 bit.
+ $ cd ../crts/
+ $ ../linux64/bin/srktool -a -s sha384 -t SRK_1_2_3_4_table.bin \
+ -e SRK_1_2_3_4_fuse.bin -f 1 -c \
+ SRK1_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK2_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK3_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK4_sha384_secp384r1_v3_usr_crt.pem
+
+ - In i.MX 8ULP/9x, the expected SRK HASH is of 256 bit.
+ $ cd ../crts/
+ $ ../linux64/bin/srktool -a -d sha256 -s sha384 -t SRK_1_2_3_4_table.bin \
+ -e SRK_1_2_3_4_fuse.bin -f 1 -c \
+ SRK1_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK2_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK3_sha384_secp384r1_v3_usr_crt.pem,\
+ SRK4_sha384_secp384r1_v3_usr_crt.pem
+
+ Regenerate the SRK HASH (SRK_1_2_3_4_fuse.bin) by using SHA256 with
+ SRK_1_2_3_4_table.bin.
+ $ openssl dgst -binary -sha256 SRK_1_2_3_4_table.bin
+
+
+
+- Optionally users can check if the sha512sum/sha256sum of SRK_1_2_3_4_table
+matches with the SRK_1_2_3_4_fuse.bin:
+
+ $ od -t x4 --endian=big SRK_1_2_3_4_fuse.bin
+ 0000000 01b04697 0253376b 2066fe56 aaef9a91
+ 0000020 e62e09d8 14fb7e36 d5b38d05 0982edab
+ 0000040 7ada6576 2f6b4f59 1fd9347e 46e7305d
+ 0000060 46e34bf0 89780bd1 c809e714 a17e2f4e
+
+ $ sha512sum SRK_1_2_3_4_table.bin
+ 01b046970253376b2066fe56aaef9a91\
+ e62e09d814fb7e36d5b38d050982edab\
+ 7ada65762f6b4f591fd9347e46e7305d\
+ 46e34bf089780bd1c809e714a17e2f4e\
+ SRK_1_2_3_4_table.bin
+
+NOTE: The commands above cannot be used as reference to program the SoC
+ SRK_HASH fuses.
+
+The SRK_1_2_3_4_table.bin and SRK_1_2_3_4_fuse.bin files can be used in further
+steps as explained in AHAB guides available under doc/imx/ahab/guides/
+directory.
+
+3 Known limitations
+----------------------------------------
+
+- Due to a limitation in i.MX8QXP B0 silicon it's not possible to use RSA
+4096-bit SRK keys with an additional subordinate SGK key.
diff --git a/doc/imx/index.rst b/doc/imx/index.rst
new file mode 100644
index 00000000000..cc5f427de92
--- /dev/null
+++ b/doc/imx/index.rst
@@ -0,0 +1,13 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+i.MX AHAB secure boot
+======================
+
+This section provides documentation for the NXP i.MX AHAB (Advanced
+High Assurance Boot) secure boot mechanisms, covering the AHAB
+architecture introduction and the i.MX93 secure boot guide.
+
+.. toctree::
+ :maxdepth: 2
+
+ ahab/introduction_ahab
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 6/7] doc: imx: ahab: add i.MX93 secure boot guide
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
` (4 preceding siblings ...)
2026-09-02 13:41 ` [PATCH v2 5/7] doc: imx: ahab: add AHAB introduction Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 7/7] binman: test: add code coverage for nxp_imx93cst etype Jérémie Dautheribes (Schneider Electric)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Add a step-by-step guide describing how to securely boot an i.MX93
image using AHAB.
This guide is largely based on the following documents:
- doc/imx/ahab/guides/mx8ulp_9x_secure_boot.txt, from uboot-imx
(lf_v2026.04), originally written by Utkarsh Gupta
- doc/imx/habv4/guides/mx8m_spl_secure_boot.txt, from this tree,
originally written by Marek Vasut
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
doc/imx/ahab/guides/mx93_secure_boot.rst | 294 +++++++++++++++++++++++++++++++
doc/imx/ahab/guides/mx93_secure_boot.txt | 269 ++++++++++++++++++++++++++++
doc/imx/ahab/introduction_ahab.rst | 3 +-
doc/imx/index.rst | 1 +
4 files changed, 566 insertions(+), 1 deletion(-)
diff --git a/doc/imx/ahab/guides/mx93_secure_boot.rst b/doc/imx/ahab/guides/mx93_secure_boot.rst
new file mode 100644
index 00000000000..2a966ffed1b
--- /dev/null
+++ b/doc/imx/ahab/guides/mx93_secure_boot.rst
@@ -0,0 +1,294 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+i.MX93 Secure boot guide using AHAB
+===================================
+
+This document provides a step-by-step guide on how to securely boot an
+i.MX93 boot image. It is assumed that the reader is familiar with basic
+AHAB concepts and with the PKI tree generation. Details about AHAB can be
+found in the :doc:`AHAB introduction <../introduction_ahab>` document and
+in the processor Security Reference Manual (SRM). The i.MX93 signing
+procedure is integrated in the U-Boot build thanks to binman.
+
+1. Preparing the environment to build a secure boot image
+---------------------------------------------------------
+
+Secure boot image preparation requires the U-Boot build system to build
+the image and the Code Signing Tool (CST) to sign it.
+
+The following files are needed to prepare the boot image:
+
+ - EdgeLock secure enclave Firmware (ELE) (Optional).
+ - DDR PHY initialization firmware.
+ - U-Boot proper and SPL.
+ - ARM Trusted Firmware (ATF).
+ - OPTEE (Optional)
+
+The ELE FW is distributed by NXP and is already signed using NXP keys.
+In the following sections, <work> designates the repository where all
+parts have been downloaded and built.
+
+2. Preparing U-Boot to support AHAB secure boot features
+--------------------------------------------------------
+
+The U-Boot/SPL provides extra AHAB supported functionalities that include
+extension of Root of Trust, checking any events(issues) after image
+authentication, chip lifecycle status, securing the target etc.
+
+The support is enabled by adding CONFIG_AHAB_BOOT to the defconfig file
+used by your target:
+
+ - Defconfig:
+ CONFIG_AHAB_BOOT=y
+ - Kconfig:
+ ARM architecture -> Support i.MX9 AHAB features
+
+Enabling this feature allows the SPL and U-Boot images to extend the Root
+of Trust by using the AHAB API call via ELE FW. It also enables binman to
+automatically sign the SPL and U-Boot containers while building
+flash.bin, as described in the next sections.
+
+3. i.MX93 AHAB image layout
+---------------------------
+
+The i.MX93 flash.bin image is built by binman and is composed of up to
+three containers. The ELE FW container is optional and is provided by NXP,
+it is appended at the beginning of the image when the file
+mx93a1-ahab-container.img is present in the build directory. The SPL and
+U-Boot containers are built by the nxp-imx9image etype and signed by the
+nxp-imx93cst etype.
+
+.. code-block:: text
+
+ *start ----> +---------------------------+ ---------
+ | 1st Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | ELE ROM/FW Level
+ | Padding | |
+ +---------------------------+ |
+ | ELE FW | v
+ *start + 0x400 ---> +---------------------------+ ---------
+ | 2nd Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | ELE ROM/FW Level
+ | Padding | |
+ +---------------------------+ |
+ | SPL | v
+ +---------------------------+ ---------
+ | 3rd Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | SPL Level
+ | Padding | |
+ +---------------------------+ |
+ | ARM Trusted FW (ATF) | |
+ +---------------------------+ |
+ | U-Boot proper | |
+ +---------------------------+ |
+ | OPTEE (optional) | v
+ +---------------------------+ ---------
+
+The first container includes the ELE FW which is signed using NXP keys,
+this container is authenticated by ELE ROM.
+
+The second container includes the SPL which is signed using OEM keys,
+this container is authenticated at ELE FW level.
+
+The third container includes the U-Boot proper and the ATF. The SPL is in
+charge to load this container and also to interface with ELE FW to
+authenticate the additional container.
+
+The signing procedure is slightly different when compared with HABv4
+series. On AHAB the signature is directly included in the container, the
+CST is responsible to sign and handle the "Signature Block":
+
+.. code-block:: text
+
+ +----------------------------+ ---------
+ | | ^
+ | | |
+ | Container header | |
+ | | |
+ | | |
+ +---+------------------------+ |
+ | S | Signature block header | | Signed
+ | i +------------------------+ |
+ | g | | |
+ | n | | |
+ | a | SRK table | |
+ | t | | |
+ | u | | v
+ | r +------------------------+ ---------
+ | e | Signature |
+ | +------------------------+
+ | B | |
+ | l | SGK Key |
+ | o | Certificate (optional) |
+ | c | |
+ | k | |
+ +---+------------------------+
+
+The certificate block is divided into:
+
+.. code-block:: text
+
+ +---------------+ ^
+ | Public key | | Signed
+ | Permission | |
+ +---------------+ v
+ | Signature |
+ +---------------+
+
+The first block (public key permission) verifies the Signature block
+preceding (between SRK table and Certificate blocks), while the second
+block (signature) is verified by the SRK table block.
+
+In case not using the subordinate key, the container signature is
+verified against the SRK keys directly.
+
+4. Signing the images
+---------------------
+
+Internally, Command Sequence Files (CSF) are used. The CSF files contain
+all the commands that the AHAB executes during the secure boot. These
+commands instruct the AHAB code on which memory areas of the image to
+authenticate, which keys to install and use, and so on. The CSF is generated
+using the CST Code Signing Tool based on input configuration file. This
+tool input configuration file is generated using binman, and the tool
+is invoked from binman as well.
+
+The existing file structure is automatically collected by the nxp-imx93cst
+etype and submitted as a single signing operation: the container header
+and the signature block offsets are read from the i.MX container header,
+so the offsets in the CST configuration file are always correct, whether
+the ELE FW is bundled in the image or not.
+
+Per default the AHAB keys and certificates need to be located in the
+build directory, this means creating a symbolic link or copying the
+following files from the AHAB PKI tree directory into the u-boot build
+directory for the CST Code Signing Tool to locate them:
+
+- ``crts/SRK_1_2_3_4_table.bin``
+- ``crts/SRK1_sha384_secp384r1_v3_usr_crt.pem``
+- ``keys/SRK1_sha384_secp384r1_v3_usr_key.pem``
+- ``keys/key_pass.txt``
+
+See the :doc:`AHAB introduction <../introduction_ahab>` document for the
+PKI tree generation procedure (ahab_pki_tree tool) and for the SRK Table
+generation (srktool).
+
+The paths to the SRK table and the certificate can be modified via
+changes to the nxp-imx93cst device tree node(s) or via the environment
+variables.
+
+The nxp-imx93cst etype is configurable using either DT properties or
+environment variables. The following DT properties and environment
+variables are supported. Note that environment variables override DT
+properties.
+
+.. list-table::
+ :header-rows: 1
+
+ * - DT property
+ - Variable
+ - Description
+ * - ``nxp,srk-table``
+ - ``SRK_TABLE``
+ - full path to ``SRK_1_2_3_4_table.bin``
+ * - ``nxp,srk-crt``
+ - ``SRK_KEY``
+ - full path to the SRK certificate ``SRK1_sha384_secp384r1_v3_usr_crt.pem``
+
+
+The SRK private key (``SRK1_sha384_secp384r1_v3_usr_key.pem``) must be located
+next to the certificate so that can find it.
+
+Environment variables can be set as follows to point the build process
+to external key material:
+
+.. code-block:: console
+
+ $ export SRK_TABLE=$CST_DIR/crts/SRK_1_2_3_4_table.bin
+ $ export SRK_KEY=$CST_DIR/crts/SRK1_sha384_secp384r1_v3_usr_crt.pem
+ $ make flash.bin
+
+5. Programming SRK Hash
+-----------------------
+
+As explained in the :doc:`AHAB introduction <../introduction_ahab>`
+document, the SRK Hash fuse values are generated by the srktool and
+should be programmed in the SoC SRK_HASH[255:0] fuses.
+
+Be careful when programming these values, as this data is the basis for
+the root of trust. An error in SRK Hash results in a part that does not
+boot.
+
+The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs.
+
+- Dump SRK Hash fuses values in host machine:
+
+ On i.MX93 family, the SRK Hash uses sha256 and dump 8 words fuses:
+
+ .. code-block:: console
+
+ $ od -t x4 SRK_1_2_3_4_fuse.bin
+ 0000000 db2959f2 90dfc39c 53394566 e0b75829
+ 0000020 85e6f3b1 af00983d e5e804fe 7a451024
+
+- Program SRK_HASH[255:0] fuses:
+
+On i.MX93:
+
+.. code-block:: console
+
+ => fuse prog 16 0 0xdb2959f2
+ => fuse prog 16 1 0x90dfc39c
+ => fuse prog 16 2 0x53394566
+ => fuse prog 16 3 0xe0b75829
+ => fuse prog 16 4 0x85e6f3b1
+ => fuse prog 16 5 0xaf00983d
+ => fuse prog 16 6 0xe5e804fe
+ => fuse prog 16 7 0x7a451024
+
+6. Verify AHAB events
+---------------------
+
+If the fuses have been burned properly, there should be no AHAB events
+after boot. To validate this, power on the board, and run ahab_status
+command on U-Boot terminal.
+
+No events should be returned after this command:
+
+.. code-block:: console
+
+ => ahab_status
+ Lifecycle: 0x00000008, OEM Open
+
+ No Events Found!
+
+7. Close the device
+-------------------
+.. warning::
+
+ Before closing the device, please ensure your sample is in OEM Open state,
+ OEM SRK hash has been fused, and you are able to boot a signed image
+ successfully without any AHAB events reported . If not, your sample will be
+ unrecoverable.
+
+After the device successfully boots a signed image without generating any
+AHAB security events, it is safe to close the device. The chip lifecycle
+should be changed from OEM open to OEM closed. Be aware this step can
+damage your board if a previous step failed. It is also irreversible. Run
+on the U-Boot terminal:
+
+.. code-block:: console
+
+ => ahab_close
+
+Now reboot the target, and run:
+
+.. code-block:: console
+
+ => ahab_status
+ Lifecycle: 0x00000020, OEM Closed
+
+ No Events Found!
diff --git a/doc/imx/ahab/guides/mx93_secure_boot.txt b/doc/imx/ahab/guides/mx93_secure_boot.txt
new file mode 100644
index 00000000000..45a70926d51
--- /dev/null
+++ b/doc/imx/ahab/guides/mx93_secure_boot.txt
@@ -0,0 +1,269 @@
++=========================================================+
++ i.MX93 Secure boot guide using AHAB +
++=========================================================+
+
+1. AHAB secure boot process
+----------------------------
+
+This document provides a step-by-step guide on how to securely boot an
+i.MX93 boot image. It is assumed that the reader is familiar with basic
+AHAB concepts and with the PKI tree generation. Details about AHAB can be
+found in the introduction_ahab.txt document and in processors Security
+Reference Manual Document (SRM). The i.MX93 signing procedure is
+integrated in the U-Boot build thanks to binman.
+
+1.1 Preparing the environment to build a secure boot image
+-----------------------------------------------------------
+
+Secure boot image preparation requires the U-Boot build system to build
+the image and the Code Signing Tool (CST) to sign it.
+
+Based on boot mode, the following files are needed to prepare the boot
+image:
+
+- All boot modes
+ - Edgelock secure enclave Firmware (ELE) (Optional).
+ - DDR PHY initialization firmware.
+ - U-Boot proper and SPL.
+ - ARM Trusted Firmware (ATF).
+ - OPTEE (Optional)
+
+The ELE FW is distributed by NXP and is already signed using NXP keys.
+In the following sections, <work> designates the repository where all
+parts have been downloaded and built.
+
+1.2 Preparing U-Boot to support AHAB secure boot features
+----------------------------------------------------------
+
+The U-Boot/SPL provides extra AHAB supported functionalities that include
+extension of Root of Trust, checking any events(issues) after image
+authentication, chip lifecycle status, securing the target etc.
+
+The support is enabled by adding CONFIG_AHAB_BOOT to the defconfig file
+used by your target:
+
+ - Defconfig:
+ CONFIG_AHAB_BOOT=y
+ - Kconfig:
+ ARM architecture -> Support i.MX9 AHAB features
+
+Enabling this feature allows the SPL and U-Boot images to extend the Root
+of Trust by using the AHAB API call via ELE FW. It also enables binman to
+automatically sign the SPL and U-Boot containers while building
+flash.bin, as described in the next sections.
+
+1.3 i.MX93 AHAB image layout
+-----------------------------
+
+The i.MX93 flash.bin image is built by binman and is composed of up to
+three containers. The ELE FW container is optional and is provided by NXP,
+it is appended at the beginning of the image when the file
+mx93a1-ahab-container.img is present in the build directory. The SPL and
+U-Boot containers are built by the nxp-imx9image etype and signed by the
+nxp-imx93cst etype.
+
+ *start ----> +---------------------------+ ---------
+ | 1st Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | ELE ROM/FW Level
+ | Padding | |
+ +---------------------------+ |
+ | ELE FW | v
+ *start + 0x400 ---> +---------------------------+ ---------
+ | 2nd Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | ELE ROM/FW Level
+ | Padding | |
+ +---------------------------+ |
+ | SPL | v
+ +---------------------------+ ---------
+ | 3rd Container header | ^
+ | and signature | | Authenticated at
+ +---------------------------+ | SPL Level
+ | Padding | |
+ +---------------------------+ |
+ | ARM Trusted FW (ATF) | |
+ +---------------------------+ |
+ | U-Boot proper | |
+ +---------------------------+ |
+ | OPTEE (optional) | v
+ +---------------------------+ ---------
+
+The first container includes the ELE FW which is signed using NXP keys,
+this container is authenticated by ELE ROM.
+
+The second container includes the SPL which is signed using OEM keys,
+this container is authenticated at ELE FW level.
+
+The third container includes the U-Boot proper and the ATF. The SPL is in
+charge to load this container and also to interface with ELE FW to
+authenticate the additional container.
+
+The signing procedure is slightly different when compared with HABv4
+series. On AHAB the signature is directly included in the container, the
+CST is responsible to sign and handle the "Signature Block":
+
+ +----------------------------+ ---------
+ | | ^
+ | | |
+ | Container header | |
+ | | |
+ | | |
+ +---+------------------------+ |
+ | S | Signature block header | | Signed
+ | i +------------------------+ |
+ | g | | |
+ | n | | |
+ | a | SRK table | |
+ | t | | |
+ | u | | v
+ | r +------------------------+ ---------
+ | e | Signature |
+ | +------------------------+
+ | B | |
+ | l | SGK Key |
+ | o | Certificate (optional) |
+ | c | |
+ | k | |
+ +---+------------------------+
+
+The certificate block is divided into:
+
+ +---------------+ ^
+ | Public key | | Signed
+ | Permission | |
+ +---------------+ v
+ | Signature |
+ +---------------+
+
+The first block (public key permission) verifies the Signature block
+preceding (between SRK table and Certificate blocks), while the second
+block (signature) is verified by the SRK table block.
+
+In case not using the subordinate key, the container signature is
+verified against the SRK keys directly.
+
+1.4 Signing the images
+-----------------------
+
+Internally, Command Sequence Files (CSF) are used. The CSF files contain
+all the commands that the AHAB executes during the secure boot. These
+commands instruct the AHAB code on which memory areas of the image to
+authenticate, which keys to install, use and etc. The CSF is generated
+using the CST Code Signing Tool based on input configuration file. This
+tool input configuration file is generated using binman, and the tool
+is invoked from binman as well.
+
+The existing file structure is automatically collected by the nxp-imx93cst
+etype and submitted as a single signing operation: the container header
+and the signature block offsets are read from the i.MX container header,
+so the offsets in the CST configuration file are always correct, whether
+the ELE FW is bundled in the image or not.
+
+Per default the AHAB keys and certificates need to be located in the
+build directory, this means creating a symbolic link or copying the
+following files from the AHAB PKI tree directory into the u-boot build
+directory for the CST Code Signing Tool to locate them:
+
+- `crts/SRK_1_2_3_4_table.bin`
+- `crts/SRK1_sha384_secp384r1_v3_usr_crt.pem`
+- `keys/SRK1_sha384_secp384r1_v3_usr_key.pem`
+- `keys/key_pass.txt`
+
+See the introduction_ahab.txt document for the PKI tree generation
+procedure (ahab_pki_tree tool) and for the SRK Table generation
+(srktool, use the SHA256 variant for i.MX93).
+
+The paths to the SRK table and the certificate can be modified via
+changes to the nxp-imx93cst device tree node(s) or via the environment
+variables.
+
+The nxp-imx93cst etype is configurable using either DT properties or
+environment variables. The following DT properties and environment
+variables are supported. Note that environment variables override DT
+properties.
+
++--------------------+-------------+--------------------------------------------------------------+
+| DT property | Variable | Description |
++====================+=============+==============================================================+
+| nxp,srk-table | SRK_TABLE | full path to SRK_1_2_3_4_table.bin |
++--------------------+-------------+--------------------------------------------------------------+
+| nxp,srk-crt | SRK_KEY | full path to the SRK Key SRK1_sha384_secp384r1_v3_usr_crt.pem|
++--------------------+-------------+--------------------------------------------------------------+
+
+Environment variables can be set as follows to point the build process
+to external key material:
+
+ $ export SRK_TABLE=$CST_DIR/crts/SRK_1_2_3_4_table.bin
+ $ export SRK_KEY=$CST_DIR/crts/SRK1_sha384_secp384r1_v3_usr_crt.pem
+ $ make flash.bin
+
+1.5 Programming SRK Hash
+-------------------------
+
+As explained in introduction_ahab.txt document, the SRK Hash fuse values
+are generated by the srktool and should be programmed in the SoC
+SRK_HASH[255:0] fuses.
+
+Be careful when programming these values, as this data is the basis for
+the root of trust. An error in SRK Hash results in a part that does not
+boot.
+
+The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs.
+
+- Dump SRK Hash fuses values in host machine:
+
+ On i.MX93 family, the SRK Hash uses sha256 and dump 8 words fuses
+ $ od -t x4 SRK_1_2_3_4_fuse.bin
+ 0000000 db2959f2 90dfc39c 53394566 e0b75829
+ 0000020 85e6f3b1 af00983d e5e804fe 7a451024
+
+- Program SRK_HASH[255:0] fuses:
+
+On i.MX93:
+
+ => fuse prog 16 0 0xdb2959f2
+ => fuse prog 16 1 0x90dfc39c
+ => fuse prog 16 2 0x53394566
+ => fuse prog 16 3 0xe0b75829
+ => fuse prog 16 4 0x85e6f3b1
+ => fuse prog 16 5 0xaf00983d
+ => fuse prog 16 6 0xe5e804fe
+ => fuse prog 16 7 0x7a451024
+
+1.6 Verify AHAB events
+-----------------------
+
+If the fuses have been burned properly, there should be no AHAB events
+after boot. To validate this, power on the board, and run ahab_status
+command on U-Boot terminal.
+
+No events should be returned after this command:
+
+ => ahab_status
+ Lifecycle: 0x00000008, OEM Open
+
+ No Events Found!
+
+1.7 Close the device
+---------------------
+
+After the device successfully boots a signed image without generating any
+AHAB security events, it is safe to close the device. The chip lifecycle
+should be changed from OEM open to OEM closed. Be aware this step can
+damage your board if a previous step failed. It is also irreversible. Run
+on the U-Boot terminal:
+
+ => ahab_close
+
+Warning: Please ensure your sample is in OEM Open state, OEM SRK hash
+has been fused, and you are able to boot a signed image successfully
+without any SECO events reported. If not, your sample will be
+unrecoverable.
+
+Now reboot the target, and run:
+
+ => ahab_status
+ Lifecycle: 0x00000020, OEM Closed
+
+ No Events Found!
diff --git a/doc/imx/ahab/introduction_ahab.rst b/doc/imx/ahab/introduction_ahab.rst
index aef75b5e841..8c40c840ab5 100644
--- a/doc/imx/ahab/introduction_ahab.rst
+++ b/doc/imx/ahab/introduction_ahab.rst
@@ -292,7 +292,8 @@ scenario in i.MX 9x:
| │ │ │ │
More details on the boot flow can be found in respective Security Reference
-Manual (SRM).
+Manual (SRM) and in the :doc:`i.MX93 Secure boot guide
+<guides/mx93_secure_boot>`.
2. Generating a PKI tree
------------------------
diff --git a/doc/imx/index.rst b/doc/imx/index.rst
index cc5f427de92..daf846947cc 100644
--- a/doc/imx/index.rst
+++ b/doc/imx/index.rst
@@ -11,3 +11,4 @@ architecture introduction and the i.MX93 secure boot guide.
:maxdepth: 2
ahab/introduction_ahab
+ ahab/guides/mx93_secure_boot
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 7/7] binman: test: add code coverage for nxp_imx93cst etype
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
` (5 preceding siblings ...)
2026-09-02 13:41 ` [PATCH v2 6/7] doc: imx: ahab: add i.MX93 secure boot guide Jérémie Dautheribes (Schneider Electric)
@ 2026-09-02 13:41 ` Jérémie Dautheribes (Schneider Electric)
6 siblings, 0 replies; 8+ messages in thread
From: Jérémie Dautheribes (Schneider Electric) @ 2026-09-02 13:41 UTC (permalink / raw)
To: NXP i.MX U-Boot Team, u-boot
Cc: Jérémie Dautheribes (Schneider Electric),
Miquèl Raynal, Thomas Petazzoni, Tom Rini, Simon Glass,
Alper Nebi Yasak, Stefano Babic, Fabio Estevam, Marek Vasut,
Denis Mukhin, Rasmus Villemoes, Ilias Apalodimas,
Krzysztof Drobiński, Peng Fan, Alice Guo, Simona Toaca,
Ye Li, Quentin Schulz, Christophe Guerreiro
Add test methods to cover all code paths of the nxp_imx93cst etype,
reusing the pattern of the nxp_imx8mcst as done in commit 0cab35362d77
("binman: test: Fix code coverage for iMX8 and cst bintool") by Simon
Glass.
This brings nxp_imx93cst to 100% coverage.
Signed-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>
---
tools/binman/ftest.py | 85 ++++++++++++++++++++++
tools/binman/test/vendor/nxp_imx93_csf.dts | 18 +++++
.../binman/test/vendor/nxp_imx93_csf_imagename.dts | 24 ++++++
3 files changed, 127 insertions(+)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 5f0de4c74a7..ce012b415ff 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -35,6 +35,7 @@ from dtoc import fdt
from dtoc import fdt_util
from binman.etype import fdtmap
from binman.etype import image_header
+from binman.etype import nxp_imx93cst
from binman.image import Image
from u_boot_pylib import command
from u_boot_pylib import terminal
@@ -8152,6 +8153,90 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
result = cst.fetch(bintool.FETCH_BUILD)
self.assertEqual(('cst', None), result)
+ def testNxpImx93cstNormal(self):
+ """Test CST signing with an i.MX93 SPL container (no ELE FW)"""
+ # Create a fake AHAB SPL container: tag at offset 3, image-entry
+ # flags at offset 40 whose low byte is the A55 core/type (0x23),
+ # and the signature block offset at offset 12
+ spl_data = bytearray(64)
+ spl_data[3] = nxp_imx93cst.CONTAINER_HDR_TAG
+ spl_data[12:14] = struct.pack('<H', 0x90)
+ spl_data[40:44] = struct.pack('<I', 0x123)
+ self._MakeInputFile('imx93-container.bin', bytes(spl_data))
+
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('vendor/nxp_imx93_csf.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
+ def testNxpImx93cstELE(self):
+ """Test CST signing where the SPL container starts with the ELE FW"""
+ # Create a fake AHAB image starting with the NXP-signed ELE
+ # container. The low byte of the first image entry flags (0x66) is
+ # the ELE core/type, so the SPL container header is at 0x400
+ ele_data = bytearray(0x410)
+ ele_data[3] = nxp_imx93cst.CONTAINER_HDR_TAG
+ ele_data[40:44] = struct.pack('<I', 0x866)
+ ele_data[0x400 + 3] = nxp_imx93cst.CONTAINER_HDR_TAG
+ ele_data[0x400 + 12:0x400 + 14] = struct.pack('<H', 0x90)
+ self._MakeInputFile('imx93-container.bin', bytes(ele_data))
+
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('vendor/nxp_imx93_csf.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
+ def testNxpImx93cstUnknownTag(self):
+ """Test CST with unknown input tag passes data through"""
+ # Trigger the pass-through path using an input without the AHAB
+ # container tag
+ data = b'\x00' * 64
+ self._MakeInputFile('imx93-container.bin', data)
+ self._DoTestFile('vendor/nxp_imx93_csf.dts',
+ force_missing_bintools='cst')
+
+ # The pass-through branch returns the input data unchanged, so the
+ # produced image must be exactly the 64 zero bytes
+ out = tools.read_file(tools.get_output_filename('image.bin'))
+ self.assertEqual(out, b'\x00' * 64)
+
+ def testNxpImx93cstSigned(self):
+ """Test CST-signing-success path with mocked cst invocation"""
+ spl_data = bytearray(64)
+ spl_data[3] = nxp_imx93cst.CONTAINER_HDR_TAG
+ spl_data[12:14] = struct.pack('<H', 0x90)
+ spl_data[40:44] = struct.pack('<I', 0x123)
+ self._MakeInputFile('imx93-container.bin', bytes(spl_data))
+
+ # Mock run_cmd() so that when cst is invoked, it creates a fake
+ # output blob and returns success, thus covering the signing path
+ original = bintool.Bintool.run_cmd
+
+ def fake_cst_run_cmd(self_tool, *args, binary=False):
+ if self_tool.name == 'cst':
+ arg_list = list(args)
+ if '-o' in arg_list:
+ idx = arg_list.index('-o')
+ tools.write_file(arg_list[idx + 1], b'\x00' * 32)
+ return 'fake cst output'
+ return original(self_tool, *args, binary=binary)
+
+ with unittest.mock.patch.object(bintool.Bintool, 'run_cmd',
+ new=fake_cst_run_cmd):
+ data = self._DoReadFile('vendor/nxp_imx93_csf.dts')
+
+ # The output must be the fake 32-byte CST blob produced by cst
+ self.assertEqual(data, b'\x00' * 32)
+
+ def testNxpImx93ImageSizeNone(self):
+ """Test SetImagePos() early return when an entry has no size"""
+ # The imagename entry is in GetEntries() but not packed, so has
+ # size=None, which triggers the early-return guard in SetImagePos()
+ self._DoTestFile('vendor/nxp_imx93_csf_imagename.dts',
+ force_missing_bintools='mkimage')
+
def testNxpImx8MFSPI(self):
"""Test that binman can produce an iMX8m FSPI image"""
self._DoTestFile('vendor/nxp_imx8m_fspi.dts')
diff --git a/tools/binman/test/vendor/nxp_imx93_csf.dts b/tools/binman/test/vendor/nxp_imx93_csf.dts
new file mode 100644
index 00000000000..bbe8eda4b70
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx93_csf.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx93cst {
+ args;
+
+ blob {
+ filename = "imx93-container.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx93_csf_imagename.dts b/tools/binman/test/vendor/nxp_imx93_csf_imagename.dts
new file mode 100644
index 00000000000..13009438ee8
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx93_csf_imagename.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx93cst {
+ args;
+
+ u-boot {
+ };
+
+ imagename {
+ type = "section";
+
+ u-boot {
+ };
+ };
+ };
+ };
+};
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-02 13:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 13:41 [PATCH v2 0/7] binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 1/7] binman: add nxp_imxcst base etype for i.MX CST signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 2/7] binman: nxp_imx8mcst: use the nxp_imxcst base etype Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 3/7] tools: binman: add nxp_imx93cst etype for i.MX93 flash.bin signing Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 4/7] imx93-u-boot: wrap SPL and U-Boot nodes in a CST node if AHAB_BOOT enabled Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 5/7] doc: imx: ahab: add AHAB introduction Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 6/7] doc: imx: ahab: add i.MX93 secure boot guide Jérémie Dautheribes (Schneider Electric)
2026-09-02 13:41 ` [PATCH v2 7/7] binman: test: add code coverage for nxp_imx93cst etype Jérémie Dautheribes (Schneider Electric)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.