| +=======================================================+ |
| + i.MX6, i.MX7 U-Boot Secure Boot guide using HABv4 + |
| +=======================================================+ |
| |
| 1. HABv4 secure boot process |
| ----------------------------- |
| |
| This document describes a step-by-step procedure on how to sign and securely |
| boot an U-Boot image for non-SPL targets. 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 Building a u-boot-dtb.imx image supporting secure boot |
| ----------------------------------------------------------- |
| |
| The U-Boot provides support to secure boot configuration and also provide |
| access to the HAB APIs exposed by the ROM vector table, the support is |
| enabled by selecting the CONFIG_SECURE_BOOT option. |
| |
| When built with this configuration, the U-Boot provides extra functions for |
| HAB, such as the HAB status logs retrievement through the hab_status command |
| and support for extending the root of trust. |
| |
| The U-Boot also correctly pads the final image by aligning to the next 0xC00 |
| address, so the CSF signature data generated by CST can be concatenated to |
| image. |
| |
| The diagram below illustrate a signed u-boot-dtb.imx image layout: |
| |
| ------- +-----------------------------+ <-- *start |
| ^ | Image Vector Table | |
| | +-----------------------------+ <-- *boot_data |
| | | Boot Data | |
| | +-----------------------------+ <-- *dcd |
| | | DCD Table | |
| | +-----------------------------+ |
| Signed | | Padding | |
| Data | +-----------------------------+ <-- *entry |
| | | | |
| | | | |
| | | u-boot-dtb.bin | |
| | | | |
| | | | |
| | +-----------------------------+ |
| v | Padding | |
| ------- +-----------------------------+ <-- *csf |
| | | |
| | Command Sequence File (CSF) | |
| | | |
| +-----------------------------+ |
| | Padding (optional) | |
| +-----------------------------+ |
| |
| 1.2 Enabling the secure boot support |
| ------------------------------------- |
| |
| The first step is to generate an U-Boot image supporting the HAB features |
| mentioned above, this can be achieved by adding CONFIG_SECURE_BOOT to the |
| build configuration: |
| |
| - Defconfig: |
| |
| CONFIG_SECURE_BOOT=y |
| |
| - Kconfig: |
| |
| ARM architecture -> Support i.MX HAB features |
| |
| 1.3 Creating the CSF description file |
| -------------------------------------- |
| |
| The CSF contains all the commands that the HAB executes during the secure |
| boot. These commands instruct the HAB on which memory areas of the image |
| to authenticate, which keys to install, use and etc. |
| |
| CSF examples are available under doc/imx/habv4/csf_examples/ directory. |
| |
| A build log containing the "Authenticate Data" parameters is available after |
| the U-Boot build, the example below is a log for mx7dsabresd_defconfig target: |
| |
| - mkimage build log: |
| |
| $ cat u-boot-dtb.imx.log |
| |
| Image Type: Freescale IMX Boot Image |
| Image Ver: 2 (i.MX53/6/7 compatible) |
| Mode: DCD |
| Data Size: 667648 Bytes = 652.00 KiB = 0.64 MiB |
| Load Address: 877ff420 |
| Entry Point: 87800000 |
| HAB Blocks: 0x877ff400 0x00000000 0x0009ec00 |
| ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ |
| | | | |
| | | ------- (1) |
| | | |
| | ------------------ (2) |
| | |
| ----------------------------- (3) |
| |
| (1) Size of area in file u-boot-dtb.imx to sign. |
| This area should include the IVT, the Boot Data the DCD |
| and the U-Boot itself. |
| (2) Start of area in u-boot-dtb.imx to sign. |
| (3) Start of area in RAM to authenticate. |
| |
| - In "Authenticate Data" CSF command users can copy and past the output |
| addresses: |
| |
| Block = 0x877ff400 0x00000000 0x0009ec00 "u-boot-dtb.imx" |
| |
| 1.4 Signing the U-Boot binary |
| ------------------------------ |
| |
| The CST tool is used for singing the U-Boot binary and generating a CSF binary, |
| users should input the CSF description file created in the step above and |
| should receive a CSF binary, which contains the CSF commands, SRK table, |
| signatures and certificates. |
| |
| - Create CSF binary file: |
| |
| $ ./cst -i csf_uboot.txt -o csf_uboot.bin |
| |
| - Append CSF signature to the end of U-Boot image: |
| |
| $ cat u-boot-dtb.imx csf_uboot.bin > u-boot-signed.imx |
| |
| The u-boot-signed.imx is the signed binary and should be flashed into the boot |
| media. |
| |
| - Flash signed U-Boot binary: |
| |
| $ sudo dd if=u-boot-signed.imx of=/dev/sd<x> bs=1K seek=1 && sync |
| |
| 1.5 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. |
| |
| The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs. |
| |
| - Dump SRK Hash fuses values in host machine: |
| |
| $ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' SRK_1_2_3_4_fuse.bin |
| 0x20593752 |
| 0x6ACE6962 |
| 0x26E0D06C |
| 0xFC600661 |
| 0x1240E88F |
| 0x1209F144 |
| 0x831C8117 |
| 0x1190FD4D |
| |
| - Program SRK_HASH[255:0] fuses, using i.MX6 series as example: |
| |
| => fuse prog 3 0 0x20593752 |
| => fuse prog 3 1 0x6ACE6962 |
| => fuse prog 3 2 0x26E0D06C |
| => fuse prog 3 3 0xFC600661 |
| => fuse prog 3 4 0x1240E88F |
| => fuse prog 3 5 0x1209F144 |
| => fuse prog 3 6 0x831C8117 |
| => fuse prog 3 7 0x1190FD4D |
| |
| The table below lists the SRK_HASH bank and word according to the i.MX device: |
| |
| +-------------------+---------------+---------------+---------------+ |
| | | i.MX6 Series | i.MX7D/S | i.MX7ULP | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[31:00] | bank 3 word 0 | bank 6 word 0 | bank 5 word 0 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[63:32] | bank 3 word 1 | bank 6 word 1 | bank 5 word 1 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[95:64] | bank 3 word 2 | bank 6 word 2 | bank 5 word 2 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[127:96] | bank 3 word 3 | bank 6 word 3 | bank 5 word 3 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[159:128] | bank 3 word 4 | bank 7 word 0 | bank 5 word 4 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[191:160] | bank 3 word 5 | bank 7 word 1 | bank 5 word 5 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[223:192] | bank 3 word 6 | bank 7 word 2 | bank 5 word 6 | |
| +-------------------+---------------+---------------+---------------+ |
| | SRK_HASH[255:224] | bank 3 word 7 | bank 7 word 3 | bank 5 word 7 | |
| +-------------------+---------------+---------------+---------------+ |
| |
| 1.6 Verifying HAB events |
| ------------------------- |
| |
| The next step is to verify that the signature attached to U-Boot 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: |
| |
| => hab_status |
| |
| Secure boot disabled |
| |
| HAB Configuration: 0xf0, HAB State: 0x66 |
| No HAB Events Found! |
| |
| 1.6.1 Verifying HAB events in i.MX7ULP |
| --------------------------------------- |
| |
| When booting i.MX7ULP in low power or dual boot modes the M4 binary is |
| authenticated by an independent HAB in M4 ROM code using a |
| different SRK key set. |
| |
| The U-Boot provides a M4 option in hab_status command so users can retrieve |
| M4 HAB failure and warning events. |
| |
| - Verify HAB M4 events: |
| |
| => hab_status m4 |
| |
| Secure boot disabled |
| |
| HAB Configuration: 0xf0, HAB State: 0x66 |
| No HAB Events Found! |
| |
| As HAB M4 API cannot be called from A7 core the command is parsing the M4 HAB |
| persistent memory region, M4 software should not modify this reserved region. |
| |
| Details about HAB persistent memory region can be found in AN12263[2]. |
| |
| 1.7 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, using i.MX6 series as example: |
| |
| => fuse prog 0 6 0x00000002 |
| |
| The table below list the SEC_CONFIG[1] bank and word according to the i.MX |
| device: |
| |
| +--------------+-----------------+------------+ |
| | Device | Bank and Word | Value | |
| +--------------+-----------------+------------+ |
| | i.MX6 Series | bank 0 word 6 | 0x00000002 | |
| +--------------+-----------------+------------+ |
| | i.MX7D/S | bank 1 word 3 | 0x02000000 | |
| +--------------+-----------------+------------+ |
| | i.MX7ULP | bank 29 word 6 | 0x80000000 | |
| +--------------+-----------------+------------+ |
| |
| 1.8 Completely secure the device |
| --------------------------------- |
| |
| Additional fuses can be programmed for completely secure the device, more |
| details about these fuses and their possible impact can be found at AN4581[1]. |
| |
| - Program SRK_LOCK, using i.MX6 series as example: |
| |
| => fuse prog 0 0 0x4000 |
| |
| - Program DIR_BT_DIS, using i.MX6 series as example: |
| |
| => fuse prog 0 6 0x8 |
| |
| - Program SJC_DISABLE, using i.MX6 series as example: |
| |
| => fuse prog 0 6 0x100000 |
| |
| - JTAG_SMODE, using i.MX6 series as example: |
| |
| => fuse prog 0 6 0xC00000 |
| |
| The table below list the SRK_LOCK, DIR_BT_DIS, SJC_DISABLE, and JTAG_SMODE bank |
| and word according to the i.MX device: |
| |
| +--------------+---------------+------------+ |
| | Device | Bank and Word | Value | |
| +--------------+---------------+------------+ |
| | SRK_LOCK | |
| +-------------------------------------------+ |
| | i.MX6 Series | bank 0 word 0 | 0x00004000 | |
| +--------------+---------------+------------+ |
| | i.MX7D/S | bank 0 word 0 | 0x00000200 | |
| +--------------+---------------+------------+ |
| | i.MX7ULP | bank 1 word 1 | 0x00000080 | |
| +--------------+---------------+------------+ |
| | DIR_BT_DIS | |
| +-------------------------------------------+ |
| | i.MX6 Series | bank 0 word 6 | 0x00000008 | |
| +--------------+---------------+------------+ |
| | i.MX7D/S | bank 1 word 3 | 0x08000000 | |
| +--------------+---------------+------------+ |
| | i.MX7ULP | bank 1 word 1 | 0x00002000 | |
| +--------------+---------------+------------+ |
| | SJC_DISABLE | |
| +-------------------------------------------+ |
| | i.MX6 Series | bank 0 word 6 | 0x00100000 | |
| +--------------+---------------+------------+ |
| | i.MX7D/S | bank 1 word 3 | 0x00200000 | |
| +--------------+---------------+------------+ |
| | i.MX7ULP | bank 1 word 1 | 0x00000020 | |
| +--------------+---------------+------------+ |
| | JTAG_SMODE | |
| +-------------------------------------------+ |
| | i.MX6 Series | bank 0 word 6 | 0x00C00000 | |
| +--------------+---------------+------------+ |
| | i.MX7D/S | bank 1 word 3 | 0x00C00000 | |
| +--------------+---------------+------------+ |
| | i.MX7ULP | bank 1 word 1 | 0x000000C0 | |
| +--------------+---------------+------------+ |
| |
| 2. Extending the root of trust |
| ------------------------------- |
| |
| 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 supports this feature and can be used to authenticate the Linux |
| Kernel Image. |
| |
| The process of signing an additional image is similar to the U-Boot. |
| The diagram below illustrate the zImage layout: |
| |
| ------- +-----------------------------+ <-- *load_address |
| ^ | | |
| | | | |
| | | | |
| | | | |
| | | zImage | |
| Signed | | | |
| Data | | | |
| | | | |
| | +-----------------------------+ |
| | | Padding Next Boundary | |
| | +-----------------------------+ <-- *ivt |
| v | Image Vector Table | |
| ------- +-----------------------------+ <-- *csf |
| | | |
| | Command Sequence File (CSF) | |
| | | |
| +-----------------------------+ |
| | Padding (optional) | |
| +-----------------------------+ |
| |
| 2.1 Padding the image |
| ---------------------- |
| |
| The zImage must be padded to the next boundary address (0x1000), for instance |
| if the image size is 0x649920 it must be padded to 0x64A000. |
| |
| The tool objcopy can be used for padding the image. |
| |
| - Pad the zImage: |
| |
| $ objcopy -I binary -O binary --pad-to 0x64A000 --gap-fill=0x00 \ |
| zImage zImage_pad.bin |
| |
| 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 zImage does not include an IVT this has |
| to be manually created and appended to the end of the padded zImage, the |
| script genIVT.pl in script_examples directory can be used as reference. |
| |
| - Generate IVT: |
| |
| $ genIVT.pl |
| |
| Note: The load Address may change depending on the device. |
| |
| - Append the ivt.bin at the end of the padded zImage: |
| |
| $ cat zImage_pad.bin ivt.bin > zImage_pad_ivt.bin |
| |
| 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 |
| U-Boot must be used when extending the root of trust. |
| |
| CSF examples are available in ../csf_examples/additional_images/ |
| directory. |
| |
| - Create CSF binary file: |
| |
| $ ./cst --i csf_additional_images.txt --o csf_zImage.bin |
| |
| - Attach the CSF binary to the end of the image: |
| |
| $ cat zImage_pad_ivt.bin csf_zImage.bin > zImage_signed.bin |
| |
| 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, zImage must be |
| loaded at the load address specified in the IVT. |
| |
| - Authenticate additional image: |
| |
| => hab_auth_img <Load Address> <Image Size> <IVT Offset> |
| |
| If no HAB events were found the zImage is successfully signed. |
| |
| References: |
| [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using |
| HABv4" - Rev 2. |
| [2] AN12263: "HABv4 RVT Guidelines and Recommendations" - Rev 0. |