Secure Boot with i.MX 95 SPSDK (Japanese Blog) Introduction
This document describes the procedure for creating and booting a signed container image using the Secure Provisioning SDK (SPSDK) for secure booting on i.MX 95 .
In addition to classic RSA and Elliptic Curve Digital Signatures (ECDSA), i.MX 95 also supports Post -Quantum Cryptography (PQC) ML-DSA as a secure boot digital signature algorithm.
Here, we will look at an example of implementing both ECDSA and PQC ML-DSA signature authentication using Hybrid Boot.
Secure Boot Process (Conceptual Diagram)
Creating a signed image
SRKH: Super Root Key Hash
i.MX 95 AHAB (Advanced High Accuracy Boot) Secure Boot Flow
This article assumes that you have already built the Linux BSP for i.MX 95 once. Please refer to the following article for instructions on how to build the project.
The build target needs to be the machine name of the i.MX 95, but the method is similar.
[Beginner's Guide] How to Build Yocto Linux BSP - i.MX FRDM Board Edition (Japanese Blog)
[Beginner's Guide] How to Build Yocto Linux BSP - i.MX 8M Plus Edition
The environment used for testing this time
Hardware: Development board i.MX 95 19x19 LPDDR5 EVK
Software: Linux BSP version L6.18.2-1.0.0
Tools: SPSDK version 3.9.0, Linux version
If you are using eMMC/SD booting, you can perform the same procedure with the FRDM i.MX 95 development board (FRDM-IMX95 / LPDDR4X compatible).
table of contents
1. Preparation on Linux BSP 2. Installing SPSDK 3. Key creation 4. Preparing the YAML file 5. Preparing the workspace 6. Creating a signed image 7. Introduction of signed images 8. SRKH (Super Root Key Hash) eFuse Program 9. Update the lifecycle to OEM Closed. 10. Checking ELE Events 11. Direct signing of the bootloader
The preparation procedures and commands used for eMMC/SD booting and FlexSPI NOR booting differ slightly. Therefore, please follow the procedure appropriate for the boot device you wish to test.
1. Preparation on Linux BSP
1.1 Bootloader
FlexSPI NOR boot
The BSP's default boot loader is configured for eMMC/SD booting.
For FlexSPI NOR booting, add the following to the / /conf/local.conf file.
UBOOT_CONFIG = "fspi"
eMMC / SD / FlexSPI NOR Boot Common
Use the bootloader built with u-boot CONFIG_AHAB_BOOT enabled.
$ cd
$ source setup-environment
$ bitbake u-boot-imx -c cleansstate
$ bitbake u-boot-imx -c configure
$ bitbake u-boot-imx -c devshell
A separate shell will open, where you can modify the u-boot configuration.
# make O=../../build/ / menuconfig
The build directory path specified with O= should be adjusted to match your actual environment.
../../build/ /.config Then, confirm that it shows CONFIG_AHAB_BOOT=y and return to the original shell.
# exit
Rebuild using the original shell.
$ bitbake u-boot-imx -c compile -f
$ bitbake imx-boot
1.2 Linux kernel and device tree
We will use the binary built with BSP as is.
The built binaries are created in the BSP's /tmp/deploy/images/ / directory.
2. Installing SPSDK
Follow the SPSDK Installation Guide to prepare and install a Python virtual environment (venv). After installation, check if you can view version information and help.
(venv) $ spsdk --version
(venv) $ spsdk --help
We will also add the PQC plugin.
(venv) $ pip install spsdk-pqc
3. Key creation
We will create four pairs of private/public keys for ECDSA SECP384.
(venv) $ mkdir -p keys/secp384r1
(venv) $ nxpcrypto -v key generate -k secp384r1 -o keys/secp384r1/srk0_secp384r1.pem
(venv) $ nxpcrypto -v key generate -k secp384r1 -o keys/secp384r1/srk1_secp384r1.pem
(venv) $ nxpcrypto -v key generate -k secp384r1 -o keys/secp384r1/srk2_secp384r1.pem
(venv) $ nxpcrypto -v key generate -k secp384r1 -o keys/secp384r1/srk3_secp384r1.pem
We will also create four pairs of private/public keys for PQC ML-DSA.
(venv) $ mkdir keys/mldsa65
(venv) $ nxpcrypto -v key generate -k mldsa65 -o keys/mldsa65/srk0_mldsa65.pem
(venv) $ nxpcrypto -v key generate -k mldsa65 -o keys/mldsa65/srk1_mldsa65.pem
(venv) $ nxpcrypto -v key generate -k mldsa65 -o keys/mldsa65/srk2_mldsa65.pem
(venv) $ nxpcrypto -v key generate -k mldsa65 -o keys/mldsa65/srk3_mldsa65.pem
After writing the public key hash (Super Root Key Hash - SRKH) to the i.MX 95's built-in eFuse, when you rebuild the image, you need to sign it with the private key that pairs with that public key, so save all the keys you've created.
I will not disclose my private key to any third party.
4. Preparing the YAML file
In SPSDK, the YAML file specifies the container header settings, the private key, the public key, and the paths to the binary files that make up the signed image.
Please also refer to the example YAML file used in this operational verification.
The container header settings and key specification fields in the YAML file are as follows:
Container header
YAML key
Content
srk_set
SRK Set
used_srk_id
SRK Selection
srk_revoke_mask
SRK Revoke Mask
gdet_runtime_behavior
GDET enablement
check_all_signatures
Check all signatures
pocket
Fast Boot
fuse_version
Fuse Version
sw_version
SW Evolution
Each field in the container header is described in the "Container header details" section of the i.MX 95 Reference Manual .
Key specification
YAML key
Content
signer
Classic private key
signer_#2
PQC private key
srk_table
Classic public key table
srk_table_#2
PQC Public Key Table
Specify the same key in all YAML files.
4.1 YAML file for bootloader
Create a YAML file template and prepare spl.yaml and uboot.yaml.
(venv) $ nxpimage ahab get-template -f mimx9596 -o ahab_template.yaml
(venv) $ cp ahab_template.yaml spl.yaml
(venv) $ cp ahab_template.yaml uboot.yaml
spl.yaml Specify the files up to the point where they are loaded into the i.MX 95's internal SRAM and perform DRAM initialization training, etc.
YAML Key
Content
binary_container
ELE Boot Firmware (Binary specific to Mask Revision)
lpddr_imem
LPDDR4X or 5 Initialization Firmware
lpddr_imem_qb
LPDDR4X or 5 Initialization Firmware
lpddr_dmem
LPDDR4X or 5 initialization data
lpddr_dmem_qb
LPDDR4X or 5 initialization data
oei_ddr
OEI
system_manager
System Manager
spl
U-boot SPL
cortex_m7_app (Option)
M7 image
image_path (Option)
FCB copy generate
uboot.yaml U-boot SPL specifies the files to be loaded into DRAM.
YAML Key
Content
atf
ARM Trusted Firmware
uboot
U-boot
tee (Option)
OP-TEE OS (Option)
4.2 Removing the FCB - FlexSPI NOR Boot Only
The YAML file for FlexSPI NOR booting also specifies the FCB (FlexSPI Configuration Block). Therefore, the standard unsigned bootloader (flash.bin) built for FlexSPI NOR booting... Next, we'll extract the FCB using the SPSDK command.
The FCB is located at the FlexSPI_NOR_FCB_Offset (default 0x400) of the i.MX 95's built-in eFuse. 512 bytes are extracted from that offset and used to create fcb.bin.
(venv) $ nxpimage utils binary-image extract -b flash.bin -a 0x400 -s 0x200 -o fcb.bin
4.3 YAML file for OS container
Prepare os_cntr.yaml from the YAML file template.
(venv) $ cp ahab_template.yaml os_cntr.yaml
In os_cntr.yaml, the key image_path sets the path to the Linux kernel and the device tree to be used, and other necessary parameters are also set.
4.4 Selection of a Digital Signature Algorithm
This will be selected using the i.MX 95's built-in eFuse or the Flags in the container header.
eFuse
Flags field in the container header
By setting "Bit 15: Check all signature" = 0x1 in the Flags field of the container header, all signatures within the container will be authenticated regardless of the ELE_BOOT_CRYPTO setting in eFuse.
The "Check all signature" field in the container header's Flags section is specified by the YAML key "check_all_signature".
5. Preparing the workspace
Create a workspace in SPSDK and place the necessary key files, YAML files, and binary files there.
5.1 Creating a Workspace
(venv) $ nxpimage bootable-image get-templates -f mimx9596 -o workspace
5.2 Key File
I'll bring over the entire `keys` folder that I created when generating the key .
5.3 Example YAML File
The YAML file used for testing is attached to imx95-spsdk-yaml-examples.tar.gz .
5.4 Binary files
If you want to get binary files from Yocto Linux BSP,
The binary that makes up the boot loader Copy the binary located in iMX95/ from the path displayed by $ bitbake -e imx-boot | grep ^S=.
Linux kernel / /tmp/deploy/images/ /Image-- - - .bin Copy this.
Device Tree Copy one of the dtb files located in / /tmp/deploy/images/ / that you want to use.
If you use the example YAML file , The Linux kernel is an image. The device tree is imx95.dtb They will be placed under these names.
5.5 eMMC / SD Boot
The file structure will be as follows:
If you use the example YAML file , rename spl.yaml from emmc_sd/spl-lpddr4x.yaml or spl-lpddr5.yaml depending on the DRAM type and place it in the correct location.
In the above example, the ELE boot firmware is mx95b0-ahab-container.img for RevC products (B0 mask).
5.6 FlexSPI NOR Boot
The file structure will be as follows. fcb.bin is also required.
If you want to use the example YAML file , copy bootable_image_fspi_nor.yaml from fspi_nor/. Also, rename spl_fspi_nor-lpddr5.yaml to spl.yaml and place it in the correct location.
In the above example, the ELE boot firmware is mx95b0-ahab-container.img for RevC products (B0 mask).
6. Creating a signed image
We will create signed bootloader and signed OS container images using the SPSDK.
Navigate to the directory created during workspace preparation and begin working there.
(venv) $ cd workspace/imx_boot_flash_all/imx95-19x19-lpddr5-evk/
6.1 Signed Bootloader
The spl.yaml and uboot.yaml files, which specify the key file and binary file, are called from bootable_image.yaml.
A signed bootloader, signed_flash.bin, and a script (*.bcf) for the SRKH eFuse program will be created.
eMMC / SD Boot
(venv) $ nxpimage -v bootable-image export --config bootable_image.yaml -o output/signed_flash.bin
The following information will be displayed.
FlexSPI NOR boot
(venv) $ nxpimage -v bootable-image export --config bootable_image_fspi_nor.yaml -o output/signed_flash.bin
The following information will be displayed. One difference from eMMC/SD is that it has "FCB" at the beginning.
You can perform image verification.
// eMMC / SD ブート
(venv) $ nxpimage -v bootable-image verify -f mimx9596 -b output/signed_flash.bin -m serial_downloader
// FlexSPI NOR ブート
(venv) $ nxpimage -v bootable-image verify -f mimx9596 -b output/signed_flash.bin -m flexspi_nor
6.2 Signed OS Containers
The contents of os_cntr.yaml will be used to create a signed OS container image.
(venv) $ nxpimage -v ahab export -c os_cntr.yaml
The following information will be displayed.
You can perform image verification.
(venv) $ nxpimage -v bootable-image verify -f mimx9596 -b output/os_cntr_signed.bin -m serial_downloader
7. Introduction of signed images
This explains how to install the signed bootloader and signed OS container you created.
7.1 Signed Bootloader
Write signed_flash.bin to the boot device of the i.MX95 board.
Connect the board's debug port and serial download port to your PC. If u-boot starts up, switch to fastboot mode.
u-boot=> fastboot 0
Alternatively, you can start the system in BOOT_MODE as serial download mode.
We will write the program using SPSDK.
// eMMC
(venv) $ nxpuuu write -b emmc -f mimx9596 output/signed_flash.bin
// SD
(venv) $ nxpuuu write -b sd -f mimx9596 output/signed_flash.bin
// FlexSPI NOR
(venv) $ nxpuuu write -b qspi -f mimx9596 output/signed_flash.bin
It is also possible to flash the device using the standard uuu or u-boot command instead of the SPSDK's nxpuuu command.
7.2 Signed OS Containers
Place os_cntr_signed.bin into the boot partition of the eMMC or SD card that already has the BSP image written to it.
The u-boot command makes the connected eMMC or SD card of the i.MX95 appear as USB storage, allowing it to be mounted on the PC. The serial download port must be connected to your PC.
// eMMC
u-boot=> ums mmc 0
// SDカード
u-boot=> ums mmc 1
After copying os_cntr_signed.bin to the boot partition mounted on your PC, press Ctrl-C in u-boot.
Alternatively, you can place os_cntr_signed.bin into the boot partition using another method.
When starting a signed OS container, the following message will appear:
CONFIG_AHAB_BOOT With u-boot enabled , the os_cntr_signed.bin (signed) image is used instead of the regular Linux Image (unsigned).
7.3 Operation Check
At this stage, the i.MX95's lifecycle state is OEM Open, so u-boot or Linux will start, but a KEY HASH verification failure will be detected in the ELE event .
8. SRKH (Super Root Key Hash) eFuse Program
8.1 eFuse Writing
Write the hash value of the public key to the i.MX 95 SRKH eFuse.
Once you write to it, you cannot undo it.
When updating a signed bootloader or signed OS container on the written device, the private key, which is the public key pair underlying the written SRKH, is used to sign it.
If you want to use a different key pair, revoke the current SRKH and use one of the four unused key pairs you have created.
Connect the i.MX 95 board's serial download port to your PC, and ensure that u-boot is set to fastboot mode beforehand.
u-boot=> fastboot 0
SRKH eFuse programming script (*.bcf) created during the creation of a signed image. We will use this and write the program using SPSDK. The SRKH eFuse programming script includes the word index for i.MX 95 eFuse.
// OEM_SRKH
(venv) $ nxpele -f mimx9596 batch output/ahab_oem0_srk0_hash_nxpele.bcf
// OEM_PQC_SRKH
(venv) $ nxpele -f mimx9596 batch output/ahab_oem0_srk1_hash_nxpele.bcf
8.2 Checking the eFuse value
You can use the SPSDK's nxpele command to specify the word index of eFuse and read it to check the value.
// OEM_SRKH[31:0] word index = 128
(venv) $ nxpele -f mimx9596 read-common-fuse -i 128
// OEM_PQC_SRKH[511:480] word index = 463
(venv) nxpele -f mimx9596 read-common-fuse -i 463
など
Alternatively, you can access the eFuse via read and write using U-boot commands or System Manager monitor commands, instead of SPSDK.
U-boot
u-boot=> fuse read
u-boot=> fuse prog
System Manager
>$ fuse.H
>$ fuse.w
8.3 Operation Check
At this stage, the lifecycle status of the i.MX 95 is OEM Open, but because it is programmed with SRKH, no ELE events will be detected unless it has been tampered with.
Even if tampering occurs, if that part does not affect operation, it will boot for OEM Open, but the authentication failure will be detected in the ELE event .
9. Update the lifecycle to OEM Closed.
The i.MX 95's lifecycle immediately after shipment is OEM Open.
After debugging is complete, change the i.MX 95 lifecycle to OEM Closed.
Points to note after closing the OEM
You cannot revert to OEM Open.
CONFIG_AHAB_BOOT=y When booting with a bootloader that includes u-boot, unsigned images and images with invalid signatures will not be able to boot.
CONFIG_AHAB_BOOT=y A bootloader that does not include u-boot can boot with an unsigned Linux image. Therefore, to ensure that the OS container os_cntr_signed.bin is always booted, use a bootloader that includes u-boot with CONFIG_AHAB_BOOT=y .
After verifying functionality, unsigned Linux images and device trees will be removed from the boot partition.
9.1 SPSDK
Connect the i.MX 95 board's serial download port to your PC, and ensure that u-boot is set to fastboot mode beforehand.
u-boot=> fastboot 0
Update the lifecycle using SPSDK.
(venv) $ nxpele -f mimx9596 forward-lifecycle-update -l OEM_CLOSED
Forward Lifecycle update ends successfully.
(venv) $
9.2 U-boot
u-boot=> ahab_close
Even after marking the device as OEM Closed, you will still need to use a signed bootloader when writing the BSP image (wic file) with uuu.
10. Checking ELE Events
ELE (Edgelock Secure Enclave) is a built-in block in the i.MX 95 that authenticates container images during secure boot.
You can check the ELE status using SPSDK, U-boot, and System Manager commands.
10.1 SPSDK
Connect the serial download port to your PC and enter fastboot mode using U-boot before proceeding.
u-boot=> fastboot 0
We will retrieve ELE events using SPSDK.
(venv) $ nxpele -f mimx9596 get-events
10.2 U-boot
CONFIG_AHAB_BOOT=y These are commands that can be used with U-boot.
Depending on the device's lifecycle, it will also show whether it's OEM Open or OEM Closed.
u-boot=> ahab_status
10.3 System Manager
>$ ele events
10.4 Display Example
When an ELE event (SRKH value mismatch) is detected
SPSDK
U-boot (when OEM open)
System Manager
When no ELE event is detected
SPSDK
U-boot (after OEM closure)
System Manager
11. Direct signing of the bootloader
It is also possible to directly add a signature to an existing unsigned bootloader binary using the SPSDK. In this case, SPSDK interprets the configuration from the bootloader binary container. While you cannot specify detailed settings for each image in a YAML file, you can create a signed bootloader by simply specifying the container header settings and the paths to the private and public keys.
11.1 Template Creation
(venv) $ nxpimage ahab get-template -f mimx9596 -o ahab_sign.yaml --sign
(venv) $ cp ahab_sign.yaml sign.yaml
11.2 YAML File
Specify the container header settings and the paths to the private and public keys in sign.yaml. If you are using the example YAML file , make a copy of direct_signing/sign.yaml.
11.3 Adding Signatures
The existing bootloader binary, flash.bin, will be signed.
// eMMC / SD
(venv) $ nxpimage ahab sign -c sign.yaml -b flash.bin -o output/flash_directsign.bin -fs output
// FlexSPI NOR
(venv) $ nxpimage ahab sign -c sign.yaml -b flash.bin -o output/flash_directsign.bin -fs output -m flexspi_nor
output/flash_directsign.bin and the SRKH eFuse programming scripts output/*.bcf This will be created.
In conclusion
This document describes the process of creating a signed image for i.MX 95 Secure Boot using the SPSDK and booting it, in order to protect the SoC boot image. This example demonstrates the procedure using PQC, a new feature added in i.MX 95 AHAB.
=========================
We are currently unable to respond to comments left in the "Comment" section of this post. We apologize for the inconvenience, but please refer to " Technical Questions to NXP - How to Contact Us( Japanese Blog) " when making an inquiry. (If you are already an NXP distributor or have a relationship with NXP, you may ask your representative directly.) This course provides hands-on instruction on creating and booting signed container images for secure booting on i.MX95 using the Secure Provisioning SDK (SPSDK) .
This document presents an example of implementing signature authentication using both Elliptic Curve Digital Signature Cryptography (ECDSA) and Post-Quantum Cryptography (PQC) ML-DSA in a Hybrid Boot environment.
(Estimated work time: half a day *Assuming that the Linux BSP build for i.MX 95 has already been completed once) i.MX Processors Security Japanese Blog
View full article