第二章:硬件信任根(RoT)——信任链的起点
大家好,我是你们的TEE实战课讲师。今天我们来聊聊硬件信任根,也就是RoT。说实话,这个概念听起来挺唬人的,但说白了,它就是整个安全体系的“第一块积木”。
你想想看,如果第一块积木就是歪的,那后面搭得再漂亮也没用。我当年刚接触嵌入式安全时,总觉得软件层面做好加密就够了,直到有一次项目被攻破,才发现攻击者直接从硬件层面篡改了启动代码……嗯,从那以后我再也不敢轻视硬件信任根了。
2.1 信任链的概念
信任链,说白了就是“一层信任一层”的传递机制。就像你进公司,保安先确认你的工牌,然后你才能进大门;进了大门,前台再确认你的预约,你才能进会议室。每一步都建立在上一步验证通过的基础上。
在TEE里,这个链条是这样的:
- 硬件信任根(BootROM)—— 不可篡改的起点
- 一级Bootloader(SPL/FSBL)—— 验证下一级镜像
- 二级Bootloader(U-Boot/EDK2)—— 验证OS内核
- OS内核 —— 验证TEE和REE
- TEE/REE —— 验证应用和TA
我习惯把这个链条画成一个“信任传递图”,每个环节都只信任上一环节签过名的内容。一旦某个环节被篡改,链条就断了,系统直接拒绝启动。
核心原则:信任链必须从不可篡改的硬件开始,逐级验证,任何一级验证失败,系统都不能继续执行。
我在项目中遇到过最典型的案例:某款IoT设备,Bootloader没有做签名验证,攻击者直接替换了启动镜像,植入了后门。嗯,这就是信任链断裂的后果。
2.2 片上ROM(BootROM)的角色
BootROM,就是芯片出厂时固化在片上ROM里的一段代码。它有几个关键特性:
- 只读不可写—— 出厂后谁都没法改
- 最先执行—— 芯片上电后第一条指令就在这
- 验证第一级Bootloader—— 它是信任链的“守门员”
BootROM的代码量通常很小,几KB到几十KB。它做的事情其实很简单:
- 初始化最基本的硬件(时钟、内存控制器等)
- 从固定存储位置(如eMMC、NAND Flash、SPI Flash)读取第一级Bootloader
- 验证该Bootloader的签名或哈希
- 如果验证通过,跳转执行;否则进入错误处理(比如死循环或重启)
我个人习惯把BootROM看作“芯片的DNA”。它决定了这颗芯片的“出身”是否可信。我记得有一次调试一个启动失败的问题,折腾了两天,最后发现是BootROM读取Flash的时序配置不对——嗯,这种问题最头疼,因为BootROM代码你改不了。
实战技巧:调试BootROM相关问题时,多用芯片厂商提供的调试工具(如JTAG),单步跟踪BootROM的执行流程。我一般会先确认BootROM是否成功读取了Bootloader,再检查签名验证是否通过。
2.3 eFuse与OTP存储
eFuse和OTP,都是“一次可编程”的存储。什么意思呢?就是出厂后你可以写一次,写完了就再也改不了了。有点像古代的“火漆封印”——封上之后,谁动过一眼就能看出来。
它们通常用来存储:
- 根公钥哈希—— 用于验证Bootloader签名的公钥的哈希值
- 芯片唯一ID—— 每颗芯片独一无二的标识
- 安全配置位—— 比如是否启用JTAG调试、是否允许回退到旧版本
- 硬件唯一密钥(HUK)的种子—— 后面会细讲
eFuse和OTP的区别,我简单列个表:
| 特性 | eFuse | OTP(如MTP/反熔丝) |
|---|---|---|
| 编程方式 | 电迁移(熔断金属线) | 击穿栅氧化层 |
| 面积 | 较大 | 较小 |
| 可靠性 | 中等(可能熔断不彻底) | 高(一旦编程很难恢复) |
| 典型容量 | 几百bit到几Kbit | 几Kbit到几十Kbit |
| 常见应用 | 安全配置、密钥存储 | 芯片ID、校准数据 |
我曾经踩过一个坑:某款芯片的eFuse编程电压没控制好,导致一批芯片的根公钥哈希写错了,整批芯片直接报废……嗯,从那以后我每次烧eFuse都像拆弹一样小心。
警告:eFuse/OTP一旦编程,不可恢复。生产线上一定要做“预编程验证”,先用测试模式确认数据正确,再真正烧录。我建议在烧录前,先用芯片的“读回”功能确认OTP内容为空,再写入。
2.4 硬件唯一密钥(HUK)的生成
HUK,全称Hardware Unique Key。每颗芯片的HUK都不一样,而且它只存在于芯片内部,永远不应该被读出到外部。它的作用是什么?
- 派生其他密钥—— 比如存储加密密钥、通信会话密钥
- 绑定数据到特定芯片—— 即使把Flash拆下来,换到另一颗芯片上也解不开
- 作为信任根的“种子”—— 所有安全操作都基于它
HUK的生成方式,常见的有几种:
- 基于物理不可克隆函数(PUF)—— 利用芯片制造过程中的随机差异(如SRAM上电初始值、金属层厚度差异)生成唯一指纹。这种方式不需要存储密钥,但需要纠错电路。
- 基于OTP存储的种子—— 在OTP里烧录一个随机种子,然后通过硬件哈希运算生成HUK。这种方式简单可靠,但种子一旦泄露,HUK就完了。
- 混合方式—— PUF生成一个“模糊”的密钥,再用OTP存储的纠错码来稳定化。我比较推荐这种方式,兼顾了安全性和可靠性。
我个人习惯用PUF方式,因为它不需要在芯片外部存储任何密钥材料。但要注意,PUF的输出受温度、电压影响,必须做纠错处理。我在一个项目中遇到过PUF输出在高温下漂移的问题,后来加了纠错电路才解决。
关键点:HUK永远不应该离开芯片安全边界。任何试图读取HUK的指令,都应该被硬件阻止。如果软件能读到HUK,那这个设计就是有问题的。
下面我用一个SVG图来展示整个信任链的流程,从BootROM到HUK的生成:
这张图把整个流程串起来了。你从底部往上看:BootROM是起点,它用eFuse/OTP里存的根公钥哈希去验证Bootloader,然后信任链一级一级往上传递,最后HUK作为整个系统的“密钥之母”诞生。
嗯,这里要注意:HUK的生成必须在安全环境中完成,通常是在BootROM或安全监视器(Secure Monitor)里。我见过一些设计把HUK生成放在REE侧,那基本等于把钥匙挂在门上——毫无安全性可言。
避坑指南:我曾经在一个项目中,HUK的派生算法用了简单的SHA256,结果被攻击者通过侧信道攻击拿到了HUK。后来我们改用带掩码的硬件哈希电路,才堵住这个漏洞。所以,HUK的生成和派生,一定要用硬件加速器,别用软件实现。
好了,这一章的内容就到这里。硬件信任根是整个TEE安全体系的基石,理解它,你才能理解后面所有的安全机制。下一章我们会深入讨论安全启动的具体实现,包括镜像签名、版本回滚防护等实战内容。
可可精品资料库