4. 安全启动与信任链
在 BootROM 启动回滚保护工程中,安全启动并不是一个单独的功能开关,而是一条从芯片上电到操作系统加载的完整信任传递路径。它的核心思想是:先固化一个不可篡改的信任根,再由信任根逐级验证下一阶段镜像的完整性与合法性,最终把信任扩展到整个系统。理解这条链路,是后续实现回滚保护、防降级攻击和镜像防篡改的基础。
一、信任根:安全启动的起点
信任根(Root of Trust,RoT)是安全启动中第一个被无条件信任的组件。它通常由芯片内部的 BootROM 代码、固化在 OTP/eFuse 中的公钥哈希、以及硬件级只读存储共同构成。BootROM 在芯片流片时就被写入掩膜 ROM,运行时不可修改,因此攻击者无法通过软件手段替换它。
信任根需要满足三个条件:第一,代码不可写;第二,验证所需的公钥或哈希不可被外部替换;第三,执行入口固定且不可跳过。在工程实践中,BootROM 会读取 eFuse 中的根公钥哈希(ROTPK Hash),并用它来校验第一阶段引导程序(如 BL1 或 SPL)的签名。如果 eFuse 未烧录或哈希不匹配,芯片应直接进入不可恢复的停止状态,而不是继续启动。
关键点:信任根不是“一段代码”,而是“代码 + 密钥材料 + 硬件保护机制”的组合。缺少任何一项,信任链都会在起点断裂。
二、信任链建立:逐级签名与哈希校验
信任链(Chain of Trust)的建立过程,本质上是“上一级验证下一级”的递归过程。每一级镜像都包含两部分内容:镜像数据本身,以及对该镜像的签名或哈希值。上一级在加载下一级之前,先计算镜像的哈希,再用自己的公钥验证签名,只有验证通过才跳转执行。
典型的启动阶段划分如下:
- BL1 / SPL:由 BootROM 验证,运行在 SRAM 中,负责初始化时钟、DDR 和加载 BL2。
- BL2:由 BL1 验证,负责加载更完整的固件或安全监控程序。
- BL31 / BL32:由 BL2 验证,分别对应 EL3 运行时固件和可信执行环境。
- BL33 / U-Boot:由 BL2 或 BL31 验证,最终加载操作系统内核。
每一级验证都遵循相同的模式:读取镜像 → 计算哈希 → 验证签名 → 检查版本/回滚计数器 → 跳转执行。这种递归结构保证了只要信任根安全,整条链上的任何篡改都会被检测到。
三、签名验证与哈希校验:两种互补的完整性手段
哈希校验和签名验证经常被混为一谈,但它们在安全启动中承担不同职责。哈希校验只能证明“数据没有被意外损坏”,它本身不提供身份认证,因为攻击者可以同时替换数据和哈希值。签名验证则使用非对称密钥,私钥签名、公钥验签,攻击者没有私钥就无法伪造合法签名。
因此,安全启动的标准做法是:先对镜像计算哈希,再对哈希值进行签名。验证时,上一级用公钥解密签名得到原始哈希,再与本地计算的哈希比对。两者一致,才认为镜像既完整又合法。常见算法组合包括 SHA-256 + RSA-2048、SHA-384 + ECDSA P-256 等。
| 校验方式 | 作用 | 能否防篡改 | 典型算法 | 在启动链中的位置 |
|---|---|---|---|---|
| 哈希校验 | 检测数据完整性 | 不能单独防恶意替换 | SHA-256、SHA-384 | 签名验证的前置步骤 |
| 签名验证 | 验证来源合法性与完整性 | 能,依赖私钥保密 | RSA-2048、ECDSA P-256 | 每一级镜像跳转前 |
| 回滚计数器 | 防止降级到旧版本 | 能,依赖单调递增存储 | eFuse 计数器、TPM NV | 签名验证通过后检查 |
| 安全策略引擎 | 决定失败后的行为 | 间接,限制攻击面 | BootROM 策略表 | 验证失败分支 |
四、启动阶段的安全策略与实战场景
安全策略决定了“验证失败之后怎么办”。不同产品对可用性和安全性的权衡不同,常见策略包括:
- 严格模式:任何一级验证失败立即停止启动,芯片进入不可恢复状态。适用于支付、身份认证等高安全场景。
- 恢复模式:验证失败后进入 USB/UART 恢复通道,允许重新烧录合法镜像。适用于开发板和可维护设备。
- 降级模式:允许启动到受限功能系统,但禁用敏感外设和密钥访问。适用于需要保留基本可用性的工业设备。
以下是一段典型的 BL1 验证 BL2 的伪代码逻辑,展示了签名验证与回滚计数检查的组合:
// BL1 验证 BL2 镜像
hash = sha256(bl2_header + bl2_payload);
if (!verify_signature(bl2_pubkey, bl2_signature, hash)) {
secure_log("BL2 signature verify failed");
enter_recovery_or_halt();
}
// 检查回滚计数器
if (bl2_rollback_counter < efuse_min_counter) {
secure_log("BL2 rollback detected: %d < %d",
bl2_rollback_counter, efuse_min_counter);
halt_boot();
}
// 验证通过,跳转执行
jump_to(bl2_entry);
常见误区:很多团队只做了签名验证,却忽略了回滚计数器检查。攻击者可以拿一个旧版本、签名合法的镜像重新烧录,利用旧版本中的已知漏洞实现降级攻击。签名验证防的是“伪造”,回滚计数器防的是“合法但过期的版本”。两者必须同时启用。
五、复盘:信任链设计中的三个关键检查点
在实际项目中,信任链最容易出问题的地方往往不是算法本身,而是工程实现细节。建议在设计和评审阶段重点检查以下三点:
- 信任根是否真正不可变:确认 BootROM 不可写、eFuse 烧录后不可逆、调试接口在量产模式下已关闭。
- 每一级是否都验证了下一级:不能出现“BL2 验证了 BL31,但 BL31 直接跳转 BL33 而不验证”的断链情况。
- 失败路径是否安全:验证失败后不能回退到未验证的镜像,也不能暴露调试 shell 或密钥接口。
安全启动与信任链的本质,是把“信任”从一个不可证明的起点,通过密码学手段逐级传递到整个系统。信任根提供起点,签名验证提供身份,哈希校验提供完整性,回滚计数器提供版本约束,启动策略提供失败时的安全边界。只有这五者协同工作,BootROM 启动回滚保护才能真正落地。