i.MX 93 signed and encrypted AHAB image#
This notebook describes how to build a bootable signed and encrypted AHAB image with ELE firmware and U-BOOT bootloader.
Set up the environment#
SPSDK is needed with examples extension.
pip install spsdk[examples](Please refer to the installation documentation.)This demo was tested with i.MX93 EVK board
Images preparation#
to create resulting binary containing AHAB containers, we need to prepare the binaries
in this section we reproduce the process which is done by the
imx-mkimagetool
Requirements#
lpddr4 firmware files
u-boot binary (u-boot SPL and u-boot) built with AHAB support.
bl31.bin binary (ARM Trusted Firmware)
ELE firmware binary AHAB
Four ECC keys (In this example we use ECC384). Might be created with nxpcrypto tool.
# This env variable sets colored logger output to STDOUT
%env JUPYTER_SPSDK=1
%alias execute echo %l && %l
%alias_magic ! execute
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
AHAB Template#
We can generate the template using the nxpimage ahab get-template command. The command will generate a template. The template is a YAML file that contains the AHAB header and the AHAB container. The AHAB header contains the information about the image, such as the version, the number of containers, and the signature. The AHAB container contains the information about the image, such as the image type, the image version, the image size, and the image signature.
The following command generates the template:
nxpimage ahab get-template -f mx93 -o ahab_template.yaml
Exporting of the AHAB image#
The AHAB image can be exported using the nxpimage ahab export command. The command will create the AHAB image from the template. The following command creates the AHAB image:
nxpimage ahab export -c ahab_template.yaml
## Export AHAB Images
WORKSPACE = "workspace/" # change this to path to your workspace
U_BOOT_SPL_CONTAINER_CONFIG = "signed-u-boot-spl-container-img_config.yaml"
U_BOOT_ATF_CONTAINER_CONFIG = "signed-u-boot-atf-container-img_config.yaml"
VERBOSITY = "-v"
# EXPORT U-BOOT SPL CONTAINER IMAGE
%! nxpimage $VERBOSITY ahab export -c $U_BOOT_SPL_CONTAINER_CONFIG
nxpimage -v ahab export -c signed-u-boot-spl-container-img_config.yaml
INFO:spsdk.image.ahab.ahab_iae:Adding DDR memory areas into SPL image
INFO:spsdk.apps.nxpimage:Created AHAB Image:
Name: AHAB Image
Starts: 0x0
Ends: 0x529ff
Size: Size: 330.5 kiB; 338,432 B
Alignment: 8 B
Pattern:zeros
AHAB Image for mx93_a1
INFO:spsdk.apps.nxpimage:Created AHAB Image memory map:
+==0x0000_0000= AHAB Image ============================+
| Size: 330.5 kiB; 338,432 B |
| AHAB Image for mx93_a1 |
| Pattern: zeros |
|+==0x0000_0000= AHAB Containers =====================+|
|| Size: 8.0 kiB; 8,192 B ||
|| AHAB Containers block ||
|| Pattern: zeros ||
||+==0x0000_0000= AHAB Container 0 ==================+||
||| Size: 544 B |||
||| AHAB Container for nxp_SWver:0 |||
||+==0x0000_021f=====================================+||
|| Gap: 480 B ||
||+==0x0000_0400= AHAB Container 1 ==================+||
||| Size: 776 B |||
||| AHAB Container for oem_SWver:0 |||
||+==0x0000_0707=====================================+||
|+==0x0000_1fff=======================================+|
|+==0x0000_2000= Container 0 AHAB Data Image 0 =======+|
|| Size: 95.8 kiB; 98,144 B ||
|| AHAB encrypted data block with ele Image Type. ||
|+==0x0001_9f5f=======================================+|
| Gap: 160 B |
|+==0x0001_a000= U-Boot SPL with DDR tunning images ==+|
|| Size: 226.5 kiB; 231,936 B ||
|| AHAB encrypted data block with executable Image ||
|| Type. ||
|+==0x0005_29ff=======================================+|
+==0x0005_29ff=========================================+
Success. (AHAB: outputs/signed-u-boot-spl-container.img created.)
Generated file containing SRK hash: outputs/signed-u-boot-spl-container_oem1_srk_hash.txt
INFO:spsdk.image.ahab.utils:
Fuses info:
--== Grouped register name: SRKH ==--
OTP ID: 128, Value: 0x9102e77
OTP ID: 129, Value: 0xd52d6dc6
OTP ID: 130, Value: 0xc65db27a
OTP ID: 131, Value: 0xb60904a2
OTP ID: 132, Value: 0x63646786
OTP ID: 133, Value: 0x547e3e98
OTP ID: 134, Value: 0x5be524cf
OTP ID: 135, Value: 0x374f6438
Generated script for writing fuses for container 1: outputs/signed-u-boot-spl-container_oem1_srk_hash_nxpele.bcf
# EXPORT U-BOOT ATF CONTAINER IMAGE
%! nxpimage $VERBOSITY ahab export -c $U_BOOT_ATF_CONTAINER_CONFIG
nxpimage -v ahab export -c signed-u-boot-atf-container-img_config.yaml
INFO:spsdk.apps.nxpimage:Created AHAB Image:
Name: AHAB Image
Starts: 0x0
Ends: 0x1289ff
Size: Size: 1.2 MiB; 1,214,976 B
Alignment: 8 B
Pattern:zeros
AHAB Image for mx93_a1
INFO:spsdk.apps.nxpimage:Created AHAB Image memory map:
+==0x0000_0000= AHAB Image ====================+
| Size: 1.2 MiB; 1,214,976 B |
| AHAB Image for mx93_a1 |
| Pattern: zeros |
|+==0x0000_0000= AHAB Containers =============+|
|| Size: 8.0 kiB; 8,192 B ||
|| AHAB Containers block ||
|| Pattern: zeros ||
||+==0x0000_0000= AHAB Container 0 ==========+||
||| Size: 904 B |||
||| AHAB Container for oem_SWver:0 |||
||+==0x0000_0387=============================+||
|+==0x0000_1fff===============================+|
|+==0x0000_2000= ATF - ARM Trusted Firmware ==+|
|| Size: 38.0 kiB; 38,912 B ||
|| AHAB encrypted data block with executable ||
|| Image Type. ||
|+==0x0000_b7ff===============================+|
|+==0x0000_b800= U-Boot Firmware =============+|
|| Size: 1.1 MiB; 1,167,872 B ||
|| AHAB encrypted data block with executable ||
|| Image Type. ||
|+==0x0012_89ff===============================+|
+==0x0012_89ff=================================+
Success. (AHAB: outputs/signed-u-boot-atf-container.img created.)
Generated file containing SRK hash: outputs/signed-u-boot-atf-container_oem0_srk_hash.txt
INFO:spsdk.image.ahab.utils:
Fuses info:
--== Grouped register name: SRKH ==--
OTP ID: 128, Value: 0x9102e77
OTP ID: 129, Value: 0xd52d6dc6
OTP ID: 130, Value: 0xc65db27a
OTP ID: 131, Value: 0xb60904a2
OTP ID: 132, Value: 0x63646786
OTP ID: 133, Value: 0x547e3e98
OTP ID: 134, Value: 0x5be524cf
OTP ID: 135, Value: 0x374f6438
Generated script for writing fuses for container 0: outputs/signed-u-boot-atf-container_oem0_srk_hash_nxpele.bcf
AHAB Image set#
Now we have the AHAB image with U-Boot SPL DDR and AHAB Image with U-Boot ATF container. We can use the nxpimage bootable-image merge command to merge the AHAB images into one binary image. The following command merges the AHAB images:
nxpimage -v bootable-image merge -c u-boot-flash_template.yaml -o flash.bin
U_BOOT_FLASH_BOOT_CFG = "signed-u-boot-bootable.yaml"
U_BOOT_FLASH_BOOT = "outputs/signed-flash.bin"
%! nxpimage -v bootable-image merge --config $U_BOOT_FLASH_BOOT_CFG --output $U_BOOT_FLASH_BOOT
nxpimage -v bootable-image merge --config signed-u-boot-bootable.yaml --output outputs/signed-flash.bin
INFO:spsdk.image.ahab.ahab_iae:Adding DDR memory areas into SPL image
INFO:spsdk.apps.nxpimage:Created Bootable Image:
Name: Bootable Image for mx93
Starts: 0x0
Ends: 0x17b5ff
Size: Size: 1.5 MiB; 1,553,920 B
Alignment: 1 B
Pattern:zeros
Memory type: serial_downloader
Revision: a1
INFO:spsdk.apps.nxpimage:Created Bootable Image memory map:
+==0x0000_0000= Bootable Image for mx93 =================+
| Size: 1.5 MiB; 1,553,920 B |
| Memory type: serial_downloader Revision: a1 |
| Pattern: zeros |
|+==0x0000_0000= primary_image_container_set ===========+|
|| Size: 330.5 kiB; 338,432 B ||
|| AHAB Image for mx93_a1 ||
|| Pattern: zeros ||
||+==0x0000_0000= AHAB Containers =====================+||
||| Size: 8.0 kiB; 8,192 B |||
||| AHAB Containers block |||
||| Pattern: zeros |||
|||+==0x0000_0000= AHAB Container 0 ==================+|||
|||| Size: 544 B ||||
|||| AHAB Container for nxp_SWver:0 ||||
|||+==0x0000_021f=====================================+|||
||| Gap: 480 B |||
|||+==0x0000_0400= AHAB Container 1 ==================+|||
|||| Size: 776 B ||||
|||| AHAB Container for oem_SWver:0 ||||
|||+==0x0000_0707=====================================+|||
||+==0x0000_1fff=======================================+||
||+==0x0000_2000= Container 0 AHAB Data Image 0 =======+||
||| Size: 95.8 kiB; 98,144 B |||
||| AHAB encrypted data block with ele Image Type. |||
||+==0x0001_9f5f=======================================+||
|| Gap: 160 B ||
||+==0x0001_a000= U-Boot SPL with DDR tunning images ==+||
||| Size: 226.5 kiB; 231,936 B |||
||| AHAB encrypted data block with executable Image |||
||| Type. |||
||+==0x0005_29ff=======================================+||
|+==0x0005_29ff=========================================+|
| Gap: 512 B |
|+==0x0005_2c00= secondary_image_container_set =========+|
|| Size: 1.2 MiB; 1,214,976 B ||
|| AHAB Image for mx93_a1 ||
|| Pattern: zeros ||
||+==0x0005_2c00= AHAB Containers =====================+||
||| Size: 8.0 kiB; 8,192 B |||
||| AHAB Containers block |||
||| Pattern: zeros |||
|||+==0x0005_2c00= AHAB Container 0 ==================+|||
|||| Size: 904 B ||||
|||| AHAB Container for oem_SWver:0 ||||
|||+==0x0005_2f87=====================================+|||
||+==0x0005_4bff=======================================+||
||+==0x0005_4c00= ATF - ARM Trusted Firmware ==========+||
||| Size: 38.0 kiB; 38,912 B |||
||| AHAB encrypted data block with executable Image |||
||| Type. |||
||+==0x0005_e3ff=======================================+||
||+==0x0005_e400= U-Boot Firmware =====================+||
||| Size: 1.1 MiB; 1,167,872 B |||
||| AHAB encrypted data block with executable Image |||
||| Type. |||
||+==0x0017_b5ff=======================================+||
|+==0x0017_b5ff=========================================+|
+==0x0017_b5ff===========================================+
Success. (Bootable Image: outputs/signed-flash.bin created)
Image download#
First we put the iMX93 into serial downloader mode for Cortex-A (0011), and use uuu to upload the flash.bin containing U-Boot and other firmware.
The picture below shows the desired DIP switch configuration for flashing Cortex-A:

