By Toradex秦海
1). 简介
嵌入式设备对于网络安全的要求越来越高,而 Secure boot就是其中重要的一部分。 NXP i.MX8MM/i.MX8MP 处理器基于 HABv4 特性来提供 Secure boot 启动过程中的 Chain of Trust; HABv4 是基于公共密钥加密 (Public Key Cryptography) 和数字签名 (Digital Signature) 技术来实现 Secure boot 的,一个简单的流程图参考如下。本文就基于 NXP i.MX8M Mini 处理器平台测试部署 Secure boot 功能。
本文所演示的平台来自于 Toradex Verdin i.MX8MM 嵌入式平台,主要测试基本的 Chain of Trust,也就是 U-boot和Linux Kernel 两个层级的加密和验证启动,后面 Rootfs 以及 Application 层面暂不涉及。
2. 准备
a). Verdin i.MX8MM ARM核心版配合Dahlia 载板,并连接调试串口用于测试。
b). 参考这里下载 Toradex Yocto Linux BSP6 Reference Image 用于后续测试,目前最新的是 6.6.0 版本。
3). 生成PKI Tree文件
a). 从NXP官方网站下载Code Signing Tools软件包(需注册),目前最新版本是3.4.0版本,然后解压后使用预设的脚本生成Public Key Infrastructure (PKI) tree,用于后面签名U-boot/Linux Kernel Image文件
--------------------------------
$ tree -L 1 cst-3.4.0/
cst-3.4.0/
├── add-ons
├── BUILD.md
├── ca
├── code
├── crts
├── Dockerfile
├── Dockerfile.hsm
├── docs
├── keys
├── LICENSE.bsd3
├── LICENSE.hidapi
├── LICENSE.openssl
├── linux32
├── linux64
├── Makefile
├── mingw32
├── Release_Notes.txt
└── Software_Content_Register_CST.txt
--------------------------------
b). 生成PKI TREE
./ 首先创建 serial和key_pass.txt 文件
--------------------------------
$ cd .../cst-3.4.0/keys
### create serial number for OpenSSL certification ###
$ vi serial
1234567C
### create key_pass for protection of private keys
$ vi key_pass.txt
Toradex123!
Toradex123!
--------------------------------
./ 运行CST工具预制脚本通过交互方式生成PKI TREE,这里生成一个2048bit RSA key SRK PKI TREE示例,更多可以参考如下U-Boot源代码中的文档说明
--------------------------------
### generate PKI TREE ###
$ ./hab4_pki_tree.sh
...
Do you want to use an existing CA key (y/n)?: n
Key type options (confirm targeted device supports desired key type):
Select the key type (possible values: rsa, rsa-pss, ecc)?: rsa
Enter key length in bits for PKI tree: 2048
Enter PKI tree duration (years): 10
How many Super Root Keys should be generated? 1
Do you want the SRK certificates to have the CA flag set? (y/n)?: y
...
### check generated SRK keys ###
$ ls SRK*
SRK1_sha256_2048_65537_v3_ca_key.der SRK1_sha256_2048_65537_v3_ca_key.pem
### generate HABv4 SRK Table 和 Efuse Hash ###
$ 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 -f 1
Number of certificates = 1
SRK table binary filename = SRK_1_2_3_4_table.bin
SRK Fuse binary filename = SRK_1_2_3_4_fuse.bin
SRK Fuse binary dump:
SRK HASH[0] = 0x3D06A4A9
SRK HASH[1] = 0x4BC55D12
SRK HASH[2] = 0xA5F45E7F
SRK HASH[3] = 0x1F1F68FC
SRK HASH[4] = 0x3B9B4AE8
SRK HASH[5] = 0xFC658293
SRK HASH[6] = 0x40A706C9
SRK HASH[7] = 0x94A9139E
### check SRK Table and Efuse Hash ###
$ ls SRK_*
SRK_1_2_3_4_fuse.bin SRK_1_2_3_4_table.bin
--------------------------------
c). 上面最后生成的两个文件就是我们后面签名和 fuse 设备需要用到的,”SRK_1_2_3_4_table.bin” 文件是 SRK Table ,用于签名 Container Image ;”SRK_1_2_3_4_fuse.bin” 文件是Efuse Hash,用于 fuse 到 Verdin i.MX8MM 设备的 eFuse 。更多 CST 工具使用说明可以参考如下 CST User Guide 文档
cst-3.4.0/docs/CST_UG.pdf
4). Boot Container 配置和签名
a). 参考这里说明下载 Toradex Yocto Linux BSP 6.x.y 版本 U-boot源代码,默认配置并未使能 HABv4 功能支持,需要在 config 中使能如下选项,当前 Verdin i.MX8MM 使用的 Downstream U-boot 版本 2022.04 还需要一个 patch 来保证开启 HABv4 后 SPL 启动成功,修改完成后重新编译 U-Boot 文件。
./ U-boot 配置修改
--------------------------------
### add HAB and related crypto driver support ###
→ ARM architecture
[*] Support i.MX HAB features
→ SPL / TPL
[*] Support crypto drivers
→ Init options > Start-up hooks
[*] Call arch-specific init after relocation, when console is ready
### remove some modules to reduce SPL size ###
→ SPL / TPL
[ ] Suppport USB Gadget drivers
Library routines > Hashing Support
[ ] Enable SHA1 support in SPL
--------------------------------
./ Patch 文件
--------------------------------
--- a/board/toradex/verdin-imx8mm/spl.c
+++ b/board/toradex/verdin-imx8mm/spl.c
@@ -59,7 +59,7 @@ void spl_board_init(void)
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
if (ret)
- printf("Failed to initialize %s: %d\n", dev->name, ret);
+ printf("Failed to initialize caam_jr(FSL_CAAM) : %d\n", ret);
}
}
--------------------------------
b). 参考如下文档,使用编译生成的U-Boot 相关文件打包生成 Verdin iMX8MM Boot Container Image 文件 ”flash.bin”
Specifics: Build U-Boot for NXP i.MX 8M Mini/Plus-based SoMs | Toradex Developer Center
./ imx-mkimage 工具生成 Boot container image 的一些打印参数需要保留后面生成 csf 文件时候需要
--------------------------------
### generate boot container image flash.bin ###
$ make clean; make SOC=iMX8MM V=1 dtbs=fsl-imx8mp-evk.dtb flash_evk_emmc_fastboot
...
...
========= OFFSET dump =========
Loader IMAGE:
header_image_off 0x0
dcd_off 0x0
image_off 0x40
csf_off 0x35c00
spl hab block: 0x7e0fc0 0x0 0x35c00
Second Loader IMAGE:
sld_header_off 0x5fc00
sld_csf_off 0x60c20
sld hab block: 0x401fcdc0 0x5fc00 0x1020
------------------------------