+=========================================================+ + i.MX 8ULP, i.MX 9x Encrypted Boot guide using AHAB + +=========================================================+ 1. AHAB Encrypted Boot process ------------------------------- This document describes a step-by-step procedure on how to encrypt and sign a bootloader image for i.MX8ULP and i.MX9x family devices. It is assumed that the reader is familiar with basic AHAB concepts and the secure boot process, step-by-step procedure can be found in mx8ulp_9x_secure_boot.txt. The steps described in this document are based on i.MX93 device, the same concept can be applied to others processor with similar AHAB architecture like i.MX8ULP and i.MX9x family devices. 1.1 Understanding the encrypted image signature block ------------------------------------------------------ As described in mx8ulp_9x_secure_boot.txt guide a single binary is used to boot the device. The imx-mkimage tool combines all the input images in a container structure, generating a flash.bin binary. AHAB is able to decrypt image containers by calling EdgeLock Enclave (ELE) authentication functions, the image must be encrypted by CST and the resulting DEK (Data Encryption Key) must be encapsulated and included into the container 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 +------------------------+ | | DEK Blob | +---+------------------------+ 1.1.1 Understanding and generating the DEK blob ------------------------------------------------ The encrypted boot image requires a DEK blob on each time AHAB is used to decrypt an image. The DEK blob is used as a security layer to wrap and store the DEK off-chip using the OTPMK which is unique per device. On i.MX8ULP/9x devices the DEK blob is generated using the ELE API, the following funtion is available in U-Boot and can be executed through dek_blob command: - ele_generate_key_blob_req(sc_ipc_t ipc, uint32_t id, sc_faddr_t load_addr, sc_faddr_t export_addr, uint16_t max_size) Details in API usage can be found in EdgeLock Enclave (ELE) API guide [1]. As part of the DEK generation process, the DEK blob will need to be transferred to a host computer to insert into the boot image. Therefore, the target board must have a filesystem in place to transfer the DEK file. 1.2 Enabling the encrypted boot support in U-Boot -------------------------------------------------- For deploying an encrypted boot image additional U-Boot tools are needed, please be sure to have the following features enabled, this can be achieved by following one of the methods below: - Defconfig: CONFIG_AHAB_BOOT=y CONFIG_CMD_DEKBLOB=y CONFIG_IMX_ELE_DEK_ENCAP=y CONFIG_FAT_WRITE=y - Kconfig: ARM architecture -> Support i.MX8 AHAB features ARM architecture -> Support the 'dek_blob' command File systems -> Enable FAT filesystem support-> Enable FAT filesystem write support 1.3 Enabling the encrypted boot support in CST ----------------------------------------------- CST version 3.0.0 and later have the encryption feature enabled by default. If using an earlier version, the encryption feature must be explicitly enabled. For CST versions <3.0.0, the CST backend must be recompiled, execute the following commands to enable encryption support in CST: $ sudo apt-get install libssl-dev openssl $ cd /code/back_end/src $ gcc -o cst_encrypted -I ../hdr -L ../../../linux64/lib *.c -lfrontend -lcrypto $ cp cst_encrypted ../../../linux64/bin/ 1.4 Preparing the image container ---------------------------------- The container generation is explained in mx8ulp_9x_secure_boot.txt guide. This document is based in imx-mkimage flash target (3 containers in flash.bin). - Assembly flash.bin binary: $ make SOC= flash_ Note: Please see all target options in the make file /soc.mak The mkimage log is used during the encrypted boot procedure to create the Command Sequence File (CSF) and for final image construction: Output: u-boot-atf-container.img ... 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 ... Output: flash.bin ... CST: CONTAINER 0 offset: 0x400 CST: CONTAINER 0: Signature Block: offset is at 0x490 DONE. Note: Please copy image to offset: IVT_OFFSET + IMAGE_OFFSET append u-boot-atf-container.img at 271 KB 1.5 Creating the CSF descriptions to encrypt the 2nd & 3rd containers -------------------------------------------------------------- The 2nd & 3rd containers on the boot image must be encrypted. For details on the boot image structure and signing the boot image for authentication refer to mx8ulp_9x_secure_boot.txt. For generating the CSF, csf_enc_boot_image.txt is available under ahab/csf_examples/ and can be used as example for encrypting the flash.bin binary. The main change is the Install Secret Key command that must be added after Authenticate Data command. By default all images are encrypted. Optionally users can provide a key identifier that must match the value provided during the blob generation, by default its value is zero. Additionally, image indexes parameter can be used to mask the images indexes that must be encrypted. We start with the CSF for the 2nd Container containing SPL. The offsets are calculated by using the signature offset and container location. csf_boot_image.txt: ... [Authenticate Data] File = "flash.bin" # Container offset = 0x400 # Signature Block = 0x490 Offsets = 0x400 0x490 [Install Secret Key] Key = "dek_2.bin" Key Length = 128 #Key Identifier = 0x1234CAFE #Image Indexes = 0xFFFFFFFE The CSF for the 3rd container containing u-boot and ATF will look similar, but with different file, offsets, and DEK. csf_3rd_image.txt: ... [Authenticate Data] File = "enc_2nd_cntnr_flash.bin" # Container location is 271KB in flash.bin # 0x110 is signature block offset inside u-boot-atf-container.img # 271KB + 0x110 = 0x43C00 + 0x110 = 0x43D10 Offsets = 0x43C00 0x43D10 [Install Secret Key] Key = "dek_3.bin" Key Length = 128 #Key Identifier = 0x1234CAFE #Image Indexes = 0xFFFFFFFE 1.6 Encrypting the Image --------------------------------- The image is encrypted using the Code Signing Tool. The tool generates the encrypted image and a random dek.bin file. - Encrypt flash.bin binary: $ ./cst -i csf_boot_image.txt -o enc_2nd_cntnr_flash.bin The DEK BLOB must be inserted at offset 0x6c0 (its expected size is 72 bytes) CSF Processed successfully and signed image available in enc_2nd_cntnr_flash.bin $ ./cst -i csf_3rd_image.txt -o encrypted-flash.bin The DEK BLOB must be inserted at offset 0x43f40 (its expected size is 72 bytes) CSF Processed successfully and signed image available in encrypted-flash.bin The output log will be used in a later step to insert the DEK blob into the signature block. 1.7 Generating the DEK Blob ---------------------------- The DEK must be encapsulated into a blob so it can be included into the final encrypted binary. The U-Boot provides a tool called dek_blob which is calling the ELE blob encapsulation API. Copy dek_2 and dek_3 to the i.MX8ULP or 9x and run the following commands from U-Boot prompt. Boot the flash.bin generated earlier with mkimage on board. Halt at U-Boot and connect to host computer with USB Mass Storage (UMS): mmc2(part 0) is current device flash target is MMC:2 Net: eth0... Fastboot: Normal Normal Boot Hit any Key to stop autoboot: 0 => ums 0 mmc 2:1 Copy both DEK over to the board using the computer's file system. Now use fatload and dek_blob to create and encapsulate the DEK blob. => mmc list FSL_SDHC: 1 FSL_SDHC: 2 (eMMC) => fatload mmc 2:1 0x80280000 dek_2.bin => dek_blob 0x80280000 0x80281000 128 => fatwrite mmc 2:1 0x80281000 dek_blob2.bin 0x48 => fatload mmc 2:1 0x80280000 dek_3.bin => dek_blob 0x80280000 0x80281000 128 => fatwrite mmc 2:1 0x80281000 dek_blob3.bin 0x48 Use UMS to copy the dek blobs back to the host PC. In host PC copy the generated dek_blob binaries to the CST directory. 1.8 Assembling the encrypted image ----------------------------------- The DEK blobs generated in the step above have to be inserted into the containers' signature blocks. The CSF log is used to determine the DEK Blob offset: The DEK BLOB must be inserted at offset 0x6c0 (its expected size is 72 bytes) CSF Processed successfully and signed image available in enc_2nd_cntnr_flash.bin The DEK BLOB must be inserted at offset 0x43f40 (its expected size is 72 bytes) CSF Processed successfully and signed image available in encrypted-flash.bin - Insert DEK Blobs into container signature blocks: $ dd if=dek_blob2.bin of=encrypted-flash.bin bs=1 seek=$((0x6c0)) conv=notrunc $ dd if=dek_blob3.bin of=encrypted-flash.bin bs=1 seek=$((0x43f40)) conv=notrunc 1.10 Flashing the encrypted boot image --------------------------------------- After completing all steps in Section 1.8 the encrypted flash.bin image can be flashed to the device using UUU. Please refer to UUU documentation for more details on programming the flash devices on the target: $ uuu -b emmc encrypted-flash.bin 1.11 Verify Encrypted Boot Once the encrypted flash.bin image has been flashed to the device, verify that the encrypted image was authenticated and decrypted properly by validating no AHAB security events are triggered by haulting boot at U-Boot and using ahab_status command: => ahab_status Lifecycle: 0x00000008, OEM Open No Events Found! With no AHAB security events found, the target device has successfully booted an encrypted image. From here, the board can be moved into closed lifecycle if desired. References: [1] ELE API guide: "EdgeLock Enclave (ELE) API Reference Guide"