Secure boot conga-SMX8-Plus
Secure boot i.MX8MP
Disclaimer
The information contained within this document, including but not limited to any product specification, is subject to change without notice. congatec provides no warranty with regard to this document or an other information contained herein and hereby expressly disclaims any implied warranties of merchantability or fitness for any particular purpose with regard to any of the foregoing. congatec assumes no liability for any damages incurred directly or indirectly from any technical or typographical errors or omissions contained herein or for discrepancies between the product and this document. In no event shall congatec be liable for any incidental consequential, special, or exemplary damages, whether based on tort, contract or otherwise, arising out of or in connection with this document or any other information contained herein or the use thereof.
Prerequisites
Code Signing Tools (CST) 3.3.2
Account required on NXP website
https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL_NEW
U-Boot source code
cgtbcbe
1. HABv4 secure boot process
This document describes a step-by-step procedure on how to sign and securely boot a bootloader image on i.MX8M family devices. It is assumed that the reader is familiar with basic HAB concepts and with the PKI tree generation.
Details about HAB can be found in the application note AN4581[1] and in the introduction_habv4.txt document.
1.1. Understanding the i.MX8M family flash.bin image layout
Due to the new the architecture, multiple firmwares and softwares are required to boot i.MX8M family devices. In order to store all the images in a single binary the FIT (Flattened Image Tree) image structure is used.
The final image is generated by the imx-mkimage project, the tool combines all the input images in a FIT structure, generating a flash.bin image with an appropriate IVT set.
For a secure boot process users should ensure all images included in flash.bin file are covered by a digital signature.
The diagram below illustrate a signed flash.bin image layout:
+-----------------------------+
| |
| *Signed HDMI/DP FW |
| |
+-----------------------------+
| Padding |
------- +-----------------------------+ --------
^ | IVT - SPL | ^
Signed | +-----------------------------+ |
Data | | u-boot-spl.bin | |
| | + | | SPL
v | DDR FW | | Image
------- +-----------------------------+ |
| CSF - SPL + DDR FW | v
+-----------------------------+ --------
| Padding |
------- +-----------------------------+ --------
Signed ^ | FDT - FIT | ^
Data | +-----------------------------+ |
v | IVT - FIT | |
------- +-----------------------------+ |
| CSF - FIT | |
------- +-----------------------------+ | FIT
^ | u-boot-nodtb.bin | | Image
| +-----------------------------+ |
Signed | | OP-TEE (Optional) | |
Data | +-----------------------------+ |
| | bl31.bin (ATF) | |
| +-----------------------------+ |
v | u-boot.dtb | v
------- +-----------------------------+ --------
i.MX8M boot flow:
Secure World Non-Secure World
|
|
+------------+ +------------+ |
| SPL | | i.MX 8M | |
| + | ---> | ROM | |
| DDR FW | | + HAB | |
+------------+ +------------+ |
| |
v |
+------------+ |
| *Signed | |
| HDMI/DP FW | |
+------------+ |
| |
v |
+------------+ +------------+ |
| FIT Image: | | SPL | |
| ATF + TEE | ---> | + | |
| + U-Boot | | DDR FW | | +-----------+
+------------+ +------------+ | | Linux |
| | +-----------+
v | ^
+------------+ | | +-------+
| ARM | | +-----------+ | Linux |
| Trusted | ----+---> | U-Boot | <--- | + |
| Firmware | | +-----------+ | DTB |
+------------+ | +-------+
| |
v |
+----------+ |
| **OP-TEE | |
+----------+ |
Particularly on the i.MX8M, the HDMI firmware or DisplayPort firmware are the first image to boot on the device. These firmwares are signed and distributed by NXP, and are always authenticated regardless of security configuration. In case not required by the application the HDMI or DisplayPort controllers can be disabled by eFuses and the firmwares are not required anymore.
The next images are not signed by NXP and users should follow the signing procedure as described in this document.
The Second Program Loader (SPL) and DDR firmware are loaded and authenticated by the ROM code, these images are executed in the internal RAM and responsible for initializing essential features such as DDR, UART, PMIC and clock enablement.
Once the DDR is available, the SPL code loads all the images included in the FIT structure to their specific execution addresses, the HAB APIs are called to extend the root of trust, authenticating the U-Boot, ARM trusted firmware (ATF) and OP-TEE (If included).
The root of trust can be extended again at U-Boot level to authenticate Kernel and M4 images.
1.2 Enabling the secure boot support in U-Boot
The first step is to generate an U-Boot image supporting the HAB features, similar to i.MX6 and i.MX7 series the U-Boot provides extra functions for HAB, such as the HAB status logs retrievement through the hab_status command and support to extend the root of trust.
The support is enabled by adding the CONFIG_IMX_HAB to the build configuration:
Defconfig:
CONFIG_IMX_HAB=y
Kconfig:
ARM architecture -> Support i.MX HAB features
The U-Boot image must then be recompiled after these changes are made.
1.3 Preparing the fit image
The cgtbcbe project is used to combines all the images in a single flash.bin binary, the following files are required:
u-boot-spl.bin
u-boot.dtb
imx8mp-cgtqx8p.dtb
u-boot-nodtb.bin
The procedure to build ATF and download the firmwares are out of the scope of this document.
Copy all files to iMX8M directory and run the following command according to the target device, on this example we are building a SPI target and also including the OP-TEE binary, set the configuration for the conga-QMX8-Plus:
$ ./mkbcbe.sh -b BUILD_QX8P_FSPI -c mx8mp/config/cgtqx8p-A3-2GB4GB_BSP-5.15.32_2.0.0_rel_cgtqx8p_23-02-23-0.inc.sh
Some files are referred with symlinks, that would lead into issues calculating the offset of those files, therefore runing the following commands we fix that
Build the flash.bin:
Build log:
Additional HAB information is provided by running the following command:
1.4 Preparing the private keys and certificates
The tool is not provided with any keys. Therefore, the keys required for signing have to be prepared according User guide (CST_UG.pdf), section 3.2 “Generating AHAB Keys and Certificates”.
Follow the procedure below to create keys and certificates suitable to sign code for AHAB.
The example defines “123456A4” as serial, “Congatec!” as password and elliptic curve cryptography with 256bit key size - specify these values according your requirements.
If everything went correctly, a bunch of keys and certificates has been created. All key and certificate information required for signing an image for AHAB is now available.
1.4.1 Creating SRK tables and efuse hashes
In the next step the AHAB SRK table and corresponding hash values for burning into the efuses on the SOC are created. The SRK table is a collection of the public keys created in the previous step that will be embedded in the image when it is signed. Once signed, the authenticity of the image can be assured using the signature, the embedded SRK table and the hash values programmed onto the SOC.
The SRK table (SRK_1_2_3_4_table.bin) and hashes (SRK_1_2_3_4_fuse.bin) are created with the srktool:
1.5 Creating the CSF description file
The CSF contains all the commands that the ROM executes during the secure boot. These commands instruct the HAB code on which memory areas of the image to authenticate, which keys to install, use and etc. More information on constructing a CSF file can be found in the CST User Guide, located within the CST package's doc directory.
Key and Certificate generation done by the CST is out of the scope of this document. Please refer to introduction_habv4.txt for keys, certificates, SRK table, and SRK hash generation. The resulting file locations should be inserted into the CSF files like this:
Insertion into both csf_spl.txt and csf_fit.txt
CSF examples are available under doc/imx/hab/habv4/csf_examples/ directory.
As explained in sections above the SPL is first authenticated by the ROM code and the root of trust is extended to the FIT image, hence two CSF files are necessary to completely sign an flash.bin image.
The build log provided by imx-mkimage can be used to define the "Authenticate Data" parameter in CSF. The addresses supplied in the build log will be needed again for binary insertion.
SPL "Authenticate Data" addresses in flash.bin build log:
"Authenticate Data" command in csf_spl.txt file:
FIT image "Authenticate Data" addresses in flash.bin build log:
FIT image "Authenticate Data" addresses in print_fit_hab build log:
"Authenticate Data" command in csf_fit.txt file:
1.5.1 Avoiding Kernel crash in closed devices
For devices prior to HAB v4.4.0, the HAB code locks the Job Ring and DECO master ID registers in closed configuration. In case the user specific application requires any changes in CAAM MID registers it's necessary to add the "Unlock CAAM MID" command in CSF file.
The current NXP BSP implementation expects the CAAM registers to be unlocked when configuring CAAM to operate in non-secure TrustZone world.
The Unlock command is already included by default in the signed HDMI and DisplayPort firmwares. On i.MX8MM, i.MX8MN and i.MX8MP devices or in case the HDMI or DisplayPort controllers are disabled in i.MX8M, users must ensure this command is included in SPL CSF.
Add Unlock MID command in csf_spl.txt:
1.6 Signing the flash.bin binary
The CST tool is used for singing the flash.bin image and generating the CSF binary. Users should input the CSF description file created in the step above and receive a CSF binary, which contains the CSF commands, SRK table, signatures and certificates.
Create SPL CSF binary file:
Create FIT CSF binary file:
1.7 Assembling the CSF in flash.bin binary
The CSF binaries generated in the step above have to be inserted into the flash.bin image.
The CSF offsets can be obtained from the flash.bin build log:
SPL CSF offset:
csf_off 0x36000
FIT CSF offset:
sld_csf_off 0x61020
The signed flash.bin image can be then assembled:
Create a flash.bin copy:
Insert csf_spl.bin in signed_flash.bin at 0x36000 offset:
Insert csf_fit.bin in signed_flash.bin at 0x61020 offset:
Flash signed_flash.bin using the UUU tool
1.8 Programming SRK Hash
As explained in AN4581[1] and in introduction_habv4.txt document the SRK Hash fuse values are generated by the srktool and should be programmed in the SoC SRK_HASH[255:0] fuses.
Be careful when programming these values, as this data is the basis for the root of trust. An error in SRK Hash results in a part that does not boot. More information and full details regarding fuses can be found in the Security Reference Manual of the target board. Contact an NXP Representative for access.
The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs.
Dump SRK Hash fuses values in host machine:
Program SRK_HASH[255:0] fuses on i.MX8M family devices at U-boot level:
1.9 Verifying HAB events
The next step is to verify that the signatures included in flash.bin image is successfully processed without errors. HAB generates events when processing the commands if it encounters issues.
The hab_status U-Boot command call the hab_report_event() and hab_status() HAB API functions to verify the processor security configuration and status. This command displays any events that were generated during the process.
Prior to closing the device users should ensure no HAB events were found, as
the example below:
Verify HAB events:
1.10 Closing the device
After the device successfully boots a signed image without generating any HAB events, it is safe to close the device. This is the last step in the HAB process, and is achieved by programming the SEC_CONFIG[1] fuse bit.
Once the fuse is programmed, the chip does not load an image that has not been signed using the correct PKI tree.
Program SEC_CONFIG[1] fuse on i.MX8M family devices:
2. Authenticating additional boot images
The High Assurance Boot (HAB) code located in the on-chip ROM provides an Application Programming Interface (API) making it possible to call back into the HAB code for authenticating additional boot images.
The U-Boot is running in non-secure TrustZone world and to make use of this feature it's necessary to use a SIP call to the ATF, this is already implemented in hab.c code and it's transparent to the user.
The process of signing an additional image is similar as in i.MX6 and i.MX7 series devices, the steps below are using the Linux Kernel image as example.
The diagram below illustrate the Image layout:
2.1 Padding the image
The Image must be padded to the size specified in the Image header, this can be achieved by using the od command.
Read Image size:
The tool objcopy can be used for padding the image.
Pad the Image:
2.2 Generating Image Vector Table
The HAB code requires an Image Vector Table (IVT) for determining the image length and the CSF location. Since Image does not include an IVT this has to be manually created and appended to the end of the padded Image, the script genIVT.pl should be created with this content:
Getting the offsets:
CSF_Offset (Image_size + 0x20)
Load_address, under U-boot run:
IVT_address (Load_address + Image_size) 0x40400000 + 0x01e10000
CSF_address (IVT_address + 0x20)
Generate IVT:
Note: The load Address may change depending on the device.
Append the ivt.bin at the end of the padded Image:
2.3 Signing the image
A CSF file has to be created to sign the image. HAB does not allow to change the SRK once the first image is authenticated, so the same SRK key used in the initial image must be used when extending the root of trust.
CSF examples are available in ../csf_examples/additional_images/ directory.
"Authenticate Data" command in csf_fit.txt file:
Create CSF binary file:
Attach the CSF binary to the end of the image:
2.4 Verifying HAB events
The U-Boot includes the hab_auth_img command which can be used for authenticating and troubleshooting the signed image, the Image must be loaded at the load address specified in the IVT.
Authenticate additional image:
If no HAB events were found the Image is successfully signed.
References
[0] U-boot: i.MX8M family Secure Boot guide using HABv4
[1] AN4581: "i.MX Secure Boot on HABv4 Supported Devices"