Yocto meta-toradex-security layer 使用 TI AM62 安全启动功能

By Toradex 胡珊逢

简介

Arm 处理器的 Secure Boot 安全启动功能能够有效防止在设备上运行非授权的或者恶意窜改的固件。Secure Boot 系统在启动时会使用烧录的处理器上的密钥验证 Bootloader,Bootloader 会验证 kernel FIT 镜像,而 kernel 继续验证 rootfs 的有效性。这一逐个验证的流程成为 Chain of Trust。用户如果使用传统方法使用启动功能需用需要依次实现上述的每个环节。借助meta-toradex-securitylayer,只要几行简单的配置即可实现。

生成密钥

安全启动依赖于匹配的密钥对来验证软件。要启用安全启动,您需要将公钥烧录到设备的 OTP 存储器中。该密钥必须与用于签名已验证固件的私钥相匹配。

TI 设备使用三组密钥对实现安全启动:

  • MEK(Manufacture Encryption Key):由 TI 提供并永久烧录至 SoC 中,用于验证 TI 签名软件且不可更改。

  • SMPK(Secondary Manufacture Public Key):由用户创建并烧录到设备中,用于验证用户生成的引导加载程序的签名。

  • BMPK(Backup Manufacture Public Key):可选的用户生成备份密钥。若 SMPK 丢失或遭泄露,系统可重新配置为使用 BMPK 来验证引导加载程序的签名。

SMPK 和 BMPK 用于签名引导加载程序,因此该密钥的生成和管理必须谨慎处理,并做和完善的备份。

在写该文章时生成密钥需要使用 OpenSSL 1.1.1 版本,除非 TI 在后续新版本软件中注明,否则请使用openssl version命令查看当前系统的 OpenSSL 版本。如果本版不匹配,可以使用下面命令在 Linux 系统安装。

$ wget https://ftp.debian.org/debian/pool/main/o/openssl/
openssl_1.1.1w-0+deb11u1_amd64.deb
$ wget http://ftp.debian.org/debian/pool/main/o/openssl/
libssl1.1_1.1.1w-0+deb11u1_amd64.deb
$ sudo apt install ./libssl1.1_1.1.1w-0+deb11u1_amd64.deb
./openssl_1.1.1w-0+deb11u1_amd64.deb

设置环境变量。由于后续的 TI MCU SDK 和 OPT Keywriter 的编译也需要使用到这些密钥,请勿更新这些变量的参数。

$ export KEYS_DIR=~/keys/ti
$ export SMPK_NAME=custMpk
$ export BMPK_NAME=backMpk

创建密钥生成的路径。

$ mkdir -p "${KEYS_DIR}" && cd "${KEYS_DIR}"

生成 RSA-4096 的 SMPK 密钥对 SSL 证书。

$ openssl genrsa -F4 -out ${SMPK_NAME}.key 4096
$ cp ${SMPK_NAME}.key ${SMPK_NAME}.pem
$ openssl req -batch -new -x509 -key ${SMPK_NAME}.key -out ${SMPK_NAME}.crt

生成 RSA-4096 的 BMPK 密钥对 SSL 证书。

$ openssl genrsa -F4 -out ${BMPK_NAME}.key 4096
$ cp ${BMPK_NAME}.key ${BMPK_NAME}.pem
$ openssl req -batch -new -x509 -key ${BMPK_NAME}.key -out ${BMPK_NAME}.crt

生成 ti-degenerate-key。

$ openssl genrsa -F4 -out ti-degenerate-key.pem 4096

生成 AES-256 加密密钥。

$ openssl rand -out aes256.key 32
$ openssl rand -out bmek.key 32
$ openssl rand -out smek.key 32

删除密钥和证书的可写权限。

$ chmod a-w *

Yocot Project 配置

和之前的文章一样,首先需要搭建Yocto Project 编译环境。这里我们将以基于 TI AM62 SoC 的 Verdin AM62 模块为例进行介绍。在 local.conf 的结尾添加下面两行配置即可。

