嵌入式安全实战:手把手教你为ARM64 Linux内核生成签名并配置U-Boot验签(基于FIT Image)
·
ARM64嵌入式安全实战:从密钥生成到U-Boot验签的全链路实现
在智能网联设备和工业控制领域,嵌入式系统的启动安全已成为防御供应链攻击的第一道防线。当一块基于NXP S32G274A的开发板从QSPI闪存启动时,如何确保加载的Linux内核未被篡改?本文将揭示如何通过FIT镜像签名机制,构建从开发环境到目标硬件的完整信任链。
1. 密码学基础与密钥管理
1.1 密钥生成的最佳实践
在~/secure_boot目录下执行以下命令生成符合PKCS#1标准的RSA密钥对:
openssl genpkey -algorithm RSA -out secure.key \
-pkeyopt rsa_keygen_bits:4096 \
-pkeyopt rsa_keygen_pubexp:65537
openssl req -x509 -new -nodes -key secure.key -sha256 -days 1825 \
-out secure.crt -subj "/CN=SecureBoot/O=IoTDevice"
关键参数说明:
- rsa_keygen_bits: 2048位密钥已逐渐被淘汰,推荐使用4096位
- days: 证书有效期建议设置为3-5年(1095-1825天)
- sha256: 必须使用SHA-2系列算法,避免已破解的SHA1
生产环境必须将私钥存储在HSM或安全芯片中,禁止明文存储在开发主机
1.2 密钥部署策略
典型的安全密钥存储方案对比:
| 存储方式 | 安全性等级 | 成本 | 开发便利性 | 适用场景 |
|---|---|---|---|---|
| 文件系统存储 | ★☆☆☆☆ | 低 | 高 | 原型开发阶段 |
| TPM/HSM模块 | ★★★★☆ | 高 | 中 | 工业级设备 |
| 安全启动芯片 | ★★★★★ | 较高 | 低 | 车规级/金融设备 |
| eFuse一次性烧录 | ★★★★★ | 中 | 低 | 量产固件签名 |
2. FIT镜像描述文件深度解析
2.1 ITS文件结构剖析
创建kernel.its文件时需特别注意地址对齐和版本控制:
/dts-v1/;
/ {
description = "Secure Kernel Image";
#address-cells = <1>;
images {
kernel@1 {
data = /incbin/("./Image");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x80080000>;
entry = <0x80080000>;
hash@1 {
algo = "sha512";
};
};
fdt@1 {
data = /incbin/("./s32g274a.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
hash@1 {
algo = "sha512";
};
};
};
configurations {
default = "conf@1";
conf@1 {
kernel = "kernel@1";
fdt = "fdt@1";
signature@1 {
algo = "sha512,rsa4096";
key-name-hint = "secure";
};
};
};
};
常见配置陷阱:
- load/entry地址:必须与内核链接脚本中的
CONFIG_TEXT_BASE一致 - hash算法:必须与U-Boot配置的
CONFIG_FIT_SIGNATURE_HASH匹配 - 版本控制:建议使用
version字段实现OTA回滚保护
2.2 设备树签名扩展
在s32g274a-uboot.dts中添加验签节点:
signature {
key-secure {
required = "conf";
algo = "sha512,rsa4096";
rsa,r-squared = <0x...>;
rsa,modulus = <0x...>;
rsa,exponent = <0x...>;
rsa,n0-inverse = <0x...>;
};
};
通过
dtc -I dts -O dtb -o secure.dtb s32g274a-uboot.dts编译时,确保开启-@保留符号引用
3. U-Boot配置与编译陷阱
3.1 关键配置选项
执行make menuconfig时必须验证以下配置:
Boot options --->
[*] Enable FIT image support
[*] Enable signature verification of FIT images
[*] Enable RSA4096 algorithm support
[*] Require verified images for booting
Security options --->
[*] Enable chain of trust
[*] Allow unsigned images (DEBUG ONLY)
常见编译错误解决方案:
- CONFIG_OF_SEPARATE冲突:当使用独立DTB时需禁用
CONFIG_OF_EMBED - RSA库缺失:需在
lib/rsa/目录添加rsa-mod-exp驱动 - 堆栈溢出:增大
CONFIG_SYS_MALLOC_LEN至(16MB+)
3.2 交叉编译技巧
针对ARM64的优化编译命令:
export CROSS_COMPILE=aarch64-linux-gnu-
make BL31=bl31.bin SCP=scp.bin \
EXT_DTB=secure.dtb \
BOOT_DEVICE=qspi \
BUILD_BASE=../build \
-j$(nproc)
关键产物验证:
aarch64-linux-gnu-objdump -D u-boot | grep "fit_image_verify"
strings u-boot | grep "Verifying Hash Integrity"
4. 验签流程实战验证
4.1 镜像打包与签名
使用mkimage的进阶参数:
mkimage -f kernel.its -K secure.dtb \
-k ~/secure_keys -c "Revoke-2024" \
-r -E -N sha512,rsa4096 \
signed_kernel.fit
参数说明:
-c:添加版权声明到签名头-E:强制大端格式存储签名-N:覆盖ITS文件中的默认算法
4.2 目标板验证流程
在U-Boot命令行中触发验签:
=> setenv verify 1
=> setenv bootargs console=ttyLF0,115200 earlycon
=> load mmc 0:1 0x90000000 signed_kernel.fit
=> bootm 0x90000000
验签失败时的调试技巧:
-
错误码解析:
-EBADMSG:签名不匹配-EKEYREJECTED:证书过期-ENOKEY:公钥未注册
-
调试信息开启:
=> setenv verify_debug 1 => setenv trace on -
内存诊断:
=> md 0x90000000 0x100 => crc32 0x90000000 0x100000
5. 生产环境增强方案
5.1 安全启动链扩展
实现二级引导验证的DTB配置示例:
/ {
secure-boot {
compatible = "nxp,secure-boot";
trusted-key {
nxp,primary-key = <&key_secure>;
nxp,backup-key = <&key_recovery>;
};
stages {
stage1 {
load = <0x80000000>;
verify = <&verify_uboot>;
};
stage2 {
load = <0x81000000>;
verify = <&verify_kernel>;
};
};
};
};
5.2 抗物理攻击措施
-
时钟毛刺检测:在
drivers/crypto/fsl_sec.c中添加:if (readl(SCU_BASE + SCU_CLK_STAT) & CLK_GLITCH) { panic("Clock glitch detected!"); } -
关键函数保护:修改链接脚本保护验签函数:
.secure_text : { KEEP(*(.fit_verify)) KEEP(*(.rsa_verify)) } > secure_ram -
运行时完整性检查:
=> crc32 0x80080000 0x100000 => if test "$?" != "0"; then reset; fi
在完成基础验签功能后,建议在U-Boot中实现安全计数器(secure counter)来防御重放攻击。通过efuse write命令将成功启动次数写入OTP区域,每次启动时校验计数器值是否符合预期增长模式。
更多推荐



所有评论(0)