%! uuu -b emmc outputs/flash.bin
Writing Fuses#
We need to write SRKH (Super root key hash) to fuses. This might be done using the NXPELE tool. When the signed AHAB Image is exported, the “.bcf” script is generated.
The script might look like this
# nxpele AHAB SRK fuses programming script
# Family: mx93 Revision: a1
# Value: 0x772e1009c66d2dd57ab25dc6a20409b686676463983e7e54cf24e55b38644f37
# Description: SHA256 hash digest of hash of four SRK keys
# Grouped register name: SRKH
# OTP ID: 128, Value: 0x9102e77
write-fuse --index 128 --data 0x09102E77
# OTP ID: 129, Value: 0xd52d6dc6
write-fuse --index 129 --data 0xD52D6DC6
# OTP ID: 130, Value: 0xc65db27a
write-fuse --index 130 --data 0xC65DB27A
# OTP ID: 131, Value: 0xb60904a2
write-fuse --index 131 --data 0xB60904A2
# OTP ID: 132, Value: 0x63646786
write-fuse --index 132 --data 0x63646786
# OTP ID: 133, Value: 0x547e3e98
write-fuse --index 133 --data 0x547E3E98
# OTP ID: 134, Value: 0x5be524cf
write-fuse --index 134 --data 0x5BE524CF
# OTP ID: 135, Value: 0x374f6438
write-fuse --index 135 --data 0x374F6438
The script might be executed using nxpele batch mode
nxpele -v -f mx93 -p COM100 batch outputs\signed-u-boot-atf-container_oem0_srk_hash_nxpele.bcf