BootROM 与安全启动链:根信任、镜像验签与逐级加载
更新时间:2026-09-19。前置:SPI Flash XIP 启动、eFUSE/OTP、系统复位与启动。复位后 CPU 从固定地址取指,那段「永远可信、不可被改写」的一级代码就是 BootROM。
本文要回答的问题
- 为什么第一段启动代码必须放在片上 ROM,而不是 Flash?
- 安全启动的「信任链」怎样一环验一环建立?
- 根公钥存哪、镜像签名怎么验,验完还要锁什么?
- 怎么防回滚降级、怎么处理加密镜像和调试口?
一、BootROM 的职责
BootROM 是芯片出厂固化的一级引导(见 XIP 启动里「从哪取指」)。它通常做:
- 最小初始化:时钟、RAM、必要引脚、启动介质选择(strap/efuse)。
- 从启动介质(SPI Flash/eMMC/SD/UART/USB)读取下一阶段镜像(SPL/FSBL)。
- 安全模式下验证镜像,通过才跳转;非安全模式可直接加载(开发用)。
- 传递启动参数、内存使用情况、熵源/设备唯一密钥给下一阶段。
- 异常/验签失败处理:进入恢复模式、UART 下载或受控死循环(安全策略)。
关键属性:不可篡改(掩模 ROM 或写保护 OTP)、确定行为、是整条信任链的根(RoT, Root of Trust)。若 BootROM 本身在可写 Flash 里,攻击者改它即可绕过一切检查。
二、信任链(Chain of Trust)
bash
RoT(片上 BootROM,不可改)
│ 用根公钥验证
▼
SPL/FSBL(一阶段引导,含下一阶段公钥/配置)
│ 验证
▼
Bootloader(U-Boot/UEFI 等)
│ 验证
▼
OS 内核 + dtb/initramfs
│ 验证
▼
应用/根文件系统(dm-verity 等)每一级只信任「被上一级验签通过」的下一级:每一级镜像附带签名和证书链,验证者用上一级存的/传来的公钥校验。信任从不可改的 ROM 逐级延伸到软件栈。
三、镜像验签与根公钥
- 非对称签名:镜像私钥(厂商保管,离线)签名 SHA 哈希,芯片用公钥验签。算法常用 RSA-2048/3072、ECDSA(P-256)。
- 根公钥哈希在 efuse/OTP:通常不把整把公钥烧 efuse(位有限),而是烧「公钥的哈希」;BootROM 从镜像头取公钥证书,算哈希与 efuse 值比对,再用该公钥验签。efuse 一次性烧写、不可改(见 eFUSE/OTP)。
- 验证流程(概念):
bash
读镜像头 {公钥证书, 版本号/防回滚计数, 镜像体, 签名}
hash(证书公钥) == efuse ROOT_KEY_HASH ?
公钥验签: verify(signature, hash(镜像体), 公钥) 合法 ?
检查版本号 >= efuse 最小允许版本(防降级) ?
通过 → 锁安全配置、跳转;否则 → 拒绝/恢复- 哈希/验签要防故障注入(电压/时钟毛刺),关键比较用恒时、冗余检查,见硬件安全 PUF/TRNG。
四、验签后必须锁的配置
只「验完跳转」还不够,跳转前/进入可信 OS 前通常要固化:
- 安全状态、启动阶段标志(只写一次),防止下一阶段被诱导回退到未初始化态。
- 关闭 BootROM 用过的临时下载口/缓冲,清零临时密钥。
- 配置内存保护(PMP/MPU/MMU,见 MMU/TLB)、隔离安全世界。
- 锁定调试口或要求调试认证(见下文)。
五、防降级、加密与调试
- 防回滚(anti-rollback):每个镜像带单调版本号/计数器,efuse 记录「已接受的最小安全版本」。旧镜像即使签名合法也拒绝,防止利用旧版本漏洞。efuse 计数只能增(烧更多 bit)。
- 加密镜像(机密性):验签保证完整性/来源,不保证内容保密。镜像可用设备唯一密钥(由根密钥派生、存在 efuse/PUF)加密,BootROM 解密到内部 RAM;密钥不出芯片。XIP 加密 Flash 见 XIP 启动。
- 调试口安全:JTAG/SWD 默认在安全产品上关闭或需安全认证后才开,否则攻击者直接读内存绕过软件链(见 JTAG 边界扫描、RISC-V 调试模块)。
- 故障恢复:验签失败/介质损坏的策略(尝试备用分区、进入厂商下载模式但不执行未授权代码)。
六、常见的坑
- BootROM 在可写介质:根被改写,整条链失效;必须掩模 ROM/写保护。
- 根公钥可被替换:公钥哈希没烧 efuse 或可被软件改,攻击者换密钥自签。
- 只验签不锁状态:下一阶段能回退配置/重开下载口,链在运行时被绕过。
- 无防回滚:降级到有漏洞的合法旧版本。
- 验签可被故障注入跳过:关键比较/分支受电压毛刺攻击,需硬件加固、恒时比较。
- 签名只覆盖部分镜像:头部/dtb/加载地址未纳入签名,攻击者改加载地址跳到任意代码。
- 加密密钥/临时密钥留在内存:跳转前不清零、可读。
- 调试口常开:量产未关 JTAG/ROM 下载模式,直接绕过安全启动。
- 验签用弱哈希/短密钥:SHA-1/RSA-1024 已不安全。
- 随机数/熵不足:需要随机处用了可预测源(见 TRNG)。
- 失败处理不安全:验签失败仍继续执行或落到可写内存里的残留代码。
- 加载地址/大小不校验:缓冲区溢出覆盖 BootROM/安全内存,应先校验镜像头里的加载范围。
相关与延伸
启动介质与 XIP 见 SPI Flash XIP;根密钥存储见 eFUSE/OTP、PUF/TRNG;启动复位见 系统复位控制器;调试口见 JTAG、RISC-V 调试模块。
总结
安全启动以片上不可改写的 BootROM 作为唯一信任根,它最小初始化后从介质读下一阶段镜像,先把镜像里公钥证书的哈希与 efuse 烧录的根公钥哈希比对、再用该公钥对覆盖整个镜像(含加载地址/dtb)的签名做验签、并检查版本号不低于 efuse 单调计数以防降级,全部通过才锁定安全状态并跳转,从而把信任逐环延伸到 OS;机密性另用设备唯一密钥加密镜像、调试口必须关闭或认证——BootROM 可写、公钥可换、验签后不锁状态和无防回滚是四大被绕过根因。