1 前言
安全引导是一种行业标准,用于确保设备引导一个受信任的原始设备制造商软件。NXP i.MX设备通过使用OEM受信任的根密钥来支持信任链(RoT)。通常,安全引导机制 (secure boot) 涉及对Bootloater和操作系统OS内核映像的签名和认证。
签名方法涉及通过分析构建日志确定需要签名的boot image部分,然后使用代码签名工具 (Code Signing Tool) 进行签名。这种方法通常是手动的,容易出错,可能导致签名/认证失败,最终可能导致引导失败。为了消除这种错误,NXP设计并提供了一种自动化方法,该方法分析输入的引导映像并使用CST进行签名。
作为NXP安全参考设计的一部分,NXP BSP发布包含了一个meta-nxp-security-reference-design/meta-secure-boot
Yocto meta layer,支持i.MX引导映像签名自动化。本文主要介绍如何导入该layer并根据自己的配置实现自动化镜像签名的方法。
2 工具
2.1 Code Signing Tool
Code Signing TOOL 目前NXP提供的最新版为cst-3.4.0。该工具包含了用于生成密钥公钥的脚本,生成公钥hash和fuse的工具和进行代码签名的工具。如何使用该工具可参考博文使用CST进行secure boot。默认情况下,NXP CST签名工具使用i.MX 8/8x/8ULP/9系列设备的ECC P256-SHA256类型作为标准密钥,以及i.MX 6/7/8M系列设备的RSA 2048-SHA256类型作为标准密钥。这些密钥应该在CST的下载位置中提供。请参考CST包中的CST用户指南以生成密钥、证书、SRK表/熔丝,并获取更多信息。
2.2 NXP CST Signer
NXP创建的NXP CST Signer工具分析输入的NXP BSP映像,提取需要签名的映像的偏移量和大小,并为CST准备相应的命令序列文件CSF以进行签名。此工具作为meta layer的一部分用于支持映像签名。
NXP CST Signer工具具有以下特性:
- 支持签名i.MX 6/7/8M系列设备的HAB和i.MX 8/8x/8ULP/9系列设备的AHAB映像。
- 分析输入映像以签署IVT/FIT/容器格式的映像。
- 从输入映像中提取偏移量和大小,并构造CSF。
- CST签名器存储库中包含默认配置文件,填充了与要使用的密钥、证书和标志相关的基本信息,适用于HAB和AHAB设备。
详细可参考官方Github NXP CST Signer Tool
3 构建secure boot的Yocto配置
本节介绍根据官方手册的方法进行Yocto构建
3.1 Yocto配置
- 设置Yocto构建环境和配置
bash
repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-mickledore -m imx-6.1.55-2.2.0_security-reference-design.xml
repo sync
DISTRO=<DISTRO> MACHINE=<MACHINE> source imx-setup-release.sh -b <build
directory>
- 将
meta-secure-boot
layer加入Yocto项目
bash
bitbake-layers add-layer ../sources/meta-nxp-security-reference-design/metasecure-boot
- 在local.conf中加入CST的路径
CST_PATH
(绝对路径)
bash
echo "CST_PATH = \"<_absolute location_ to cst package>\"" >> conf/local.conf
3.2 生成signed bootloader/kernel/WIC image
根据下面命令生成对应的signed bootloader,kernel和image镜像:
- Build a signed WIC image.
bitbake core-image-minimal-secure-boot
- Build a signed imx-boot bootloader (for i.MX 8M/8/8x/8ULP/9x).
bitbake imx-boot-signature
- Build a signed U-Boot bootloader (for i.MX 6/7)
bitbake u-boot-signature
- Build a signed Linux kernel image.
bitbake linux-imx-signature
3.3 启动signed image
Yocto构建的输出包含三个已签名的文件:
- Signed Bootloader
- Signed Kernel image
- SDcard (WIC) image (Contains signed bootloader and signed kernel images only)
根据开发场景,可以将签名的Bootloader或Kernel中的任一部分下载到目标设备上。签名的WIC映像用于部署签名的Bootloader序和Kernel到设备上。
- Secure boot in OPEN/OEM OPEN lifecycle
建议在CLOSE芯片之前下载签名的映像并验证安全引导。有关如何编程SRK熔丝、验证签名并关闭部件以启用安全引导的更多信息,请参阅安全引导用户指南,根据SoC在HAB4 UBoot Guide或AHAB UBoot Guides中。 - Secure boot in CLOSED/OEM CLOSED lifecycle
当SoC处于CLOSED生命周期状态时,相同配置的签名镜像必须以CLOSED安全状态引导设备,以确保在设备上运行可信镜像
4 修改定制化的Yocto配置
4.1 修改imx-setup-release.sh
第三节中通过bitbake-layers add-layer
命令手动添加了secure-boot的layer,这会导致在使用Yocto构建时每次都需要手动输入来添加layer。为了可以在每次构建时自动加入该layer,在source/meta-imx/tools/imx-setup-release.sh
文件中加入下面这段代码,这样每次执行source imx-setup-release.sh -b build
时,就会自动将secure-boot layer加入到layer list中。
bash
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-nxp-security-reference-design/meta-secure-boot\"" >> $BUILD_DIR/conf/bblayers.conf
根据官网手册还提到,需要指定CST工具的PATH,因为在签名过程中,程序会根据CST路径调用CST工具执行签名操作。同样在source/meta-imx/tools/imx-setup-release.sh
文件中加入下面这段代码,将路径填入local.conf
文件
bash
echo CST_PATH = \"\${BSPDIR}/cst-3.4.0/\" >> $BUILD_DIR/conf/local.conf
4.2 修改uboot defconfig文件
要使能secure boot功能,需要在指定的uboot defconfig文件中添加,这样boot env中sec_boot会被配置成=y,而且会使能ahab功能,这样启动时就可以通过ahab_status进行event检测
bash
CONFIG_AHAB_BOOT=y
4.3 修改依赖的uboot和kernel
以下是source/meta-nxp-security-reference-design/meta-secure-boot/recipes-secure-boot/linux/linux-imx-signature.bb
文件的前十段
bash
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit cst hab deploy features_check
REQUIRED_MACHINE_FEATURES = "linux-imx-signature"
DEPENDS += "cst-signer linux-gen7 u-boot-gen7"
DEPENDS:append:ahab = " imx-boot"
DEPENDS:append:mx8m-generic-bsp = " imx-boot"
其中默认的依赖是DEPENDS += "cst-signer linux-imx u-boot-imx"
,如果在项目中使用了自己剪裁的uboot或kernel的话,需要将这里的依赖改为自定义的uboot或kernel名称。同理source/meta-nxp-security-reference-design/meta-secure-boot/recipes-secure-boot/imx-mkimage/imx-boot_%.bbappend
文件中的依赖uboot名称也需要更改。
在source/meta-nxp-security-reference-design/meta-secure-boot/recipes-secure-boot/images
文件夹中,可以指定自己所需要签名的image镜像,指定require就可以选择需要签名的原始镜像
bash
DESCRIPTION = "Secure Boot image: core-image-customization"
LICENSE = "MIT"
# 依赖的原始镜像文件core-image-customization.bb
require recipes-core/images/core-image-customization.bb
inherit secure-boot-image
# 签名镜像文件core-image-customization-secure-boot
export IMAGE_BASENAME = "core-image-customization-secure-boot"
确定并更改完所需要的依赖后,即可执行如下命令构建signed bootloader, kernel, image
bash
# Use the layer meta-secure-boot provided by NXP to signature
# Build the signed bootloader image
$ bitbake imx-boot-signature
# Build the signed kernel image
$ bitbake linux-imx-signature
# Build the signed bootloader and rootfs
$ bitbake core-image-customization-secure-boot
5 通过服务器签名
一般项目中,处于安全的考量,私钥是不会放在编译服务器上的。公司都会提供签名服务器,我们在任何情况都不会知道私钥。而通过服务器签名的过程就是把image放进签名服务器,返回签过名的image和一个公钥的hash。
服务器签名就与不同的用户关联很大了,我们需要做的是更改cst-3.4.0/ca/openssl.cnf
这个文件,在里面完成服务器的一些配置,例如
bash
openssl_conf = openssl_def
[openssl_def]
engines = engine_section
[engine_section]
signserver = signserver_section
[signserver_section]
engine_id = signserver
dynamic_path = $topcst_dir/xxx
init = 0
CERT_PATH=$topcst_dir/crts/xxx.pem
KEY_PATH=$topcst_dir/crts/xxx.key
CA_PATH=$topcst_dir/crts/xxxPKI.pem
URL=https://xxxxxxx
还有一个值得注意的地方是,因为服务器签名需要与服务器联网,所以在source/meta-nxp-security-reference-design/meta-secure-boot/recipes-secure-boot/linux/linux-imx-signature.bb
和source/meta-nxp-security-reference-design/meta-secure-boot/recipes-secure-boot/imx-mkimage/imx-boot-signature.bb
文件中使能do_compile联网功能,在do_compile[depends] += "imx-boot:do_deploy"
下面添加一行
bash
do_compile[depends] += "imx-boot:do_deploy"
do_compile[network]="1"
由于服务器签名涉及不同公司的做法,所以只是简单讲解。
6 结果
通过构建得到签名后的Bootloader和包含image和rootfs的wic文件,在build/tmp/deploy/images/xxx
目录下
烧录bootloader和wic文件到芯片,进入uboot,通过fuse prog -y 16 0~7 xxx
写入公钥的hash(OTP操作只有一次机会,fuse不可更改)
然后在uboot下输入ahab_status
,如果成功,则会显示如下
然后验证signed OS container,输入run loadcntr
加载OS container,输入auth_cntr
验证
输入boot
启动kernel,签名后kernel是可以正常启动的,说明签名及验签成功
最后烧写fuse close设备,这样未经签名或者签名错误的程序将无法在此设备上启动。
reference:
[1] IMX_LINUX_USERS_GUIDE.pdf
[2] https://github.com/nxp-imx-support/nxp-cst-signer
[4] https://github.com/nxp-imx/uboot-imx/blob/lf_v2023.04/doc/imx/ahab/guides/mx8ulp_9x_secure_boot.txt