Generate an AHAB PKI Tree¶
This guide covers generating the SRK key set, signing configuration, and eFuse hash required to sign i.MX9 boot images with AHAB, using the NXP Secure Provisioning SDK (SPSDK). The resulting key set is consumed by Enable NXP Authenticated Boot.
Prerequisites¶
- SPSDK installed in a virtual environment:
- An i.MX9, i.MX8ULP, or i.MX8QM/QXP/DXL target. i.MX8M targets use HAB4 — see Generate a HAB4 PKI Tree
Generate the PKI Tree¶
| Option | Value | Description |
|---|---|---|
-k |
secp384r1 |
Key type: rsa2048, rsa3072, rsa4096, secp256r1, secp384r1, secp521r1 |
-n |
4 |
Number of SRKs; four leaves one that can never be revoked |
-d |
10 |
Certificate validity in years |
-o |
./ahab-pki |
Output directory |
-p |
— | Optional passphrase encrypting the private keys |
-ca |
— | Optional; also generates SGK keys beneath the SRK certificates |
Output:
ahab-pki/
├── crts/ # X.509 certificates
│ ├── CA0_secp384r1_ca_cert.pem
│ └── SRK{0..3}_secp384r1_cert.pem
└── keys/ # private keys, with their public counterparts
├── CA0_secp384r1_ca_key.pem
├── CA0_secp384r1_ca_key.pub
├── SRK{0..3}_secp384r1_key.pem
└── SRK{0..3}_secp384r1_key.pub
ahab-pki/keys/key_pass.txt must exist, since imx_signer always points SPSDK at that file. If
-p was used, write the same passphrase into it; otherwise leave it empty.
Warning
Restrict permissions on keys/ and never commit it. In production, hold the PKI tree on a host
separate from the build machine, or use an SPSDK signature provider backed by an HSM.
Assemble the Signing Configuration¶
Generate a template, or start from devel-keys/secure-boot/ahab/spsdk_ahab.yaml:
Set these fields:
| Field | Value |
|---|---|
srk_set |
oem |
used_srk_id |
Index of the SRK used to sign — 0 for SRK0 |
srk_table.hash_algorithm |
sha384 for secp384r1 |
srk_table.srk_array |
The four SRK{0..3}_secp384r1_cert.pem filenames |
signer |
Private key matching used_srk_id, for example SRK0_secp384r1_key.pem |
Warning
srk_array and signer take bare filenames, never paths. imx_signer rewrites them to
${SIG_DATA_PATH}/crts/… and to a type=file signature provider under ${SIG_DATA_PATH}/keys/.
Note
Do not hand-maintain family:. The imx-boot-signature recipe rewrites it from SPSDK_FAMILY,
which xhab.bbclass derives per machine.
Wire the Key Set into the Build¶
<SIG_DATA_PATH>/
├── spsdk_ahab.yaml
├── crts/
│ └── SRK{0..3}_secp384r1_cert.pem
└── keys/
├── SRK{0..3}_secp384r1_key.pem
└── key_pass.txt
Point the build at the tool and the data directory, then continue with Enable NXP Authenticated Boot:
SIG_TOOL_PATH must be the directory containing the spsdk and nxpimage executables — the
virtual environment's bin/ directory, not its root.
Compute the SRK Hash¶
SPSDK has no standalone command that turns a certificate set into fuse values. Compute the hash directly from the four certificates:
from spsdk.crypto.utils import extract_public_key
from spsdk.image.ahab.ahab_srk import SRKTable
srk = SRKTable()
for i in range(4):
srk.add_record(extract_public_key(f"crts/SRK{i}_secp384r1_cert.pem"))
srk.update_fields()
print(srk.compute_srk_hash().hex())
Split the 32-byte digest into eight 32-bit words. They map to OTP IDs 128–135, in order.
Alternatively, exporting a complete AHAB container writes the same values plus a programming script:
| Artifact | Contents |
|---|---|
*_srk_hash.txt |
OTP IDs 128–135 and their 32-bit values |
*.bcf |
nxpele batch script with one write-fuse per OTP ID |
Note
nxpimage ahab export needs a configuration describing the container images, not the
signing-only configuration in SIG_DATA_PATH. The build invokes nxpimage ahab sign, which does
not emit these artifacts, so this is a separate manual step.
Program the SRK Hash into eFuses¶
Danger
eFuse writes are irreversible. A wrong SRK hash permanently prevents the SoC from booting once the lifecycle is advanced to OEM closed. Program the hash, read it back, boot a signed image with no AHAB events, and only then close the device.
The values below are for i.MX93. Other AHAB families use family-specific OTP indices; the fuse map in the SoC reference manual is authoritative.
Replay the generated batch script over the ELE serial interface:
Or program the fuses from the U-Boot console. SRKH occupies OTP IDs 128–135, and i.MX9 OCOTP banks hold eight words each, so OTP ID 128 is bank 16 word 0:
u-boot=> fuse prog -y 16 0 <OTP 128>
u-boot=> fuse prog -y 16 1 <OTP 129>
u-boot=> fuse prog -y 16 2 <OTP 130>
u-boot=> fuse prog -y 16 3 <OTP 131>
u-boot=> fuse prog -y 16 4 <OTP 132>
u-boot=> fuse prog -y 16 5 <OTP 133>
u-boot=> fuse prog -y 16 6 <OTP 134>
u-boot=> fuse prog -y 16 7 <OTP 135>
Read the values back, then boot the signed image and confirm AHAB reports no events:
Advance the lifecycle to OEM closed. This is the final, irreversible step:
Automation
SRK hash extraction and fuse programming are manual today. The secure boot recipes under
meta-tolomeo-nxp may automate both in a future release.
Development Keys¶
DAVE provides a pre-generated AHAB key set in devel-keys/ for build validation without a production
PKI:
| File | Purpose |
|---|---|
devel-keys/secure-boot/ahab/spsdk_ahab.yaml |
AHAB signing configuration for mimx9352 |
devel-keys/secure-boot/ahab/crts/ |
SRK0–SRK3 certificates (secp384r1) and the root CA |
devel-keys/secure-boot/ahab/keys/ |
Matching private keys and key_pass.txt |
Warning
The keys in devel-keys/ are publicly known and exist only for build validation. Never use them
on a production device, and never fuse their SRK hash into a shipping SoC.
See also
- Enable NXP Authenticated Boot — wire the key set into the build
- Generate a HAB4 PKI Tree — the i.MX8M equivalent
- Enable FIT Image Signing — the kernel FIT signing stage
- Secure Boot Chain — how AHAB fits the boot chain
- Secure Boot Reference — variables, includes, classes, recipes
- nxpcrypto — SPSDK key tooling