INHERIT += "tdx-signed"
TDX_K3_SECBOOT_TARGET_HSSE_DEVICE = "1"

在编译镜像时,用于签名启动引导程序的密钥默认从 Ycoto 编译目录的 ${TOPDIR}/keys/ti 位置寻找。可以在 Yocto 的 build 目录下创建 keys/ti 目录,将上面在 ~/keys/ti 中生成的所有文件都复制过来。在 build 目录下会有以下文件夹。

tree -L 1
.
|-- buildhistory
|-- cache
|-- conf
|-- deploy
|-- keys
|-- tmp
`-- tmp-k3r5

INHERIT可以使用tdx-signedtdxref-signed两个参数。

  • tdxref-signed:生成的镜像将启用 Bootloader 签名验证、U-Boot 安全加固、FIT 镜像签名验证、Rootfs 签名验证所有功能。

  • tdx-signed:除"Rootfs 签名校验"外,其余功能全部启用。若无需通过 dm-verity 保护根文件系统,此类模式可能比 tdxref-signed 更适用。

用于 FIT 镜像签名的密钥位于 ${TOPDIR}/keys/ti/fit 目录下。同样建议妥善管理这些密钥。

tree keys -L 1
keys
|-- fit
`-- ti

TDX_K3_SECBOOT_TARGET_HSSE_DEVICE设置为 0 时,编译的镜像能够在没有 fuse 的 AM62 模块上运行。这通常用于前期开发测试阶段。当设置为 1 时,生成的镜像只能运行在 fused AM62 模块上。生产环节批量烧录系统时,则使用该镜像。为了后续演示整个流程,这里编译镜像时设置为 1。

然后使用 bitbake 命令编译镜像即可。整个过程就这么简单,

bitbake tdx-reference-minimal-image

编译 OTP Keywriter

AM62 SoC 借助 OTP Keywriter 固件将用于安全启动期间使用的密钥烧录到处理器的寄存器。这些寄存器是一次性烧录,且不可撤销,请谨慎操作。

编译 OTP keywriter 需要安装下面软件,其中 OTP Keywriter 需要向 TI 申请,通常数个工作日可以通过。具体下载地址参考该网页。主要注意的是,在写该文章时编译 OTP keywriter 需要使用 MCU Plus SDK v9 版本,v10 版本编译的 OTP keywriter 还无法在 AM62 上运行。安装时请使用默认安装路径,否则可能导致编译失败。

  • MCU Plus SDK

  • Code Composer Studio

  • SysConfig

  • OTP Keywriter

进入 OTP keywriter 编译目录

$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/
sbl_keywriter/am62x-sk/r5fss0-0_nortos

下载并打上下面补丁。

$ wget https://docs.toradex.cn/private/116128-verdin-am62v1.2-vpp.patch
$ git apply 116128-verdin-am62v1.2-vpp.patch

进入 ti-arm-clang 目录即可编译。成功后可以看到 tiboot3.bin 文件。

$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/
sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang

$ make -sj clean PROFILE=debug
$ make -sj PROFILE=debug

运行 OTP Keywriter

Verdin AM62 模块上可以通过恢复模式或者从 eMMC 上加载 bootloader 并运行 OTP Keywriter 烧录密钥寄存器。恢复模式需要将 Verdin AM62 通过 USB OTG 接口连接到电脑,并在电脑上运行相关指令。Bootloader 也可以通过 Toradex Easy Installer 写入到 eMMC 上启动分区,模块上电启动后从 eMMC 加载 bootloader。前者适合开发期间使用,后者由于无需 PC,更适合于批量烧写流程。

从恢复模式加载 bootloader

在 PC 上安装 dfu-util。

$ sudo apt install dfu-util

然后运行:

$ sudo dfu-util -c 1 -i 0 -a bootloader -D tiboot3.bin

运行成功后 Verdin AM62 将从 HS-FS 变为 HS-SE 模式,即启用安全启动功能。在下一次启动时将会加载前面生成的签名镜像。

从 eMMC 加载 bootloader

