| +=========================================================+ |
| + i.MX 8, i.MX 8X Secure Boot guide using AHAB + |
| +=========================================================+ |
| |
| 1. AHAB secure boot process |
| ---------------------------- |
| |
| This document describes a step-by-step procedure on how to sign and |
| securely boot a flash.bin image. It is assumed that the reader is |
| familiar with basic AHAB concepts and with the PKI tree generation. |
| |
| It is also assumed that the reader is familiar with all pieces of |
| software needed. The procedure to built SCFW, ATF and download the |
| firmwares are out of scope of this document, please refer to the Linux |
| BSP Release Notes and AN12212[1] for further details. |
| |
| 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 |
| ----------------------------------------------------------- |
| |
| Before continuing, be sure to have already downloaded and built the |
| following: |
| |
| - imx-mkimage downloaded and built with i.MX 8 container support. |
| - SECO firmware downloaded. |
| - U-Boot downloaded and built. Please check section 1.2. |
| - ARM Trusted Firmware (ATF) downloaded and built for your target. |
| - System Controller Firmware (SCFW). |
| - Kernel image. |
| |
| You should also have downloaded the Code Signing Tool, available on NXP |
| website. |
| |
| In the following sections, <work> designates the repository where all |
| parts have been downloaded and built. |
| |
| 1.2 Preparing U-Boot to support AHAB secure boot features |
| ---------------------------------------------------------- |
| |
| The U-Boot provides extra functions for AHAB, such as the ability to |
| authenticate additional container images by calling the SCU API |
| sc_misc_seco_authenticate() function. |
| |
| The support is enabled by adding CONFIG_AHAB_BOOT to the defconfig file used |
| for your target: |
| |
| - Defconfig: |
| CONFIG_AHAB_BOOT=y |
| - Kconfig: |
| ARM architecture -> Support i.MX 8 AHAB features |
| |
| 1.3 Building an image supporting secure boot |
| --------------------------------------------- |
| |
| The boot image is composed of different layers: |
| |
| +---------------------------+ <-- *start |
| | 1st Container header | |
| | and signature | |
| +---------------------------+ |
| | Padding for 1kB alignment | |
| +---------------------------+ <-- *start + 0x400 |
| | 2nd Container header | |
| | and signature | |
| +---------------------------+ |
| | Padding | |
| +---------------------------+ |
| | SECO FW | |
| +---------------------------+ |
| | Padding | |
| +---------------------------+ |
| | SCU FW with DDR | |
| | initialization Image | |
| | embedded | |
| +---------------------------+ |
| | Cortex-M4 Image | |
| +---------------------------+ |
| | Cortex-A bootloader | |
| +---------------------------+ |
| |
| It contains two containers, one for the SECO firmware (AHAB), and one for |
| the SCFW, the ATF, U-Boot and M4 Image. They are preceded by their headers. |
| The first one, containing the SECO firmware image, is padded to 0x1000 to |
| fix the start address of the second one, which can contain one or multiple |
| images. |
| |
| If you are familiar with secure boot process with HABv4, you will notice |
| there is no need for CSF in this architecture. The CST is responsible to |
| handle the Signature block: |
| |
| +----------------------------+ ^ |
| | | | |
| | | | |
| | Container header | | |
| | | | |
| | | | |
| +---+------------------------+ | |
| | S | Signature block header | | Signed |
| | i +------------------------+ | |
| | g | | | |
| | n | | | |
| | a | SRK table | | |
| | t | | | |
| | u | | | |
| | r +------------------------+ v |
| | e | Signature | |
| | +------------------------+ |
| | b | | |
| | l | SGK Key | |
| | o | Certificate (optional) | |
| | c | | |
| | k | | |
| +---+------------------------+ |
| |
| The certificate block is divided into: |
| |
| +---------------+ ^ |
| | Public key | | Signed |
| | Permission | | |
| +---------------+ v |
| | Signature | |
| +---------------+ |
| |
| The first block (public key permission) verify the Signature block |
| preceding (between SRK table and Certificate blocks), while the second |
| block (signature) is verified by the SRK table block. |
| |
| 1.4 Prepare the boot image layout |
| ---------------------------------- |
| |
| To generate the flash.bin file: |
| |
| - On i.MX 8 QXP: |
| |
| $ cd <work>/imx-mkimage |
| $ make SOC=iMX8QX flash |
| |
| - On i.MX 8 QM: |
| |
| $ cd <work>/imx-mkimage |
| $ make SOC=iMX8QM flash |
| |
| If the command ends successfully, the end of the result should look |
| like: |
| |
| CST: CONTAINER 0 offset: 0x400 |
| CST: CONTAINER 0: Signature Block: offset is at 0x590 |
| DONE. |
| Note: Please copy image to offset: IVT_OFFSET + IMAGE_OFFSET |
| |
| Keep in mind the offsets above to be used with CST/CSF. |
| |
| Please note that on this example we not including an Cortex-M4 Image, on |
| i.MX8/8x MEK boards the SCU console may be replaced by the M4 console not |
| being possible to run the steps documented in section "1.5.5 Verify SECO |
| events". |
| |
| 1.5 Secure boot setup with the CST |
| ----------------------------------- |
| |
| 1.5.1 Creating the CSF description file for the second container |
| ----------------------------------------------------------------- |
| |
| The CSF contains all the commands that the AHAB executes during the secure |
| boot. These commands instruct the AHAB 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. |
| |
| This csf_boot_image.txt file example should be updated with the offset values |
| of the 1.4 section and the path to your flash.bin file. It is the last part |
| of the file: |
| |
| [Authenticate Data] |
| # Binary to be signed generated by mkimage |
| File = "flash.bin" |
| # Offsets = Container header Signature block (printed out by mkimage) |
| Offsets = 0x400 0x590 |
| |
| 1.5.2 Signing the boot image |
| ----------------------------- |
| |
| Now you use the CST to generate the signed boot image from the previously |
| created csf_boot_image.txt Commands Sequence File: |
| |
| $ cd <work> |
| $ ./release/linux64/bin/cst -i csf_boot_image.txt -o flash.signed.bin |
| |
| 1.5.3 Flash the signed image |
| ----------------------------- |
| |
| Write the signed U-Boot image: |
| |
| $ sudo dd if=flash.signed.bin of=/dev/sdX bs=1k seek=32 ; sync |
| |
| Then insert the SD Card into the board and plug your device to your computer |
| with an USB serial cable. |
| |
| 1.5.4 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.5.5 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.5.6 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 |
| ----------------------------------- |
| |
| Note that the following section is not mandatory. If you do not plan to |
| authenticate the kernel image, you can disable this behavior by setting |
| sec_boot=no in U-Boot environment variable. |
| |
| Note, you can also authenticate the OS image by running a U-Boot command: |
| |
| => auth_cntr <Container address> |
| |
| 2.1 Prepare the OS container image |
| ----------------------------------- |
| |
| You need to generate the OS container image. First, copy the binary previously |
| generated to the <work> directory to save it for later: |
| |
| - On i.MX 8 QXP |
| |
| $ cd <work>/imx-mkimage |
| $ cp iMX8QX/flash.bin .. |
| $ make SOC=iMX8QX flash_linux |
| $ mv iMX8QX/flash.bin iMX8QX/flash_os.bin |
| $ cp iMX8QX/flash_os.bin .. |
| |
| - On i.MX 8 QM |
| |
| $ cd <work>/imx-mkimage |
| $ cp iMX8QM/flash.bin .. |
| $ make SOC=iMX8QM flash_linux |
| $ mv iMX8QM/flash.bin iMX8QM/flash_os.bin |
| $ cp iMX8QM/flash_os.bin .. |
| |
| If the make command ends successfully, the end of the result should look |
| like: |
| |
| CST: CONTAINER 0 offset: 0x0 |
| CST: CONTAINER 0: Signature Block: offset is at 0x110 |
| DONE. |
| Note: Please copy image to offset: IVT_OFFSET + IMAGE_OFFSET |
| |
| Keep in mind the offsets above to be used with CST/CSF |
| |
| 2.2 Creating the CSF description file for OS container image |
| ------------------------------------------------------------- |
| |
| CSF examples are available under doc/imx/hab/ahab/csf_examples/ |
| directory. |
| |
| This csf_linux_img.txt file example should be updated with the offset values |
| of the 2.1 chapter and the path to your flash_os.bin file. It it the last |
| part of the file: |
| |
| [Authenticate Data] |
| # Binary to be signed generated by mkimage |
| File = "flash_os.bin" |
| # Offsets = Container header Signature block (printed out by mkimage) |
| Offsets = 0x0 0x110 |
| |
| 2.3 Authenticating container image |
| ----------------------------------- |
| |
| Now you use the CST to signed the OS image using the previously |
| created csf_linux_img.txt Commands Sequence File: |
| |
| $ cd <work> |
| $ ./release/linux64/bin/cst -i csf_linux_img.txt -o os_cntr_signed.bin |
| |
| 2.4 Copy OS container |
| ---------------------- |
| |
| Mount the SD Card: |
| |
| $ sudo mount /dev/sdX1 partition |
| |
| Copy the OS signed image on the SD Card: |
| |
| - For i.MX 8 QXP |
| |
| $ sudo cp os_cntr_signed.bin /media/UserID/Boot\ imx8qx |
| |
| - For i.MX 8 QM |
| |
| $ sudo cp os_cntr_signed.bin /media/UserID/Boot\ imx8qm |
| |
| Finally: |
| |
| $ sudo umount partition |
| |
| References: |
| [1] AN12212: "Software Solutions for Migration Guide from Aarch32 to |
| Aarch64" - Rev 0." |