AIMLinux/AddOn/Security
Security is becoming a growing concern, especially when these devices connecte to the Internet,how to protect data from tampering, how to protect FW from malicious damage, how to ensure that the device can start safely... these are security considerations. This topic mainly introduces the Security Boot mechanism.
Contents
Security Boot[edit]
For security consideration, it is necessary that the hardware have some mechanism to ensure that the software it is running can be trusted. NXP i.MX6 series chip provides High Assurance Boot (HAB) feature which meets such a requirement. OEM can utilize it to make their product reject any system image which is not authorized for running. You can refer the " i.MX_6_Linux_High_Assurance_Boot_(HAB)_User's_Guide.pdf" file to learn more about HAB introduction,in this topic,we mainly introduce how to implement and test security boot.
Signature
Setup CST enviroment
1.Unpack the Code Siging Tools (CST) package (cst-2.3.2.tar.gz)
2.cd cst-2.3.2/keys
- Create a text file called serial, which contains 8 digits. For example: Fill in "12356789" to the serial file
- Create a text file called key_pass.txt, which contains two lines of identical text, such as "advantech_test". For example:
~/cst-2.3.2/keys$ cat key_pass.txt
advantech_test
advantech_test
- ./hab4_pki_tree.sh
- You can now create the signature keys. This script will generate private key and public key pairs in the working directory. For question prompt, enter "n", "n", "4096", "10", "4", "y" one by one.
3.cd ../crts
- ../linux64/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1
- Create the fuse table and binary to be flashed later. This command will generate root public key file "SRK_1_2_3_4_table.bin" and its corresponding hash "SRK_1_2_3_4_fuse.bin". The content of the latter will be later on burned to chip eFuse. NOTE: Don't leave space between the pem file names. Otherwise the generated SRK table and fuse file will not be correct.
- Show "SRK_1_2_3_4_fuse.bin" information. For example:
~/cst-2.3.2/crts$ hexdump -C SRK_1_2_3_4_fuse.bin
00000000 79 f5 61 26 6f cd d4 e9 ae d2 06 ff 5b f8 ea 40 |y.a&o.......[..@|
00000010 01 1c 32 97 0e e3 6b b0?13 c0 1e c8 88 eb 37 cc |..2...k.......7.|
00000020
Build secure images
1.Build uboot and kernel image for i.MX6 project (For example: RSB-4411 project).
- You can refer following URL to set up cross compiling environment (Setting up cross compiling environment):
2.get and build u-boot image
- git clone https://github.com/ADVANTECH-Corp/uboot-imx6.git -b imx_v2016.03_4.1.15_2.0.0_ga
- cd uboot-imx6/
- source environment for Yocto 2.1:source /opt/poky/2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
- Make sure the following message is defined in "./include/configs/mx6xxxx.h" (For example: mx6rsb4411.h).
/* uncomment for SECURE mode support */
#define CONFIG_SECURE_BOOT
#ifdef CONFIG_SECURE_BOOT
#ifndef CONFIG_CSF_SIZE
#define CONFIG_CSF_SIZE 0x4000
#endif
#endif
- Build SPL and u-boot image for i.MX6 project (For example: RSB-4411 project)
make mx6qrsb4411a1_1G_defconfig
make -j4 V=1 u-boot.imx all
- You can get SPL (SPL) image and u-boot (u-boot_crc.bin, u-boot_crc.bin.crc) image in uboot-imx6/ directory
3.get and build kernel image
- git clone https://github.com/ADVANTECH-Corp/linux-imx6.git -b imx_4.1.15_2.0.0_ga
- cd linux-imx6/
- source environment for Yocto 2.1
source /opt/poky/2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi - Build zImage:
make imx_v7_adv_defconfig
make -j 4 zImage - You can get zImage image in /arch/arm/boot/zImage directory
Sign uboot image
1.Copy SPL (SPL) and u-boot (u-boot_crc.bin, u-boot_crc.bin.crc) images to ~/cst-2.3.2/linux64 directory
2.Copy spl.csf to ~/cst-2.3.2/linux64 directory
- We will use the “HAB Blocks” information from previous section. Build SPL image, message:
- ./tools/mkimage -n board/freescale/mx6advantech/mx6qrsb4411a1_4x_MT41K128M16JT-125_1410022609-01.cfg.cfgtmp -T imximage -e 0x00908000 -d spl/u-boot-spl.bin SPL
Image Type: Freescale IMX Boot Image
Image Ver: 2 (i.MX53/6/7 compatible)
Mode: DCD
Data Size: 57344 Bytes = 56.00 kB = 0.05 MB
Load Address: 00907420
Entry Point: 00908000
HAB Blocks: 00907400 00000000 00009c00
DCD Blocks: 00910000 0000002c 00000320 - Open "spl.csf" file to edit the size in the "Blocks = " line...
Blocks = 0x907400 0x0 0x9C00 "SPL"
3.We provide a secure SPL image generation script "habsplimagegen.sh". Copy habsplimagegen.sh to ~/cst-2.3.2/linux64 directory
4../habsplimagegen.sh
- This will create certified SPL image "spl_signed"
5.Copy "uboot_normal.csf" file to ~/cst-2.3.2/linux64 directory
- We will use the “HAB Blocks” information from previous section. Build u-boot image, message:
./tools/mkimage -n board/freescale/mx6advantech/mx6qrsb4411a1_4x_MT41K128M16JT-125_1410022609-01.cfg.cfgtmp -T imximage -e 0x26800000 -d u-boot.bin u-boot.imx
./tools/mkimage -A arm -T firmware -C none -O u-boot -a 0x26800000 -e 0 -n "U-Boot 2016.03-dirty for mx6advantech board" -d u-boot.bin u-boot.img
Image Type: Freescale IMX Boot Image
Image Ver: 2 (i.MX53/6/7 compatible)
Mode: DCD
Data Size: 335872 Bytes = 328.00 kB = 0.32 MB
Load Address: 267ff420
Entry Point: 26800000
HAB Blocks: 267ff400 00000000 0004dc00
DCD Blocks: 00910000 0000002c 00000320 - Open "uboot_normal.csf" file to edit the size in the "Blocks = " line...
Blocks = 0x267FF400 0x0 0x4DC00 "u-boot_crc.bin"
6.We provide a secure u-boot image generation script " habubootimagegen.sh". Copy habubootimagegen.sh to ~/cst-2.3.2/linux64 directory
7../habubootimagegen.sh:This will create certified u-boot image "u-boot_normal_signed.bin".
Sign kernel image
1.Copy zImage to cst-2.3.2/linux64 directory
2.Copy genIVT file to cst-2.3.2/linux64 directory
- Get zImage length
hexdump -C zImage | tail -n 1
Example log:
00638f58 - The hexdump command above allows to learn the zImage size. Then you can modify the genIVT to reflect the proper sizes, in our example, the size of the zImage was "638f58" so the next 4kB boundary was "0x639000" as you can see in the genIVT. We need to edit genIVT file.
- Self Pointer: "0x10800000 + 0x639000 = 0x10E39000"
print $out pack("V", 0x10E39000); # Self Pointer - CSF Pointer: 0x10E39000 + 0x20
print $out pack("V", 0x10E39020); # CSF Pointer
3.Copy "zImage.csf" file to cst-2.3.2/linux64 directory
4.The "zImage.csf" file for the zImage in order to create the CSF blob and generate the signed image.
- Edit the size in the "Blocks = " line...
Blocks = 0x10800000 0x0 0x639020 "zImage-pad-ivt.bin"
5.Copy "habZimagegen.sh" file to cst-2.3.2/linux64 directory
- We need to edit habZimagegen.sh file
echo "extend zImage to 0x639000..."
objcopy -I binary -O binary --pad-to=0x639000 --gap-fill=0x00 zImage zImage-pad.bin
6.Execute "habZimagegen.sh" to generate "zImage_signed" file.
./ habZimagegen.sh
Burn
1.Copy "spl_signed", "u-boot_crc.bin.crc", "u-boot_normal_signed.bin", " zImage_signed " to USB disk
2.Burn the chip fuse to enable HAB boot
- The fuse table generated in the third point is what needs to be flashed to the device. However, the hexdump command above doesn’t show the values in their correct endianness, instead the command below will be more useful.
- The following command gives you what needs to be flashed in the proper order. Dump the content of the eFuse file in ~/cst-2.3.2/crts directory. They will be burned to chip with kernel utilities.
hexdump -e '/4 "0x"' -e '/4 "%X""\n"' < SRK_1_2_3_4_fuse.bin
Log message:
0x2661F579
0xE9D4CD6F
0xFF06D2AE
0x40EAF85B
0x97321C01
0xB06BE30E
0xC81EC013
0xCC37EB88
- !!! CAUTION!!! Make sure you perform all the steps correctly. Otherwise you may damage a chip permanently. It is strongly recommended that a socket board is used, so in the worst case scenario, we can change a chip without totally damaging the board.
- Normal boot into kernel.
- cd /sys/fsl_otp
- Use the 8 dwords generated in last step and burn them to SRK fuse one by one.
echo 0x2661F579 > HW_OCOTP_SRK0
echo 0xE9D4CD6F > HW_OCOTP_SRK1
echo 0xFF06D2AE > HW_OCOTP_SRK2
echo 0x40EAF85B > HW_OCOTP_SRK3
echo 0x97321C01 > HW_OCOTP_SRK4
echo 0xB06BE30E > HW_OCOTP_SRK5
echo 0xC81EC013 > HW_OCOTP_SRK6
echo 0xCC37EB88 > HW_OCOTP_SRK7 - Verify that the correct value has been burned. Type command:
ls | grep "SRK.$" | xargs cat
Log message:
…/sys/fsl_otp# ls | grep "SRK.$" | xargs cat
0x2661f579
0xe9d4cd6f
0xff06d2ae
0x40eaf85b
0x97321c01
0xb06be30e
0xc81ec013
0xcc37eb88
3.Insert USB disk to the device. Suppose the USB disk path is /run/media/sda1
4.Burn the secure SPL image (spl_signed) to SPI.
cd /run/media/sda1
flash_erase /dev/mtd0 0 192
dd if=spl_signed of=/dev/mtd0 bs=512 seek=2
sync
5.Burn the secure u-boot image (u-boot_normal_signed.bin, u-boot_crc.bin.crc) to emmc.
dd if=u-boot_crc.bin.crc of=/dev/mmcblk0 bs=512 seek=2 conv=fsync
dd if=u-boot_normal_signed.bin of=/dev/mmcblk0 bs=512 seek=3 conv=fsync
sync
6.Burn the secure kernel image "zImage_signed" to emmc.
cp zImage_signed /dev/mmcblk0p1/zImage
sync
7.At this point the whole HAB chain is not actually enabled, because the default chip secure config is "open" which ignores any authentication error and continues the boot process. We will enable it in the next step.
Test
1.Boot the device again and press "Enter" key to stay in the u-boot stage
Adv-Boot SPL 2016.03 (Nov 08 2017 - 14:17:25)
BOOT_DEVICE_AUTO
MMC read: dev # 0, block # 3,count 1200 ...
booting from SD
Jumping to U-Boot
U-Boot 2016.03 (Nov 08 2017 - 14:17:25 +0800)
CPU: Freescale i.MX6D rev1.5 at 792MHz
CPU: Industrial temperature grade (-40C to 105C) at 37C
.......
Net: Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot: 0
=>
- Check hab status for u-boot when HAB disabled. The following message is a correct status.
=> hab_status
Secure boot disabled
HAB Configuration: 0xf0, HAB State: 0x66
No HAB Events Found! - Modify U-Boot bootcmd so it includes the HAB command that checks the kernel:
=> load mmc 0 10800000 zImage
log:
reading zImage
6015320 bytes read in 294 ms (19.5 MiB/s) - After you type following command: if the device is "open", you will see following message:
=> hab_auth_img 10800000 0x639000
log:
hab fuse not enabled
2.Turn on chip HAB.
- !!! CAUTION !!! Make sure you perform all the steps correctly. After this step, there will be no way back, and a chip may permanently be bricked.
- Normal boot into kernel.
- cd /sys/fsl_otp
- Turn on RNG_TRIM
echo 0x00040000 > HW_OCOTP_MEM0 - See hab status for device "open":
cat HW_OCOTP_CFG5
log:
0x0 - Put SEC_CONFIG to close (turn on chip security).
echo 0x2 > HW_OCOTP_CFG5 - See hab status for device "close":
cat HW_OCOTP_CFG5
log:
0x2
3.Boot the device again and press "Enter" key to stay in the u-boot stage. The security patch should work now.
- Successful authentication will give the following dump message in U-Boot load. Check hab status for u-boot when HAB enabled. The following message is a correct status.
=> hab_status
Log:
Secure boot enabled
HAB Configuration: 0xcc, HAB State: 0x99
No HAB Events Found! - Modify U-Boot bootcmd so it includes the HAB command that checks the kernel:
=> load mmc 0 10800000 zImage
log:
reading zImage
6015320 bytes read in 294 ms (19.5 MiB/s)
- After typing following command: if the device is "close", will see following message. Successful authentication will give the following dump message in zImage load:
=> hab_auth_img 10800000 0x639000
log:
Authenticate image from DDR location 0x10800000...
Secure boot enabled
HAB Configuration: 0xcc, HAB State: 0x99
No HAB Events Found!
- set and save loading kernel image address
=> setenv loadaddr 10800000
=> saveenv
log:
Saving Environment to SPI Flash...
JEDEC ID: 0xef:0x40:0x16
Erasing SPI flash...Writing to SPI flash..................................SUCCESS
.................................................................................
done - Boot the device again. The security patch should work now. Successful authentication will give the following dump message in zImage load:
...
...
Kernel image @ 0x10800000 [ 0x000000 - 0x638f58 ]
## Flattened Device Tree blob at 18000000
Booting using the fdt blob at 0x18000000
Authenticate image from DDR location 0x10800000...
Secure boot enabled
HAB Configuration: 0xcc, HAB State: 0x99
No HAB Events Found!
Using Device Tree in place at 18000000, end 1800e5df
Starting kernel ...