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.

1. Prerequisites#

  • 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

1.1 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-mkimage tool as flash singleboot binary

  • Obtain all the necessary binaries (lpddr4 firmware, u-boot, bl31, ELE firmware) and put them into inputs directory

1.2 U-Boot#

Read the U-Boot documentation to understand the U-Boot build process In order to use the nxpele app, U-Boot must be built with AHAB support. CONFIG_AHAB_BOOT=y If you want to use the nxpele over fastboot, also multiplexing of console output to fastboot must be enabled by setting CONFIG_CONSOLE_MUX=y.

1.3 Requirements#

Download these files from the https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/<package name> and put them into the inputs directory.

  • 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

  • i.MX93 EVK board

  • Four ECC keys (In this example we use ECC384). Might be created with nxpcrypto tool.

from spsdk.utils.jupyter_utils import YamlDiffWidget

# 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`.

2. AHAB Image#

The U-Boot image (flash.bin created by imx-mkimage) consists of two container sets - first container set is load to OCRAM using the SDPS protocol supported by ROM. The first container set contains U-Boot SPL binary, ELE firmware and firmware and training data for DDR controller. The second container set contains the full U-Boot and ATF image and is loaded to DDR by U-Boot SPL.

2.1 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 mimx9352 -o ahab_template.yaml

2.2 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 

2.3 U-Boot SPL image#

U-Boot SPL image contains ELE firmware (Optional), DDR firmware and training data, and U-Boot SPL binary. It is the first container set that is loaded to OCRAM by ROM using SDPS protocol. Let’s prepare the configuration from the template.

YamlDiffWidget("inputs/imx93_signed_ahab_uboot_spl.diffc").html
nxpimage ahab get-template -f mimx9352 -o workspace/ahab_template.yaml --force
Creating workspace/ahab_template.yaml template file.

Configuration Differences

2.4 U-Boot ATF Image#

The secondary container set contains the U-Boot and ATF images.

YamlDiffWidget("inputs/imx93_signed_ahab_uboot_atf.diffc").html
nxpimage ahab get-template -f mimx9352 -o workspace/ahab_template.yaml --force
Creating workspace/ahab_template.yaml template file.

Configuration Differences

3. AHAB Image Container 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 binary-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

We have to prepare the configuration. In configuration file we just specify the target memory (in our case we are downloading the image using the nxpuuu so serial downloader is enough).

YamlDiffWidget("inputs/imx93_signed_ahab_bimg.diffc").html
nxpimage bootable-image get-templates -f mimx9352 -o workspace --force
Creating workspace/bootimg_mimx9352_serial_downloader.yaml template file.
Creating workspace/bootimg_mimx9352_flexspi_nor.yaml template file.
Creating workspace/bootimg_mimx9352_emmc.yaml template file.
Creating workspace/bootimg_mimx9352_sd.yaml template file.
Creating workspace/bootimg_mimx9352_recovery_spi.yaml template file.

Configuration Differences

U_BOOT_FLASH_BOOT_CFG = "inputs/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 mimx9352
Starts:    0x0
Ends:      0x17b5ff
Size:      Size: 1.5 MiB; 1,553,920 B
Alignment: 1 B
Pattern:zeros
Memory type: MemoryType.SERIAL_DOWNLOADER
Revision: a1

INFO:spsdk.apps.nxpimage:Created Bootable Image memory map:

+==0x0000_0000= Bootable Image for mimx9352 =============+
|               Size: 1.5 MiB; 1,553,920 B               |
| Memory type: MemoryType.SERIAL_DOWNLOADER Revision: a1 |
|                     Pattern: zeros                     |
|+==0x0000_0000= primary_image_container_set ===========+|
||              Size: 330.5 kiB; 338,432 B              ||
||              AHAB Image for mimx9352_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 for ele core and 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 for cortex-a55 core and  |||
|||               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 mimx9352_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 for cortex-a55 core and  |||
|||               executable Image Type.               |||
||+==0x0005_e3ff=======================================+||
||+==0x0005_e400= U-Boot Firmware =====================+||
|||             Size: 1.1 MiB; 1,167,872 B             |||
||| AHAB encrypted data block for cortex-a55 core and  |||
|||               executable Image Type.               |||
||+==0x0017_b5ff=======================================+||
|+==0x0017_b5ff=========================================+|
+==0x0017_b5ff===========================================+

Success. (Bootable Image: outputs\signed-flash.bin created) 

4. 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:

Download Mode Cortex-A

%! nxpuuu $VERBOSITY write -f mimx9352 -b emmc $U_BOOT_FLASH_BOOT
nxpuuu -v write -f mimx9352 -b emmc outputs/signed-flash.bin 
SDPS: boot -f outputs/signed-flash.bin


Done

5. 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: mimx9352 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 mimx9352 batch outputs\signed-u-boot-atf-container_oem0_srk_hash_nxpele.bcf