3、安全启动链基础:信任根(RoT)概念、安全启动流程、测量启动与认证启动的区别

好,咱们进入第三章。这一章是整个固件安全的地基。

你想想看,如果芯片上电后执行的第一段代码都不安全,那后面再怎么加固都是白搭。我见过太多产品,加密算法用得挺花哨,结果启动链最底层有个漏洞,整个安全体系直接崩塌。

所以这一章,咱们把安全启动链的底裤扒清楚。信任根是什么,安全启动怎么跑,测量启动和认证启动到底有啥区别。搞明白这些,你才算真正入了固件安全的门。

3.1 信任根(RoT)到底是什么?

信任根,英文叫 Root of Trust,简称 RoT。说白了,它就是整个系统信任链条的起点。

这个起点必须是绝对可信的,不能被篡改。它通常固化在硬件里,比如 ROM 代码或者一次性可编程的熔丝(eFuse)。

我个人习惯把 RoT 比作「安全世界的奇点」。它不需要证明自己可信,因为它本身就是可信的定义。

信任根的核心属性:

  • 不可变性:一旦出厂,代码就不能再改。ROM 掩膜就是典型例子。
  • 不可绕过性:芯片复位后,第一条指令必须从 RoT 开始执行。任何跳板都不行。
  • 最小化:代码量越少越好。我见过有些芯片的 RoT 只有几百行汇编,出 bug 的概率极低。

我在项目中遇到过一件事:某款 IoT 芯片的 RoT 放在 Flash 里,结果攻击者通过电压毛刺攻击,让芯片跳过了 RoT 校验,直接加载了恶意固件。嗯,那款芯片后来被召回,损失惨重。

所以记住:RoT 必须放在硬件里,不能依赖任何可擦写的存储介质。

3.2 安全启动流程:一步一步来

安全启动,英文 Secure Boot。它的核心逻辑很简单:链式信任。

每一级代码在加载下一级之前,都要先验证它的签名或哈希。验证通过才放行,不通过就死机。

典型的流程是这样的:

  1. 芯片复位:CPU 从 ROM 开始执行。这段 ROM 代码就是 RoT。
  2. RoT 验证 Bootloader:ROM 代码读取 Bootloader(通常存在 Flash 里),用公钥验签。公钥存在 eFuse 里,谁都改不了。
  3. Bootloader 验证固件:Bootloader 验签固件镜像。验过了,才把控制权交给固件。
  4. 固件运行:系统启动完成。

你看,每一级都是上一级的「保安」。保安查完身份证,才放你进下一道门。

我的经验:实际项目中,Bootloader 往往不止一级。比如有 SPL(Secondary Program Loader)和 U-Boot 两级。每一级都要做签名验证,不能偷懒。我曾经见过一个方案,SPL 验了 U-Boot,但 U-Boot 没验内核,结果被攻击者塞了个恶意内核进去……

下面这张图,把安全启动的链式信任关系画清楚了:

安全启动链式信任流程 安全启动链式信任流程 信任根 (RoT) ROM 代码 Bootloader 验签后加载 固件镜像 验签后运行 系统运行 安全环境 验证失败 → 死机/复位 任何一级验签失败,立即停止

3.3 测量启动 vs 认证启动

这两个概念,很多人容易搞混。我刚开始做固件时也迷糊过一阵子。

简单来说:认证启动(Authenticated Boot)保证「你是谁」,测量启动(Measured Boot)保证「你是什么状态」。

对比维度 认证启动 测量启动
核心目的 验证代码的签名,确保来源可信 计算代码的哈希,记录启动状态
是否阻止启动 是。验签失败直接死机 否。只记录,不阻止
依赖硬件 公钥(eFuse/ROM) TPM 或 HSM 中的平台配置寄存器(PCR)
典型应用 嵌入式设备、手机、路由器 PC(如 BitLocker)、服务器
抗回滚能力 需配合版本号检查 通过 PCR 扩展值可检测回滚

3.4 认证启动:验明正身

认证启动,说白了就是「查身份证」。每一级代码都带着数字签名,启动时用公钥验一下。签名对得上,就放行;对不上,直接死机。

我在项目中遇到过最典型的场景:某款工业控制器,Bootloader 验签固件时发现签名不对,直接进入恢复模式,红灯狂闪。后来查出来是固件升级时网络丢包,镜像被截断了。嗯,认证启动救了它一命。

注意:认证启动只能保证代码来源可信,不能保证代码没有被篡改后重新签名。所以私钥必须保护好。我见过有厂商把私钥硬编码在编译脚本里,结果源码泄露,私钥也跟着完蛋。

3.5 测量启动:记录状态

测量启动的思路不一样。它不阻止启动,而是把每一级代码的哈希值「扩展」到 TPM 的 PCR 寄存器里。

什么叫扩展?就是 PCR_new = SHA256(PCR_old || 测量值)。这样最终的 PCR 值就包含了整个启动链的完整信息。

系统启动后,远程验证方可以请求 TPM 提供 PCR 值。如果 PCR 值和预期不符,说明启动链被篡改过。

举个例子:

// 测量启动的 PCR 扩展过程
PCR[0] = 0x0000...0000  // 初始值
PCR[0] = SHA256(PCR[0] || SHA256(Bootloader))  // 测量 Bootloader
PCR[0] = SHA256(PCR[0] || SHA256(固件内核))    // 测量内核
// 最终 PCR[0] 包含了 Bootloader 和内核的哈希信息

你想想看,这种方案的好处是什么?它不打断启动流程,系统照样跑。但如果 PCR 值不对,远程服务器可以拒绝下发密钥,或者让设备进入降级模式。

我的建议:如果你的设备有 TPM 或安全元件,强烈建议用测量启动。它比认证启动更灵活,尤其适合需要远程证明(Remote Attestation)的场景。我在做服务器固件时,就用测量启动配合 TPM,实现了启动链的远程审计。

3.6 两者怎么选?

没有银弹。选哪种,取决于你的场景。

  • 嵌入式设备、IoT、手机:用认证启动。资源有限,不需要远程证明,直接死机最省事。
  • PC、服务器、云环境:用测量启动。需要远程证明,需要灵活的策略,不能一棍子打死。
  • 高安全场景:两者都用。认证启动保证来源,测量启动记录状态,双重保险。

我个人习惯是:能用认证启动就用认证启动。它简单、直接、不容易出错。测量启动虽然灵活,但需要额外的硬件(TPM)和软件栈,复杂度高不少。