2、硬件信任根:CRTM设计、Boot ROM安全机制、不可变代码区保护
各位同学,咱们今天聊点硬核的——硬件信任根。说白了,就是整个可信启动链条的“第一把锁”。这把锁要是焊不牢,后面所有度量都是白搭。我在做嵌入式安全那几年,见过太多因为信任根没守住,整个系统被从底层捅穿的案例。嗯,咱们今天就把这块掰开揉碎了讲。
2.1 CRTM:可信度量的起点
CRTM,全称 Core Root of Trust for Measurement,翻译过来就是“核心信任根度量”。你想想看,系统上电后,CPU 跑的第一段代码是谁?就是它。这段代码必须满足一个铁律:不可篡改、不可绕过、不可伪造。
我个人习惯把 CRTM 比作“系统DNA”。DNA 要是被改了,后面长出来的细胞全是癌细胞。CRTM 一旦被污染,整个启动过程就失去了可信基础。
CRTM 的核心职责:
- 上电后第一个执行,初始化最小硬件环境(CPU、内存控制器、安全外设)
- 度量下一级固件(通常是 BIOS 或 UEFI 的初始模块)的完整性
- 将度量结果扩展到 TPM(可信平台模块)的 PCR 寄存器中
- 确保自身代码不可被修改或跳过
我曾经在一个 IoT 网关项目里踩过坑。当时设计团队把 CRTM 放在 SPI Flash 里,结果攻击者通过物理探针直接短接了 Flash 的写保护引脚,把 CRTM 代码给换了。从那以后,我对于“不可变”这三个字有了刻骨铭心的理解。
2.2 Boot ROM:硬件级的“第一道防线”
Boot ROM 是 CRTM 最常见的物理载体。它被固化在芯片内部,出厂后无法修改。你想想看,这玩意儿的好处是什么?——攻击者就算把板子上的 Flash 全拆了,Boot ROM 里的代码依然纹丝不动。
Boot ROM 的安全机制,我总结为“三板斧”:
| 安全机制 | 作用 | 我在项目中遇到的坑 |
|---|---|---|
| 写保护熔丝 | 物理熔断写使能线路,ROM 区域变为只读 | 熔丝烧写顺序错了,整批芯片报废 |
| 签名验证 | Boot ROM 用公钥验证外部固件签名 | 公钥哈希被硬编码在 ROM 里,换不了 |
| 安全启动状态机 | 控制启动流程,防止跳过关键步骤 | 状态机漏了“回退”场景,被降级攻击 |
注意:Boot ROM 的代码空间极其有限,通常只有 32KB~128KB。这意味着你不能在里面写复杂的逻辑。我见过有人试图在 Boot ROM 里塞一个完整的加密库,结果 ROM 容量爆了,最后不得不砍功能。记住:Boot ROM 只做“最小必要”的事。
2.3 不可变代码区保护:从物理到逻辑
不可变代码区,不仅仅是“焊死在 ROM 里”这么简单。它需要一套组合拳来保护。我个人习惯把保护措施分成三个层级:
2.3.1 物理层保护
- 熔丝/efuse:一次性可编程,烧断后不可恢复。用于存储根密钥、芯片唯一 ID、安全配置位。
- 金属层屏蔽:在芯片顶层走线中埋入传感器网格,一旦被探针接触就触发复位或擦除。
- 光屏蔽:覆盖不透明材料,防止通过显微镜逆向工程读取 ROM 内容。
2.3.2 逻辑层保护
- 总线防火墙:只有特定 Master(如 CPU 的取指单元)才能访问 ROM 区域,DMA 控制器不行。
- 地址范围锁定:通过硬件寄存器锁定 ROM 的地址窗口,任何试图写入该范围的请求都会被总线拒绝。
- 安全监控器:持续监控 ROM 区域的访问模式,检测到异常(如连续读失败)就触发中断。
2.3.3 验证层保护
- 运行时完整性校验:Boot ROM 在启动过程中对自己做哈希校验,确保没有被硬件故障或物理篡改。
- 双重签名验证:部分高安全场景要求两个不同密钥同时签名,防止单点密钥泄露。
我的经验:在做不可变代码区保护时,最容易忽略的是“调试接口”。我曾经在一个项目里,所有保护都做得很到位,结果 JTAG 接口没锁,攻击者直接通过调试器读取了 ROM 内容。从那以后,我要求所有量产芯片必须熔断调试接口的使能熔丝。
2.4 核心逻辑:CRTM 启动流程
咱们用一张图把整个流程串起来。这张图我画了很多遍,每次给新团队讲课时都会拿出来用。
这张图里,我特别想强调一个点:度量结果必须扩展到 TPM 的 PCR 寄存器。为什么?因为 PCR 的值是“累加”的——每次扩展都会把新哈希和旧哈希混在一起。这样,攻击者就算篡改了中间某个环节,最终 PCR 值也会和预期值对不上。我在一个服务器项目里,就是靠 PCR 值的异常变化,定位到了固件被植入后门的问题。
2.5 避坑指南:我踩过的几个雷
做硬件信任根设计,有些坑是教科书上不会写的。我把自己踩过的几个分享给大家:
- Boot ROM 的“回退路径”:有些芯片支持从 SPI Flash 回退启动。如果回退路径没做签名验证,攻击者可以直接插一个恶意 Flash 芯片绕过 CRTM。我曾经在审计时发现一个产品,回退路径完全没保护,吓得我连夜让他们改了设计。
- 熔丝烧写的顺序:熔丝一旦烧断就不可逆。我见过一个团队,先烧了调试接口熔丝,结果发现 Boot ROM 有 bug 需要更新,但已经没法调试了。正确的做法是:先验证所有功能,最后再烧熔丝。
- ROM 代码的“死循环”保护:如果 Boot ROM 在度量过程中发现固件被篡改,应该怎么做?我建议直接进入死循环或触发硬件复位,而不是打印一条错误日志然后继续启动。攻击者可以利用日志输出窗口做侧信道攻击。
总结一句话:CRTM 是可信启动的“根”,这根要是烂了,整棵树都活不了。设计时,把“不可变”刻在脑子里,把“最小化”写在代码里,把“验证”焊在流程里。