i.MX8 Advanced High Assurance Boot (AHAB) / Secure Boot¶
HAB introduction¶
HAB is an optional feature in the i.MX SOC family, which allows you to make sure only software images signed by you can be executed on the SOC.
It incorporates boot ROM level security which cannot be altered after programming the appropriate one-time electrically programmable fuses (eFuses). The boot ROM is responsible for loading the initial software image from the boot medium (usually this initial software is a bootloader such as SPL/U-Boot. HAB enables the boot ROM to authenticate the initial software image by using digital signatures. It also provides a mechanism to establish a chain of trust for the remaining software components (such as the kernel image) and thus to establish a secure state of the system.
HAB authentication is based on public key cryptography using the RSA/ECDSA algorithm. It consists of the following stages:
-
Offline signing of the software images using private keys. The image data is signed offline using a series of private keys. This is done using NXP's Code Signing Tool, and Variscite's scripts, which make the process extremely easy and simple.
-
Fusing the i.MX SOC with the corresponding public keys. The key structure is called a PKI tree and Super Root Keys (SRK) are components of it. A table of the public SRKs are hashed and permanently written to the SOC using eFuses. You have the option to let the processor keep running unsigned images, while creating useful HAB messages, until you decide to “close” it by writing a dedicated bit using another eFuse. This allows you to test the sign-authenticate process and verify that it was done correctly before completely and permanently “closing” the processor to only execute your signed images.
-
Authentication of the software images on the target during boot time. The signed image data is verified on the i.MX processor using the corresponding public keys. HAB evaluates the SRK table included in the signature by hashing it and comparing the result to the SRK fuse values. If the SRK verification is successful, this establishes the root of trust, and the remainder of the signature can be processed to authenticate the image.
Once the initial bootloader is authenticated and executed, the chain of trust continues by authenticating each of the next loaded images before executing them. E.g. The boot ROM authenticates SPL, SPL authenticates U-Boot, and U-Boot authenticates the Linux kernel.
References¶
- i.MX Applications Processor Trust Architecture
- i.MX Secure Boot on HABv4 Supported Devices
- i.MX 6 Linux High Assurance Boot (HAB) User's Guide
Code signing step by step instructions¶
NXP Provides documentation for enabling AHAB for the i.MX 8 Family. The information in this wiki is derived from NXP's documentation.
The U-Boot source code provides a directory with documentation and examples: https://github.com/varigit/uboot-imx/blob/imx_v2020.04_5.4.70_2.3.2_var01/doc/imx/ahab/
The following documentation is helpful to review:
Please continue reading below to learn how Variscite's Yocto layer simplifies this process.
Code signing using Yocto¶
Introduction to meta-variscite-hab¶
Variscite provides a Yocto layer to simplify signing the imx-boot and Linux images and generate a fully signed recovery SD card image. meta-variscite-hab requires two inputs:
- NXP Code Signing Tool
-
NXP proprietary tool for signing images. Users must download this tool from NXP and provide an absolute path to meta-variscite-hab.
- Private Keys
-
Users must generate private keys and provide an absolute path or git repository to meta-variscite-hab.
meta-variscite-hab extends the imx-boot, uboot-variscite, and linux-variscite recipes to sign the imx-boot and Linux images using the NXP Code Signing Tool and private keys.
The general process for creating a signed image using meta-variscite-hab is:
- Follow the Build Yocto from source code guide to setup a build environment
- Download NXP Code Signing Tool (CST)
- Use CST to generate Public Key Infrastructure (PKI) tree (one time)
- Configure local.conf, machine.conf, or variscite.inc
- Enable hab machine override
- Provide git repository for private keys
- Provide certificate serial and passkeys
- Provide U-Boot and kernel device tree names
- Build a signed SD card image
- Program a recovery SD card
- Program SOC e-fuses
- Boot recovery SD card and interrupt U-Boot
- U-Boot: Program the SRK (public keys) to the SOC e-fuses
- U-Boot: Verify public keys and signed image by running ahab_status
- U-Boot: Secure (Close) the device
The remainder of the guide walks through this process.
Walkthrough: Setup a build environment¶
This section assumes familiarity with building Yocto. For more information, please follow the Build Yocto from source code guide.
Download the latest revision:
mkdir ~/var-fsl-yocto && cd ~/var-fsl-yocto
repo init -u https://github.com/varigit/variscite-bsp-platform -b scarthgap -m imx-6.6.52-2.2.0.xml
repo sync -j4
Setup environment to build XWayland GUI demo image
cd ~/var-fsl-yocto
MACHINE=imx8qxp-var-som DISTRO=fsl-imx-xwayland . var-setup-release.sh build_xwayland
Or, to build for i.MXQXP SOC revision B0:
cd ~/var-fsl-yocto
MACHINE=imx8qxpb0-var-som DISTRO=fsl-imx-xwayland . var-setup-release.sh build_xwayland
Walkthrough: Download NXP Code Signing Tool (CST)¶
Download the Freescale Code Signing Tool (CST) for the High Assurance Boot (HAB) library from the NXP website (registration required): https://www.nxp.com/webapp/sps/download/license.jsp?colCode=IMX_CST_TOOL
Unpack the downloaded archive:
mkdir ~/cst-3.1.0/ && cd ~/cst-3.1.0/
tar xf ~/Downloads/cst-3.1.0.tar.gz
mv release/* . && rm -r release
You are encouraged to read the documents under ~/cst-3.1.0/docs
Walkthrough: Generate Public Key Infrastructure (PKI) tree¶
Create a text file called "serial", which contains 8 digits. It will be used for the certificate serial numbers. For example:
Create a text file called "key_pass.txt", which contains two lines of a password repeated twice. This password will be used to protect the generated private keys. All private keys in the PKI tree are in PKCS #8 format will be protected by the same password. For example:
Now, to generate the PKI tree, run the following:
And complete the interactive questions. For example:
Do you want to use an existing CA key (y/n)?: n
Do you want to use Elliptic Curve Cryptography (y/n)?: n
Enter key length in bits for PKI tree: 4096
Enter the digest algorithm to use: sha384
Enter PKI tree duration (years): 20
Do you want the SRK certificates to have the CA flag set? (y/n)?: n
Generate Super Root Key (SRK) table
cd ../crts/
../linux64/bin/srktool -a -s sha384 -t SRK1234table.bin -e SRK1234fuse.bin -f 1 -c SRK1_sha384_4096_65537_v3_usr_crt.pem,SRK2_sha384_4096_65537_v3_usr_crt.pem,SRK3_sha384_4096_65537_v3_usr_crt.pem,SRK4_sha384_4096_65537_v3_usr_crt.pem
ll SRK1234*
-rw-rw-r-- 1 nate nate 64 Sep 15 14:47 SRK1234fuse.bin
-rw-rw-r-- 1 nate nate 2112 Sep 15 14:47 SRK1234table.bin
Next, add the contents of the './crts' and './keys' to a git repository matching 'CST_CERTS_URI' (defined below) in local.conf. Make sure to remove './keys/serial' and './keys/key_pass.txt'. See Variscite's repository for an example: https://github.com/varigit/var-hab-certs
Note: Instead of using a git repository, you may configure CST_CERTS_URI to fetch an archive or any other Yocto compatible URL.
Walkthrough: Configure local.conf, machine.conf, or variscite.inc¶
There are several variables that need to be configured in conf/local.conf, ../sources/meta-variscite-bsp-imx/conf/machine/imx8qxp-var-som.conf, or ../sources/meta-variscite-bsp-imx/conf/machine/variscite.inc (use whichever file you prefer):
| Variable | Description |
|---|---|
| OVERRIDES =. "ahab:" | Machine override used to enable Variscite HAB functions in meta-variscite-hab |
| CST_CERTS_URI |
SRC_URI definition for cloning certificates repository. Below is the default configuration for Variscite's example
var-hab-certs
repository:
|
| CST_CERTS_REV |
Git commit ID for CST_CERTS_URI. Below is the default definition (commit ID may change):
|
| CST_SERIAL | Certificate serial number from previous step |
| CST_KEYPASS | Key password from previous step |
| UBOOT_DTB_DEFAULT |
The imx-boot images contain a FIT image with one or more U-Boot device tree files. Currently, signed imx-boot images can contain only a single device tree file. Select the U-Boot device tree file to sign:
|
| KERNEL_DTB_DEFAULT |
Required for i.MX 8 X Family
Like imx-boot, currently only a single Linux device tree can be signed. Below is an example of how to perform this signing:
|
To get started using Variscite's default configuration and keys (not recommended for production), add the following to local.conf:
local.conf
…
# Enable Variscite HAB machine override
OVERRIDES =. "ahab:"
# Select the U-Boot device tree file to sign
UBOOT_DTB_DEFAULT = "imx8qxp-var-som-symphony.dtb"
# Select the kernel device tree file for VAR-SOM-MX8X on Symphony-Board to sign:
KERNEL_DTB_DEFAULT = "imx8qxp-var-som-symphony-sd.dtb"
…
You may override any of Variscite's default variables, see below for an example local.conf for the imx8qxp-var-som:
local.conf
…
# Enable Variscite HAB machine override
OVERRIDES =. "ahab:"
# Select the U-Boot device tree file to sign
UBOOT_DTB_DEFAULT = "imx8qxp-var-som-symphony.dtb"
# Select the kernel device tree file for VAR-SOM-MX8X on Symphony-Board to sign:
KERNEL_DTB_DEFAULT = "imx8qxp-var-som-symphony-sd.dtb"
GIT Repository for private certificates
# Note: The `CST_CERTS_REV` and `CST_CERTS_URI` variables are used by the `var-hab-certs`
recipe to provide the repository containing the certificates needed for U-Boot signing. By default, the `var-hab-certs`
repository from Variscite is used. To add your own repository and use your keys, simply modify these variables:
CST_CERTS_REV = "56ad83a9962fb1cd8b4a18dc72993de7e7894bc5"
CST_CERTS_URI = "git://github.com/varigit/var-hab-certs.git;protocol=https;branch=master;rev=${CST_CERTS_REV}"
# Configure certificate serial and passwords (These should be secret)
CST_SERIAL = "1248163E"
CST_KEYPASS = "Variscite_password"
…
Walkthrough: Build a signed SD card image¶
To be safe, clean all relevant recipes:
bitbake -c cleansstate linux-variscite
bitbake -c cleansstate u-boot-variscite
bitbake -c cleansstate imx-boot
bitbake -c cleansstate var-hab-certs
bitbake -c cleansstate var-cst-signer
bitbake -c cleansstate os-cntr-sign
bitbake -c cleansstate fsl-image-gui
# Or combined into a single command:
bitbake -c cleansstate linux-variscite u-boot-variscite imx-boot var-hab-certs var-cst-signer os-cntr-sign fsl-image-gui
Build a signed image:
Create a recovery SD card:
cd ~/var-fsl-yocto
sudo MACHINE=imx8qxp-var-som sources/meta-variscite-sdk-imx/scripts/var_mk_yocto_sdcard/var-create-yocto-sdcard.sh <options> /dev/sdX
(Replace /dev/sdX with your actual device)
Walkthrough: Program the SRK (public keys) to the SOC e-fuses¶
Boot the board, hit any key at the right time to stop autoboot and get to the U-Boot command line, and run the commands outputted by the above script. The commands should look similar to the following.
Important notes:
- The following values are just an example - you should use your own values!
- These are One-Time Programmable e-fuses. Once you write them you can't go back, so get it right the first time.
- Do not run the command at the end of the script to close the device. We will do that later.
SRK1234fuse.bin.u-boot-cmds:
cat build_xwayland/tmp/deploy/images/imx8qxp-var-som/SRK1234fuse.bin.u-boot-cmds
# Note: These are One-Time Programmable e-fuses. Once you write them you can't go back, so get it right the first time.
fuse prog -y 0 730 0xC7CD8343
fuse prog -y 0 731 0x9DAD444
fuse prog -y 0 732 0xCA69438A
fuse prog -y 0 733 0xF58BCA5A
fuse prog -y 0 734 0xD9B0C333
fuse prog -y 0 735 0xFB085CFC
fuse prog -y 0 736 0xAC6977BD
fuse prog -y 0 737 0x547DD584
fuse prog -y 0 738 0xD7D99422
fuse prog -y 0 739 0x8DD76A21
fuse prog -y 0 740 0xA4BFC709
fuse prog -y 0 741 0x176D4CB9
fuse prog -y 0 742 0x29432F99
fuse prog -y 0 743 0xF5DA795E
fuse prog -y 0 744 0xD7A20D12
fuse prog -y 0 745 0x73CA2F0C
fuse read 0 730 16
Reading bank 0:
Word 0x000002da: c7cd8343 09dad444 ca69438a f58bca5a
Word 0x000002de: d9b0c333 fb085cfc ac6977bd 547dd584
Word 0x000002e2: d7d99422 8dd76a21 a4bfc709 176d4cb9
Word 0x000002e6: 29432f99 f5da795e d7a20d12 73ca2f0c
# After the device successfully boots a signed image without generating any HAB events, it is safe to secure, or 'close', the device.
# This is the last step in the process. Once the fuse is blown, the chip does not load an image that has not been signed using the correct PKI tree.
# Important notes:
# - This is again a One-Time Programmable e-fuse. Once you write it you can't go back, so get it right the first time.
# - If anything in the previous steps wasn't done correctly, the SOM will not boot after writing this bit.
ahab_close
Walkthrough: Verify AHAB successfully authenticates the signed image¶
AHAB generates events when processing the commands if it encounters issues. The U-Boot "ahab_status" command displays any events that were generated. Run it at the U-Boot command line:
If everything is okay you should get the following output:
Note: You will receive SECO events if you have not programmed the SRK (public keys) to the SOC e-fuses.
Warning: Make sure there are not events before proceeding to the next step.
Walkthrough: Secure the device¶
After the device successfully boots a signed image without generating any AHAB events, it is safe to secure, or "close", the device. This is the last step in the process, and is completed by blowing the SEC_CONFIG[1] fuse bit. Once the fuse is blown, the chip does not load an image that has not been signed using the correct PKI tree.
Important notes:
- This is again a One-Time Programmable e-fuse. Once you write it you can't go back, so get it right the first time.
- If anything in the previous steps wasn't done correctly, the SOM will not boot after writing this bit.
Next Steps¶
This guide demonstrates how to build and boot a signed image. However, it does not cover every aspect of securing a device.
For more information, refer to NXP's documentation.

