CL-SOM-iMX7: U-Boot: Building Secure Images
Contents
Overview
Executing trusted and authentic code on an applications processor starts with securely booting the device.
The i.MX 7 processors provides this capability with the High Availability Boot (HAB) component of the on-chip ROM. The ROM is responsible for loading the initial program image from the boot medium. HAB enables the ROM to authenticate the U-Boot by using digital signatures.
This article provides a brief set of instructions related to secure boot with CompuLab i.MX7 platforms. For additional details please refer to Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using HABv4.
Building Secure Firmware images for CL-SOM-iMX7
Getting U-Boot sources
The following article assumes that you have created /home/development/cl-som-imx7/u-boot directory for the the CL-SOM-iMX7 U-Boot development. U-Boot sources with CompuLab's patch can be downloaded from CompuLab's U-Boot github.
Git clone
- Install git version control system.
- Create a clone of U-Boot tree
cd /home/development/cl-som-imx7/u-boot git clone https://github.com/compulab/u-boot.git u-boot-cl-som-imx7-hab cd /home/development/cl-som-imx7/u-boot/u-boot-cl-som-imx7-hab
- Create a branch for HAB development. It is recommended to use exactly the same baseline to avoid merge conflicts.
git checkout -b cl-som-imx7-hab v2018.11-cl-som-imx7-hab
Building the secure firmware images
- First, compile U-Boot. The following commands create the binaries u-boot-ivt.img and SPL (along with other image types):
export ARCH=arm export CROSS_COMPILE=arm-none-linux-eabi- make mrproper make cl-som-imx7_defconfig && make
Code Signing Example
Code Signing Tool (CST)
Download CST
- Download NXP's Code Signing Tool.
Sign in (registration is required) to your NXP account prior to downloading the CST tool |
Extract the CST archive
cd /home/development/cl-som-imx7/u-boot gunzip -c /path/to/downloaded/cst-3.1.0.tgz | tar xzvf - mv release cst
Create a PKI Tree
cd /home/development/cl-som-imx7/u-boot/cst/keys ./hab4_pki_tree.sh +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ This script is a part of the Code signing tools for Freescale's High Assurance Boot. It generates a basic PKI tree. The PKI tree consists of one or more Super Root Keys (SRK), with each SRK having two subordinate keys: + a Command Sequence File (CSF) key + Image key. Additional keys can be added to the PKI tree but a separate script is available for this. This this script assumes openssl is installed on your system and is included in your search path. Finally, the private keys generated are password protectedwith the password provided by the file key_pass.txt. The format of the file is the password repeated twice: my_password my_password All private keys in the PKI tree are in PKCS #8 format will be protected by the same password. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Do you want to use an existing CA key (y/n)?: n Do you want to use Elliptic Curve Cryptography (y/n)?: n Enter key length in bits for PKI tree: 2048 Enter PKI tree duration (years): 10 How many Super Root Keys should be generated? 4 Do you want the SRK certificates to have the CA flag set? (y/n)?: y A default 'serial' file was created! A default file 'key_pass.txt' was created with password = test! ...
Generate SRK Table
cd ../crts/ ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c SRK1_sha256_2048_65537_v3_ca_crt.pem,SRK2_sha256_2048_65537_v3_ca_crt.pem,SRK3_sha256_2048_65537_v3_ca_crt.pem,SRK4_sha256_2048_65537_v3_ca_crt.pem
CSF Description Template
- Generate the example command sequence file template.
cd .. mkdir bin -p cd bin cat <<EOF >csf.txt #Illustrative Command Sequence File Description [Header] Version = 4.2 Hash Algorithm = sha256 Engine = ANY Engine Configuration = 0 Certificate Format = X509 Signature Format = CMS [Install SRK] File = "../crts/SRK_1_2_3_4_table.bin" # Index of the key location in the SRK table to be installed Source index = 0 [Install CSFK] # Key used to authenticate the CSF data File = "../crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem" [Authenticate CSF] [Install Key] # Key slot index used to authenticate the key to be installed Verification index = 0 # Target key slot in HAB key store where key will be installed Target Index = 2 # Key to install File= "../crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem" [Authenticate Data] # Key slot index used to authenticate the image data Verification index = 2 # Address Offset Length Data File Path Blocks = blk_vals file_name EOF
Signing U-Boot Firmware
CSF Description
- Generate the example command sequence files for the U-Boot and SPL.
awk 'BEGIN {file_name="\"/home/development/cl-som-imx7/u-boot/u-boot-cl-som-imx7-hab/SPL\""} /HAB Blocks:/ {blk_vals=$3 " " $4 " " $5} {sub(/blk_vals/, blk_vals); sub(/file_name/, file_name)} printline {print} ENDFILE {printline=1}' ../../u-boot-cl-som-imx7-hab/SPL.log ./csf.txt > ./csf-spl.txt awk 'BEGIN {file_name="\"/home/development/cl-som-imx7/u-boot/u-boot-cl-som-imx7-hab/u-boot-ivt.img\""} /HAB Blocks:/ {blk_vals=$3 " " $4 " " $5} {sub(/blk_vals/, blk_vals); sub(/file_name/, file_name)} printline {print} ENDFILE {printline=1}' ../../u-boot-cl-som-imx7-hab/u-boot-ivt.img.log ./csf.txt > ./csf-uboot.txt
CSF Binary Signature
- Generate the CSF binary signature for the U-Boot and SPL.
../linux64/bin/cst --o csf-spl.bin --i csf-spl.txt ../linux64/bin/cst --o csf-uboot.bin --i csf-uboot.txt
Attach CSF Signature
- Attach CSF Signature to the U-Boot and SPL Images.
cat /home/development/cl-som-imx7/u-boot/u-boot-cl-som-imx7-hab/SPL csf-spl.bin > spl-signed cat /home/development/cl-som-imx7/u-boot/u-boot-cl-som-imx7-hab/u-boot-ivt.img csf-uboot.bin > u-boot-signed
Generate Firmware Image
- Merge the SPL and U-Boot images into one firmware image.
dd if=/dev/zero count=640 bs=1K | tr '\000' '\377' > cl-som-imx7-firmware dd if=spl-signed of=cl-som-imx7-firmware bs=1K seek=1 conv=notrunc dd if=u-boot-signed of=cl-som-imx7-firmware bs=1K seek=64 conv=notrunc mv cl-som-imx7-firmware /tftproot/cl-som-imx7/test/
Signing Kernel Image
Image Parameters
- Calculate kernel image parameters.
Replace /path/to/zimage/zImage with the actual kernel image path.
zimage_path=/path/to/zimage/zImage read zimage_pad_size <<< $(ls -l $zimage_path | awk '{size=int(($5+0xfff)/0x1000)*0x1000; print size}') zimage_self_ptr=$(printf "0x%x\n" $(($zimage_pad_size+0x80800000))) zimage_csf_ptr=$(printf "0x%x\n" $(($zimage_self_ptr+0x20))) zImage_pad_ivt_size=$(printf "0x%x\n" $(($zimage_pad_size+0x20)))
Image Vector Table
- Generate the image vector table.
cat <<EOF >genIVT #! /usr/bin/perl -w use strict; open(my \$out, '>:raw', 'ivt.bin') or die "Unable to open: \$!"; print \$out pack("V", 0x412000D1); # Signature print \$out pack("V", 0x80800000); # Load Address print \$out pack("V", 0x0); # Reserved print \$out pack("V", 0x0); # DCD pointer print \$out pack("V", 0x0); # Boot Data print \$out pack("V", $zimage_self_ptr); # Self Pointer *ivt print \$out pack("V", $zimage_csf_ptr); # CSF Pointer *csf print \$out pack("V", 0x0); # Reserved close(\$out); EOF chmod +x genIVT ./genIVT
Image Padding
objcopy -I binary -O binary --pad-to $zimage_pad_size --gap-fill=0x00 $zimage_path zImage_pad
Adding IVT
- Append the image vector table at the end of the padded kernel image.
cat zImage_pad ivt.bin > zImage_pad_ivt
CSF Description
- Generate the example command sequence files for the kernel image.
awk -v blk_vals="0x80800000 0x000 $zImage_pad_ivt_size" ' {sub(/blk_vals/, blk_vals); sub(/file_name/, "\"zImage_pad_ivt\""); print}' ./csf.txt > ./csf-zimage.txt
CSF Binary Signature
- Generate the CSF binary signature for the kernel image.
../linux64/bin/cst --o csf-zImage --i csf-zimage.txt
Attach CSF Signature
- Attach CSF Signature to the kernel image.
cat zImage_pad_ivt csf-zImage > zImage_signed
Test the Images
U-Boot Firmware
Update the U-Boot Firmware
- Follow the Firmware Update instructions to update the firmware with the new image.
- Reset the CL-SOM-iMX7 evaluation platform.
Fuse Programming
- Display the new fuse values for programming.
hexdump -e '/4 "0x"' -e '/4 "%X""\n"' /home/development/cl-som-imx7/u-boot/cts/crts/SRK_1_2_3_4_fuse.bin 0x5AD817FB 0xD4C8E0B3 0xA7C3870C 0x6BCDDBAD 0x2B784081 0x2B57810 0xC5F3200B 0x6A182382
Verify the values. The fuses can only be programmed once. |
- Program the fuse values from the hexdump command.
fuse prog 6 0 0x5AD817FB fuse prog 6 1 0xD4C8E0B3 fuse prog 6 2 0xA7C3870C fuse prog 6 3 0x6BCDDBAD fuse prog 7 0 0x2B784081 fuse prog 7 1 0x2B57810 fuse prog 7 2 0xC5F3200B fuse prog 7 3 0x6A182382
- Reset the CL-SOM-iMX7 evaluation platform.
- Verify the U-Boot firmware signature
CL-SOM-iMX7 # hab_status Secure boot disabled HAB Configuration: 0xf0, HAB State: 0x66 No HAB Events Found!
Kernel Image
Load Image
- Obtain an SD card. Any commercially available micro SD card of 1GB (or larger) may be used.
- Create a first partition on it. The partition can be formatted either ext2/3/4 or FAT file system.
- Copy the kernel image zImage to the root directory on the first partition of the SD card.
- Plug the SD card into the SD socket (P9) on the SBC-iMX7.
- Use the following U-Boot commands to load the kernel image to the RAM:
CL-SOM-iMX7 # mmc rescan CL-SOM-iMX7 # load mmc 1:1 ${loadaddr} zImage
Test the Image
- Verify the kernel image signature
CL-SOM-iMX7 # setexpr.l zimage_pad_size ${filesize} / 1000 CL-SOM-iMX7 # setexpr.l zimage_pad_size $zimage_pad_size * 1000 CL-SOM-iMX7 # hab_auth_img ${loadaddr} $filesize} ${zimage_pad_size} Authenticate image from DDR location 0x80800000... Secure boot enabled HAB Configuration: 0xcc, HAB State: 0x99 No HAB Events Found!
Close the Device
After the device successfully boots a signed image without generating any HAB events, it is safe to secure, or close, the device.
Closing the device is irreversible. The fuses can only be programmed once. |
CL-SOM-iMX7 # fuse prog 1 3 0x2000000