i.MX系列芯片Yocto secure boot镜像签名

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配置

  1. 设置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>
  1. meta-secure-bootlayer加入Yocto项目
bash 复制代码
bitbake-layers add-layer ../sources/meta-nxp-security-reference-design/metasecure-boot
  1. 在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镜像:

  1. Build a signed WIC image.
    bitbake core-image-minimal-secure-boot
  2. Build a signed imx-boot bootloader (for i.MX 8M/8/8x/8ULP/9x).
    bitbake imx-boot-signature
  3. Build a signed U-Boot bootloader (for i.MX 6/7)
    bitbake u-boot-signature
  4. 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.bbsource/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

[3] https://github.com/nxp-imx-support/meta-nxp-security-reference-design/tree/mickledore-6.1.55-2.2.0/meta-secure-boot

[4] https://github.com/nxp-imx/uboot-imx/blob/lf_v2023.04/doc/imx/ahab/guides/mx8ulp_9x_secure_boot.txt

相关推荐
huangkj-henan6 分钟前
DA217应用笔记
笔记
Young_202202028 分钟前
学习笔记——KMP
笔记·学习
Leo.yuan22 分钟前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
Runing_WoNiu30 分钟前
MySQL与Oracle对比及区别
数据库·mysql·oracle
秀儿还能再秀41 分钟前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
WCF向光而行1 小时前
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
笔记·学习
天道有情战天下1 小时前
mysql锁机制详解
数据库·mysql
看山还是山,看水还是。1 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0011 小时前
Redis运行时的10大重要指标
数据库·redis·缓存
CodingBrother1 小时前
MySQL 中单列索引与联合索引分析
数据库·mysql