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。它的核心逻辑很简单:链式信任。
每一级代码在加载下一级之前,都要先验证它的签名或哈希。验证通过才放行,不通过就死机。
典型的流程是这样的:
- 芯片复位:CPU 从 ROM 开始执行。这段 ROM 代码就是 RoT。
- RoT 验证 Bootloader:ROM 代码读取 Bootloader(通常存在 Flash 里),用公钥验签。公钥存在 eFuse 里,谁都改不了。
- Bootloader 验证固件:Bootloader 验签固件镜像。验过了,才把控制权交给固件。
- 固件运行:系统启动完成。
你看,每一级都是上一级的「保安」。保安查完身份证,才放你进下一道门。
我的经验:实际项目中,Bootloader 往往不止一级。比如有 SPL(Secondary Program Loader)和 U-Boot 两级。每一级都要做签名验证,不能偷懒。我曾经见过一个方案,SPL 验了 U-Boot,但 U-Boot 没验内核,结果被攻击者塞了个恶意内核进去……
下面这张图,把安全启动的链式信任关系画清楚了:
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)和软件栈,复杂度高不少。