5. FIP 签名与加密及 eFuse¶
本章说明在本仓库中对 fip.bin 做 签名与加密,并配合 eFuse 烧录,使 ROM/BL1 只执行受信任的 FIP。若还需 boot.spinor 内 FIT 的验签或加密,见 FIT 镜像安全启动。
所有命令均在 mars 根目录 执行(U-Boot 内 eFuse 命令除外);须先依次执行 source build/envsetup_soc.sh 与 defconfig ,将后者参数换为实际板型名。
5.1. 生成 FIP 用的密钥¶
只做一次,密钥妥善保存。
KEY_DIR="$(pwd)/my_fip_keys"
mkdir -p "$KEY_DIR"
openssl genrsa -out "${KEY_DIR}/rsa_hash0.pem" -F4 2048
openssl genrsa -out "${KEY_DIR}/bl_priv.pem" -F4 2048
head -c 16 /dev/random > "${KEY_DIR}/loader_ek.key"
head -c 16 /dev/random > "${KEY_DIR}/bl_ek.key"
chmod 600 "${KEY_DIR}"/*.pem "${KEY_DIR}"/*.key 2>/dev/null || true
得到:rsa_hash0.pem、bl_priv.pem、loader_ek.key、bl_ek.key。
5.2. 打开 FSBL 安全启动并编译¶
在
menuconfig中:FIP setting → 勾选 Add secure boot support to FSBL → 保存退出。
或直接在板级 defconfig 中加入:
CONFIG_FSBL_SECURE_BOOT_SUPPORT=y
执行 build_all 完成编译。完成后在 install/ 下对应板型的 soc_* 子目录中可得到 fip.bin 等(具体以板级配置为准)。
注解
若启用内核 FIT 安全启动,还需按 FIT 镜像安全启动 配置内核与 U-Boot,并与本章 build_all 在同一套配置下完成。
5.3. 对 FIP 做签名与加密¶
在 mars 根目录执行(将 KEY_DIR、FIP_IN、FIP_OUT 换成实际路径与板子输出目录):
KEY_DIR="$(pwd)/my_fip_keys"
FIP_IN=install/soc_cv1842hp_wevb_0014a_spinor/fip.bin
FIP_OUT=install/soc_cv1842hp_wevb_0014a_spinor/fip_enc.bin
python3 fsbl/plat/cvitek/cv184x/common/fipsign.py sign-enc \
--root-priv="${KEY_DIR}/rsa_hash0.pem" \
--bl-priv="${KEY_DIR}/bl_priv.pem" \
--ldr-ek="${KEY_DIR}/loader_ek.key" \
--bl-ek="${KEY_DIR}/bl_ek.key" \
"$FIP_IN" "$FIP_OUT"
得到形如 install/soc_xxx/fip_enc.bin 的输出(xxx 为板型目录名)。仅签名不加密时可改用 sign 子命令,参数见 fipsign.py --help。
5.4. 获取 eFuse 要烧写的值(开发机)¶
5.4.1. HASH0_PUBLIC(64 位十六进制)¶
需安装 PyCryptodome:
python3 -c "
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
key = RSA.import_key(open('my_fip_keys/rsa_hash0.pem').read())
n = key.n.to_bytes(256, 'big')
print(SHA256.new(n).digest().hex())
"
5.4.2. LOADER_EK(32 位十六进制)¶
xxd -p -c 256 my_fip_keys/loader_ek.key | tr -d '\n'
5.5. 烧写 eFuse(U-Boot 中,一次性、不可逆)¶
将占位符替换为上一节得到的值后,在 U-Boot 中按顺序执行:
efusew HASH0_PUBLIC <64位十六进制>
efusew LOADER_EK <32位十六进制>
efusew LOCK_WRITE_LOADER_EK 01
efusew LOCK_WRITE_HASH0_PUBLIC 01
efusew SECUREBOOT 02
顺序以芯片与厂商文档为准;锁与 SECUREBOOT 烧写后即生效,无法撤销。
注解
注意事项
eFuse 烧写为不可逆行为,执行前请确认镜像与密钥规划已核对无误。
5.6. 烧录镜像(eFuse 烧写完成之后)¶
FIP 分区:将 fip_enc.bin 作为实际烧写内容,按原 fip.bin 用法并 改名为 fip.bin 后烧录。勿使用未签名的原始 fip.bin 或 fip_spl.bin。
其它分区:与平时一致,例如 boot.spinor → BOOT,rootfs.spinor → ROOTFS,data.spinor → DATA,yoc.bin → 2nd 等。
顺序:先完成 eFuse 烧录,再烧录镜像及各分区。若先烧加密 FIP 再烧 eFuse,可能无法启动,需用未加密的 fip.bin 重烧 FIP 等方式恢复。
5.7. 流程简表(FIP 侧)¶
阶段 |
步骤 |
内容 |
|---|---|---|
准备 |
0 |
(可选)FIT 安全启动见 FIT 镜像安全启动 |
密钥 |
1 |
生成 FIP 密钥目录 my_fip_keys |
配置与编译 |
2 |
|
签名加密 |
3 |
fipsign.py sign-enc 得到 fip_enc.bin |
eFuse 取值 |
4 |
开发机计算 HASH0_PUBLIC;读取 LOADER_EK |
eFuse 烧录 |
5 |
U-Boot 中 efusew(HASH0_PUBLIC、LOADER_EK、LOCK、SECUREBOOT) |
分区烧录 |
6 |
以 fip_enc.bin 替换原 fip.bin 并仍命名为 fip.bin 后烧 FIP;其它分区照旧 |
5.8. FIP 密钥一览(my_fip_keys/)¶
文件 |
用途 |
|---|---|
rsa_hash0.pem |
签署 FSBL(BL2)的 RSA 私钥;其公钥哈希烧入 eFuse HASH0_PUBLIC |
bl_priv.pem |
签署 Monitor/U-Boot 的 RSA 私钥 |
loader_ek.key |
加密 FSBL 的 AES 密钥(16 字节);烧入 eFuse LOADER_EK |
bl_ek.key |
加密 Monitor/U-Boot 的 AES 密钥(16 字节) |
5.9. 与 FIT 的关系¶
FIT:保护 boot.spinor,由 U-Boot 验签或解密,见 FIT 镜像安全启动。
FIP:保护 fip.bin,由 ROM/BL1 验签与解密。
两者可同时使用:先完成 FIT 侧打包与烧录策略,再对 fip.bin 做 sign-enc;烧录时用 fip_enc.bin 替换并改名为 fip.bin 写 FIP 分区,BOOT 分区写已签名或加密的 boot.spinor。