| +==========================================================+ |
| + i.MX6, i.MX7 U-Boot Encrypted Boot guide using HABv4 + |
| +==========================================================+ |
| |
| 1. HABv4 Encrypted Boot process |
| ------------------------------- |
| |
| This document describes a step-by-step procedure on how to encrypt and |
| sign an U-Boot image. It is assumed that the reader is familiar |
| with basic HAB concepts and has already followed the mx6_mx7_secure_boot.txt |
| guide and got a working closed device. |
| |
| Details about HAB and encrypted boot process can be found in application |
| notes AN4581[1] and AN12056[2] and in the introduction_habv4.txt document. |
| |
| Before continuing, be sure to have fatwrite and dek_blob commands |
| available in U-Boot. If not, enable them in Kconfig and rebuild |
| U-Boot: |
| |
| - Defconfig |
| |
| CONFIG_FAT_WRITE=y |
| CONFIG_CMD_DEKBLOB=y |
| CONFIG_CMD_PRIBLOB=y |
| |
| - Kconfig |
| |
| File systems -> Enable FAT filesystem support-> Enable FAT filesystem |
| write support |
| ARM architecture -> Support the 'dek_blob' command |
| ARM architecture -> Support the set_priblob_bitfield command |
| |
| 1.1 Building an encrypted U-Boot image |
| -------------------------------------- |
| |
| This U-Boot is built the same way the one from the secure document is, |
| so it provides the same access the the HAB APIs, extra functions |
| for HAB, etc... |
| |
| However, the layout of the new image is different, as a part of it is |
| encrypted, and a DEK blob is appended at the end. The diagram below |
| illustrates an encrypted u-boot-dtb.imx image layout: |
| |
| ----------------------- +-----------------------------+ <--- *start |
| ^ ^ | Image Vector Table | |
| | | +-----------------------------+ <--- *boot_data |
| | | | Boot Data | |
| | Plain | +-----------------------------+ <--- *dcd |
| | text | | DCD Table | |
| | | +-----------------------------+ |
| Signed | v | Padding | |
| data | ------- +-----------------------------+ <--- *entry |
| | ^ | | |
| | | | | |
| | Encrypted | | u-boot-dtb.bin | |
| | data | | | |
| | | | | |
| | | +-----------------------------+ |
| v v | Padding | |
| ----------------------- +-----------------------------+ <--- *csf |
| ^ | Command Sequence File | |
| 0x2000 | | (commands + SRK table + | |
| (in bytes) | | signatures + certificates + | |
| v | Nonce + MAC) | |
| ------- +-----------------------------+ |
| | Padding | |
| +-----------------------------+ <--- *csf + 0x2000 |
| | DEK Blob | |
| +-----------------------------+ |
| | Padding | |
| +-----------------------------+ |
| |
| 1.2 Get a secure boot working |
| ----------------------------- |
| |
| You need to go through all the steps described into the |
| mx6_mx7_secure_boot.txt guide, and get a signed U-Boot which can |
| boot successfully on a closed target. Otherwise, the following |
| steps will not work. |
| |
| 1.3 Compile the CST to enable the encrypting feature |
| ---------------------------------------------------- |
| |
| The encrypting feature is not enabled by default. You need to |
| execute the following commands to enable it: |
| |
| $ sudo apt-get install libssl-dev openssl |
| $ cd <CST install directory>/code/back_end/src |
| $ gcc -o cst_encrypted -I ../hdr -L ../../../linux64/lib *.c |
| -lfrontend -lcrypto |
| $ cp cst_encrypted ../../../<where your original CST executable is> |
| |
| 1.4 Creating the CSF description files |
| -------------------------------------- |
| |
| The CSF contains all the commands that the ROM executes during the |
| secure boot. These commands instruct the HAB on which memory areas |
| of the image to authenticate, which keys to install, use, etc... |
| |
| CSF examples for encrypted boot are available under |
| doc/imx/hab/habv4/csf_examples/ directory. |
| |
| For both CSF, first part is same compared to the CSF used for |
| the secure boot step. |
| Here we describe how to encrypt the U-Boot image and then sign it. |
| |
| 1.4.1 csf_u-boot_enc.txt |
| ------------------------- |
| |
| This first CSF is used to encrypt the U-Boot image and generate the |
| dek.bin file. The Authenticate Data command has to be modified, and |
| two new commands have to be added: |
| |
| - Modify the Authenticate Data command to only cover IVT and DCD: |
| |
| Blocks = 0x877ff400 0x00000000 0x00000c00 "u-boot-dtb.imx" |
| |
| - Add the new Install Secret Key command to generate the dek.bin |
| file and install the blob. The parameter which depends of your |
| configuration is the Blob Address. Padding of 0x2000 is |
| recommended. Following the csf_uboot.txt data for instance: |
| |
| Blob Address = Authenticate Start Address + Padding + length |
| = 0x877ff400 + 0x2000 + 0x9ec00 = 0x878a0000 |
| |
| - Add the new Decrypt Data command to encrypt the file. As the file |
| specified in parameter will be modified, we suggest to copy it. |
| Then modify the Blocks command depending of your U-Boot image. |
| In our example: |
| |
| $ cp u-boot-dtb.imx u-boot-dtb.imx-enc |
| Block = (Authenticate start addr + 0xc00) 0xc00 (length - 0xc00) |
| u-boot-dtb.imx-enc |
| = (0x877ff400 + 0xc00) 0xc00 (0x9ec00 - 0xc00) |
| u-boot-dtb.imx-enc |
| = 0x87800000 0xc00 0x9e000 u-boot-dtb.imx-enc |
| |
| 1.4.2 csf_u-boot_sign_enc.txt |
| ----------------------------- |
| |
| This second CSF is used to sign the encrypted U-Boot image previously |
| generated (u-boot-dtb.imx-enc). The Authenticate Data part has also |
| to be changed, the modifications are the following: |
| |
| - The Authenticate Data command is same compared to the one in |
| csf_uboot.txt file, except that this time, the file parameter |
| is the file previously encrypted: u-boot-dtb.imx-enc. |
| |
| Blocks = 0x877ff400 0x000 0x0009ec00 "u-boot-dtb.imx-enc" |
| |
| - For the two new commands, we do not want to they modify our previously |
| signed/generated files. Therefore, for the Key parameter of the |
| Install Secret Key command, the value is now dek-dummy.bin, which |
| will generate a new dek file instead of erasing the previous one. |
| About the decrypt data command, you need to copy the u-boot-dtb.imx |
| file again in a u-boot-dtb.imx-dummy file, to not replace the |
| original encrypted file with an encrypted one: |
| |
| Key = "dek-dummy.bin" |
| Blocks = 0x87800000 0x00000c00 0x9e000 "u-boot-dtb.imx-dummy" |
| |
| 1.5 Encrypt the U-Boot image |
| ---------------------------- |
| |
| The image is encrypted using the Code Signing Tool. It generates also |
| a CSF binary and a dek.bin file, which will be used on the future |
| steps below. |
| |
| - Create the CSF binary file and encrypt the U-Boot image |
| |
| $ ./cst_encrypted -i csf_u-boot_enc.txt -o csf_u-boot_enc.bin |
| |
| 1.6 Sign the encrypted U-Boot image |
| ----------------------------------- |
| |
| The image is then signed using the Code Signing Tool. It also |
| generate a CSF binary, which will be used on the future steps below. |
| |
| - Create the CSF binary file and sign the encrypted U-Boot image |
| |
| $ ./cst_encrypted -i csf_u-boot_sign_enc.txt -o csf_u-boot_sign_enc.bin |
| |
| 1.7 Swap Nonce/MAC from csf_u-boot_enc.bin to csf_u-boot_sign_enc.bin |
| --------------------------------------------------------------------- |
| |
| First, calculate Nonce/MAC size based on MAC bytes value |
| in CSF. As Mac bytes is 16: |
| |
| Nonce/MAC size = Nonce size + MAC bytes + CSF header for Nonce/Mac |
| = 12 + 16 + 8 = 36 bytes |
| |
| Then, calculate Nonce/MAC offset in CSF: |
| |
| MAC offset = csf_u-boot-enc.bin size - Nonce/MAC size |
| = 3972 - 36 = 3936 Bytes |
| |
| In the next step, extract Nonce/NAC from the first CSF: |
| |
| $ dd if=csf_u-boot_enc.bin of=noncemac.bin bs=1 skip=3936 count=36 |
| |
| Finally, replace the MAC of csf_u-boot_sign_enc.bin with the extracted |
| one: |
| |
| $ dd if=noncemac.bin of=csf_u-boot_sign_enc.bin bs=1 seek=3936 count=36 |
| |
| 1.8 Generate encryptedu-boot with no dek |
| ---------------------------------------- |
| |
| As described in the layout in the first part of this document, the |
| final image is composed of these different parts padded to known |
| values, to make it compliant with the CSF. |
| |
| First, pad the CSF to 0x2000: |
| |
| $ objcopy -I binary -O binary --pad-to 0x2000 --gap-fill=0xff |
| csf_u-boot_sign_enc.bin csf_u-boot_sign_enc_padded.bin |
| |
| Then, append this file to the encrypted U-Boot image: |
| |
| $ cat u-boot-dtb.imx-enc csf_u-boot_sign_enc_padded.bin > |
| u-boot_encrypted_no_dek.bin |
| |
| Pad this new file to width+offset (0x9ec00 + 0x2000 = 0xa0c00): |
| |
| $ objcopy -I binary -O binary --pad-to 0xa0c00 --gap-fill=0x00 |
| u-boot_encrypted_no_dek.bin u-boot_encrypted_no_dek_padded.bin |
| |
| 1.9 Generate the DEK Blob |
| ------------------------- |
| The missing part to get our final U-Boot encrypted image is a DEK |
| blob. To generate it, copy the dek.bin file generated at step 1.5 |
| on the Boot partition of your SD Card. Then interrupt the boot |
| and your chip. You need the fatwrite and dek_blob command, which |
| should be enabled by the secure boot. If not, you have to enable |
| them in Kconfig and recompile U-Boot |
| |
| Run the following commands: |
| |
| => mmc list |
| FSL_SDHC: 0 (SD) #index to use for mmc in following commands |
| => fatload mmc 0 0x80800000 dek.bin |
| => dek_blob 0x80800000 0x80801000 128 |
| => fatwrite mmc 0 0x80801000 dek_blob.bin 0x48 |
| |
| 1.10 Finalize the encrypted U-Boot image |
| ---------------------------------------- |
| |
| Finally, copy the generated dek_blob.bin file from your SDCard to |
| your CST repository. Append it with the last padded file to get your |
| final image: |
| |
| $ cat u-boot_encrypted_no_dek_padded.bin dek_blob.bin > |
| u-boot_encrypted.bin |
| |
| If the image does not boot, please verify the size of your |
| U-Boot image, the length specified into CSF and the padding values. |
| |
| 2. About the PRIBLOB bitfield from CAAM SCFGR register |
| ------------------------------------------------------ |
| |
| It is highly recommended to set the PRIBLOB bitfield from the CAAM |
| SCFGR register to 0x3 once your encrypted U-Boot image is completed. |
| To do so, a command has been implemented in u-boot: |
| |
| => set_priblob_bitfield |
| |
| Once this bitfield is set to 0x3, it ensures cryptographic separation |
| of private blob types avoiding any modification or replacement of |
| DEK blobs. Newly created blobs will be incompatible with blobs |
| required to decrypt an encrypted boot image. When the HAB later |
| executes the command to decrypt the DEK, an incompatible DEK blob |
| will be detected and cause an error. A substitute encrypted boot image |
| will not be decrypted, and will not be executed. |
| |
| 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] AN12056: "Encrypted Boot on HABv4 and CAAM Enabled Devices" - Rev. 1 |