瑞芯微rk3566开发FIT Secure Boot
加密
FIT Secure Boot
1、目标
在RK3566 Linux 5.10平台 上完成FIT Secure Boot开发与验证,使设备只能启动签名正确的启动链镜像;未签名或被篡改的镜像不能正常启动。
1、FIT路线
Rockchip Linux Secure Boot指南明确给出:
RK3588 / RK356XKernel 检验方式:FIT内核版本:5.10
所以对RK3566来说,应走:
RK3566 + Linux 5.10 + FIT Secure Boot
而不是老平台常见的:
AVB + vbmeta + trust.img
2、FIT和Base Secure Boot的关系
文档说明:
Linux Secure Boot可分成三部分:Base Secure BootAVB / FITDM-V
- 如果平台使用
FIT方案,可以跳过单独的Base Secure Boot操作,因为FIT已经集成了Base Secure Boot。
所以对RK3566而言,开发时不要再按“先单独做Base Secure Boot,再做FIT”的思路拆开理解。
3、OTP
OTP和Secure Boot for U-Boot next-dev相关文档都说明,RK3566属于OTP平台。OTP用于保存Public Key Hash等安全信息,且是不可逆写入。
这意味着:
- 正式启用前,必须先做好联调
- 私钥必须妥善保存
--burn-key-hash只能在最终确认无误后使用
4、Secure Boot
先用一句话解释:
FIT Secure Boot主要保护启动链,不是默认保护整个rootfs。
Rockchip Linux Secure Boot指南给出的Linux启动安全链路是:
BootRomLoader / SPLU-BootBoot / Recovery- 如果要进一步保护
System / rootfs,再走DM-V。
所以本次RK3566 FIT Secure Boot的直接保护对象主要是:
Loader / SPLuboot.imgboot.imgrecovery.img(可选)
而不是自动保护:
rootfs.imgoem.imguserdata.img
如果以后要连rootfs一起保护,要继续上DM-V分区加密。
2、准备工作
1、软件与环境
建议准备:
u-boot/rkbin/- 顶层
build.sh U-Boot目录下的make.sh- 串口日志工具
Windows端RKDevTool / AndroidTool
2、文件和目录角色
这次开发里最容易混淆的是这些文件:
u-boot/boot.img
在签名链里,这往往是真正被重新签名后的boot镜像kernel/boot.img
可能是源码树里的boot镜像输入源output/update/Image/boot.img
可能只是一个软链接,并不一定代表它就是最新signed产物u-boot/uboot.img
这是FIT下的U-Boot主镜像,trust已经并入其中rk356x_spl_loader_v1.xx.xxx.bin
这是新生成的SPL/loader文件,很多情况下要拿它去替代老的MiniLoaderAll.bin
3、开发流程
1、生成FIT签名密钥
FIT 文档说明:
- FIT Keys 与 Base Secure Boot Keys 是同一套密钥
- 固定文件名必须是:
keys/dev.keykeys/dev.pubkeykeys/dev.crt
- 名字不能改,否则打包失败。
本次实际操作为:
cd u-boot mkdir -p keys touch ~/.rnd ../rkbin/tools/rk_sign_tool kk --bits 2048 --out . mv private_key.pem keys/dev.key mv public_key.pem keys/dev.pubkey openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt这里有一个实际踩坑点:
rk_sign_tool生成的文件名不是文档里的privateKey.pem
实测发现,sign_tool ver 1.4实际生成的是:
private_key.pempublic_key.pem
而不是很多文档和旧经验里写的:
privateKey.pempublicKey.pem
2、打开U-Boot FIT签名配置
文档给出的 FIT 必选配置是:
CONFIG_FIT_SIGNATURE=yCONFIG_SPL_FIT_SIGNATURE=y
可选配置:
CONFIG_FIT_ROLLBACK_PROTECT=yCONFIG_SPL_FIT_ROLLBACK_PROTECT=y
本次实际启用后,.config中已看到:
CONFIG_FIT=yCONFIG_FIT_SIGNATURE=yCONFIG_SPL_FIT_SIGNATURE=yCONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT=yCONFIG_FIT_IMAGE_POST_PROCESS=yCONFIG_FIT_HW_CRYPTO=y
3、保存配置
这是本次开发过程中最重要的坑之一。
make menuconfig改的是当前.config,但make.sh会重新加载configs/rk3568_defconfig
所以如果只做:
make menuconfig make savedefconfig但不把defconfig覆盖回configs/rk3568_defconfig,
下一次执行:
./make.sh rk3568 ...时,配置会被默认defconfig覆盖掉,结果又变成:
Image(no-signed, version=0)。
这个问题在本次开发中已经实测出现。
正确做法
在u-boot/下执行:
make rk3568_defconfig make menuconfig make savedefconfig cp configs/rk3568_defconfig configs/rk3568_defconfig.bak cp defconfig configs/rk3568_defconfig文档也明确建议:
先
menuconfig,再savedefconfig更新原defconfig,避免依赖不一致。
4、执行FIT签名链
- 顶层
build.sh:生成 SDK 整体镜像、打包系统 u-boot/make.sh:执行 FIT 签名链
所以--spl-new --boot_img --burn-key-hash这些 FIT 参数,应当给:
u-boot/make.sh而不是顶层build.sh。
测试有实际遇到:
- 脚本找:
gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
- 但 SDK 实际有的是:
gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
所以脚本一开始找不到编译器。
给make.sh期望的位置补一层兼容目录或软链接,让它能找到aarch64-linux-gnu-gcc这一套名字即可。
5、执行签名
文档说明,u-boot/make.sh在编译签名时,会同时对:
boot.imgrecovery.imgloader.binuboot.img
进行签名,必须指定一个真实可签名的FIT格式boot.img。
联调阶段,先不要写OTP:
cd u-boot sudo ./make.sh rk3568 --spl-new --boot_img /media/work/work/rk_sdk/rk_linux_sdk/kernel/boot.img成功时,实际看到:
Signature check OKImage(signed, version=0): uboot.img ...Image(signed, version=0): boot.img ...Image(signed): rk356x_spl_loader_v1.19.113.bin ...
这就说明:
签名链已经跑通。
6、正式写入OTP Key Hash
确认联调成功后,再执行正式版:
cd u-boot sudo ./make.sh rk3568 --spl-new --boot_img /media/work/work/rk_sdk/rk_linux_sdk/kernel/boot.img --burn-key-hash文档说明:
--burn-key-hash会要求SPL阶段把公钥hash写入OTP / eFuse- 成功时会出现:
RSA: Write key hash successfully.