Verdin AM62 的 eMMC 具有两个启动分区,mmcblk0boot0 和 mmcblk0boot1。包含 OTP Keywriter 的 tiboot3.bin bootloader 首先会被烧录在 mmcblk0boot0。常规启动的 bootloader tiboot3-am62x-hs-verdin.bin 会被烧录到 mmcblk0boot1 分区,其包含在 Yocto Project 生成的镜像中。首次启动时加载 mmcblk0boot0 上的 bootloader 运行 OTP Keywriter 完成密钥寄存器烧录。同时配置 eMMC EXTCSD register179,将 设置 mmcblk0boot1 为默认启动分区。这样在下一次启动时,即可加载 mmcblk0boot1 上常规 bootloader,随后加载 U-boot。

MCU SDK 中已经有 MMC 的驱动,因此,只需要在 OTP Keywritter 代码中调用MMCSD_enableBootPartition()即可。在之前的 OTP Keywritter 中打上下面补丁并重新编译。

$ wget https://docs.toradex.cn/117166-verdin-am62-fuse-switch-bootpart2.patch
$ git apply 117166-verdin-am62-fuse-switch-bootpart2.patch

修改 Yocto Project 生成的签名镜像中的 image.json 文件,将原来的 "name": "mmcblk0boot0"改为 "name": "mmcblk0boot1",

{
"name": "mmcblk0boot1",
"erase": true,
"content": {
"filesystem_type": "raw",
"rawfiles": [
{
"filename": "tiboot3-am62x-gp-verdin.bin",
"dd_options": "seek=0",
"product_ids": "0069"

在新加一个 "name": "mmcblk0boot0"分区配置,"product_ids": "0074"时需要烧录的 PID4,"filename": "tiboot3.bin"为重新编译生成的 bootloader。

{
"name": "mmcblk0boot0",
"erase": true,
"content": {
"filesystem_type": "raw",
"rawfiles": [
{
"filename": "tiboot3.bin",
"dd_options": "seek=0",
"product_ids": "0074"
}
]
}
},

烧录完成后,Verdin AM62 第一次启动时将从 HS-FS 变为 HS-SE 模式,即启用安全启动功能。在下一次启动时将会从 mmcblk0boot1 加载前面生成的签名镜像。在 Linux 系统启动后,可以删除 mmcblk0boot0 上的 bootloader 文件。

总结

借助 meta-toradex-security,用户能够轻松地使用模块的安全启动功能。更多来自 meta-toradex-security 实用功能,我们将在后续文章介绍,敬请关注。

相关推荐
xixiaoyunya3 分钟前
局域网多电脑文件互备:从传统痛点到自动化方案的技术路径
网络·安全
yume_sibai10 分钟前
11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)
汇编·安全·rust
AngusKit19 分钟前
开源扫描器拼盘 vs AngusSecurity
安全·安全性测试·代码安全·漏洞检测·trivy·安全扫描·gitleaks
山东科恩光电23 分钟前
安全触边在自动化设备中的应用与风险控制方案分析
安全
企鹅的蚂蚁31 分钟前
LubanCat RK3588 实时 Linux 开发(九):从 U-Boot 到 initramfs 的串口启动故障分析
linux·rk3588·u-boot·串口调试·initramfs·linux启动
汇智信科32 分钟前
企业综合信息门户设计:基于 CMS 扩展的全要素内容与知识生态方案
安全·汇智信科·hsim·fastclaw·汇智龙虾
zhangzhangkeji44 分钟前
stm32 3-4 : 按键控制 LED,光敏传感器控制蜂鸣器
stm32·arm
kkkkkkkkkk_Z1 小时前
学嵌入式和Linux应用编程|学习日记:UDP协议与Wireshark抓包学习笔记
linux·笔记·学习
网易易盾1 小时前
应用加固如何应对AI辅助逆向?从单点防护到持续对抗
人工智能·安全
嵌入式小能手1 小时前
飞凌嵌入式ElfBoard-Shell编程应用实例-提取字符并设置rtc时间
linux