+=========================================================+ + i.MX 8, i.MX 8X AHAB guide on SPL targets + +=========================================================+ 1. AHAB secure boot process ---------------------------- This document provides a step-by-step guide on how securely boot a flash.bin image generated by Secondary Program Loader (SPL) targets. It is assumed that the reader is familiar with basic AHAB concepts and with the PKI tree generation. Details about AHAB can be found in the introduction_ahab.txt document and in processors Security Reference Manual Document (SRM). 1.1 Preparing the environment to build a secure boot image ----------------------------------------------------------- The following files and projects are used to prepare a secure boot image for i.MX8/8x device: - imx-mkimage. - SECO Firmware. - U-Boot proper and SPL. (Please refer to section 1.2) - ARM Trusted Firmware (ATF). - System Controller Firmware (SCFW). - Cortex M binary. (Optional) - Kernel image. (Optional) - Code signing tools (CST). The procedure to download the SECO firmware and build U-Boot, SCFW and ATF are out of the scope of this document, please refer to the Linux BSP Release Notes and AN12212[1] for further details. 1.2 Preparing U-Boot to support AHAB secure boot features ---------------------------------------------------------- The U-Boot provides an alternative SPL target for i.MX8 and i.MX8x devices. The SPL is intended to be used by applications that requires a initial bootloader prior to initialize the ARM Trusted Firmware (ATF) and the U-Boot proper. The U-Boot support AHAB functions that are essential to completely authenticate the flash.bin image. On SPL targets only the SCFW, SPL and M4 IMG are authenticated at SCU ROM level, in order to authenticate the ATF and U-Boot proper it's necessary to call the SCU API sc_misc_seco_authenticate() function at SPL level. The support is enabled by adding CONFIG_AHAB_BOOT to the defconfig file used by your target: - Defconfig: CONFIG_AHAB_BOOT=y - Kconfig: ARM architecture -> Support i.MX 8 AHAB features 1.3 Building a SPL image supporting secure boot ------------------------------------------------ The boot image generated by SPL targets has three containers: +---------------------------+ --------- | 1st Container header | ^ | and signature | | +---------------------------+ | | Padding for 1kB alignment | | +---------------------------+ | | 2nd Container header | | | and signature | | +---------------------------+ | | Padding | | Authenticated at +---------------------------+ | SCU ROM Level | SECO FW | | +---------------------------+ | | Padding | | +---------------------------+ | | SCU FW + DCD Table | | +---------------------------+ | | Cortex-M Image | | +---------------------------+ | | SPL Image | v +---------------------------+ --------- | 3rd Container header | ^ | and signature | | +---------------------------+ | | Padding | | Authenticated +---------------------------+ | at SPL Level | U-Boot Proper IMG | | +---------------------------+ | | ARM Trusted FW (ATF) | v +---------------------------+ --------- The first container includes the SECO firmware which is signed using NXP keys, this container is authenticated by SECO ROM at SCU ROM level. The second container includes the SCFW, SPL and Cortex M SW images which are signed using OEM keys, this container is authenticated by SECO FW at SCU ROM level. The third container includes the U-Boot proper and the ATF. The SPL is in charge to load this container and also to interface with SCU requesting SECO FW to authenticate the additional container. The signing procedure is slightly different when compared with HABv4 series. On AHAB the signature is directly included in the container, the CST is responsible to sign and handle the "Signature Block": +----------------------------+ --------- | | ^ | | | | Container header | | | | | | | | +---+----------------------- + | | S | Signature block header | | Signed | i +------------------------+ | | g | | | | n | | | | a | SRK table | | | t | | | | u | | v | r +------------------------+ --------- | e | Signature | | +------------------------+ | B | | | l | SGK Key | | o | Certificate (optional) | | c | | | k | | +---+------------------------+ In case using the optional subordinate SGK key, the container signature is verified against the SGK key certificate. This certificate is verified against the SRK table. In case not using the subordinate key, the container signature is verified against the SRK keys directly. 1.4 Preparing the boot image ----------------------------- 1.4.1 Preparing the 3rd container ---------------------------------- The first step is to generate the third container including the U-Boot proper and ATF images. The imx-mkimage project includes a target which only generates this third container: - Generating the U-Boot proper + ATF container: $ make SOC= u-boot-atf-container.img The mkimage log provides the container and signature block offsets used by the CSF description file: CST: CONTAINER 0 offset: 0x0 CST: CONTAINER 0: Signature Block: offset is at 0x110 The u-boot-atf-container.img file is the third container which have to be signed using the Code Signing Tool (CST). 1.4.2 Signing the 3rd container -------------------------------- The CSF description file contains all the commands that the SECO executes during the secure boot procedure. These commands instruct the AHAB code on which memory areas of the image to authenticate, which keys to install, use and etc. CSF examples are available under doc/imx/hab/ahab/csf_examples/ directory. As explained in section above the mkimage log provides the container and signature block offsets used by the CSF description file: - "Authenticate Data" command in cst_uboot_atf.txt file: [Authenticate Data] # Binary to be signed generated by mkimage File = "u-boot-atf-container.img" # Offsets = Container header Signature block Offsets = 0x0 0x110 - Sign the third container: $ ./cst -i cst_uboot_atf.txt -o signed-u-boot-atf-container.img The signed-u-boot-atf-container.img have to be copied to imx-mkimage directory and renamed to u-boot-atf-container.img. 1.4.3 Preparing the flash.bin image ------------------------------------ The signed 3rd container can be now used to create the final flash.bin image, be sure that your signed container were successfully replaced and is named as u-boot-atf-container.img. - Generating the flash.bin image: $ make SOC= flash_spl The mkimage log provides the container and signature block offsets used by the CSF description file: CST: CONTAINER 0 offset: 0x400 CST: CONTAINER 0: Signature Block: offset is at 0x510 The flash.bin file include three containers and the second container have to be signed using the Code Signing Tool (CST). 1.4.4 Signing the flash.bin image ---------------------------------- As mentioned above the CSF description file contains all the commands that the SECO executes during the secure boot procedure. The procedure for signing the flash.bin image is similar as documented in mx8_mx8x_secure_boot.txt guide. - "Authenticate Data" command in csf_boot_image.txt file: [Authenticate Data] # Binary to be signed generated by mkimage File = "flash.bin" # Offsets = Container header Signature block Offsets = 0x400 0x510 - Sign the flash.bin container: $ ./cst -i csf_boot_image.txt -o signed-flash.bin The signed-flash.bin image contains all the signatures and can be flashed in the device. 1.5 Flashing the signed image ------------------------------ After completing all steps in section "1.4 Preparing the boot image" the signed flash.bin image can be flashed in the device: $ sudo dd if=signed-flash.bin of=/dev/sd bs=1k seek=32 && sync 1.6 Programming SRK Hash ------------------------- As explained in introduction_ahab.txt document the SRK Hash fuse values are generated by the srktool and should be programmed in the SoC SRK_HASH[511: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. The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs. - Dump SRK Hash fuses values in host machine: $ od -t x4 SRK_1_2_3_4_fuse.bin 0000000 d436cc46 8ecccda9 b89e1601 5fada3db 0000020 d454114a b6cd51f4 77384870 c50ee4b2 0000040 a27e5132 eba887cf 592c1e2b bb501799 0000060 ee702e07 cf8ce73e fb55e2d5 eba6bbd2 - Program SRK_HASH[511:0] fuses: * On i.MX 8 QXP: => fuse prog 0 730 0xd436cc46 => fuse prog 0 731 0x8ecccda9 => fuse prog 0 732 0xb89e1601 => fuse prog 0 733 0x5fada3db => fuse prog 0 734 0xd454114a => fuse prog 0 735 0xb6cd51f4 => fuse prog 0 736 0x77384870 => fuse prog 0 737 0xc50ee4b2 => fuse prog 0 738 0xa27e5132 => fuse prog 0 739 0xeba887cf => fuse prog 0 740 0x592c1e2b => fuse prog 0 741 0xbb501799 => fuse prog 0 742 0xee702e07 => fuse prog 0 743 0xcf8ce73e => fuse prog 0 744 0xfb55e2d5 => fuse prog 0 745 0xeba6bbd2 * On i.MX 8 QM: => fuse prog 0 722 0xd436cc46 => fuse prog 0 723 0x8ecccda9 => fuse prog 0 724 0xb89e1601 => fuse prog 0 725 0x5fada3db => fuse prog 0 726 0xd454114a => fuse prog 0 727 0xb6cd51f4 => fuse prog 0 728 0x77384870 => fuse prog 0 729 0xc50ee4b2 => fuse prog 0 730 0xa27e5132 => fuse prog 0 731 0xeba887cf => fuse prog 0 732 0x592c1e2b => fuse prog 0 733 0xbb501799 => fuse prog 0 734 0xee702e07 => fuse prog 0 735 0xcf8ce73e => fuse prog 0 736 0xfb55e2d5 => fuse prog 0 737 0xeba6bbd2 1.7 Verify SECO events ----------------------- If the fuses have been written properly, there should be no SECO events after boot. To validate this, power on the board, and run ahab_status command on U-Boot terminal. No events should be returned after this command: => ahab_status Lifecycle: 0x0020, NXP closed No SECO Events Found! U-Boot will decode the SECO events and provide more details on the failure, for example in case container image was signed with wrong keys and are not matching the OTP SRK hashes: => ahab_status Lifecycle: 0x0020, NXP closed SECO Event[0] = 0x0087EE00 CMD = AHAB_AUTH_CONTAINER_REQ (0x87) IND = AHAB_NO_AUTHENTICATION_IND (0xEE) Note: In case your SRK fuses are not programmed yet the event 0x0087FA00 may also be displayed. 1.8 Close the device --------------------- After the device successfully boots a signed image without generating any SECO security events, it is safe to close the device. The SECO lifecycle should be changed from 0x20 NXP closed to 0x80 OEM closed. Be aware this step can damage your board if a previous step failed. It is also irreversible. Run on the U-Boot terminal: => ahab_close Now reboot the target, and run: => ahab_status The lifecycle value should now be 0x80 OEM closed. 2. Authenticating the OS container ----------------------------------- The procedure for authenticating the OS container is similar as in Non-SPL targets, for a complete procedure please refer to mx8_mx8x_secure_boot.txt document available under doc/imx/hab/ahab/guides/ directory. References: [1] AN12212: "Software Solutions for Migration Guide from Aarch32 to Aarch64"