2. 固件更新基础:生命周期、安全启动链与信任根
好,咱们正式开始聊固件更新。这一章是后面所有防回滚技术的地基。你想想看,如果连固件是怎么更新的、安全启动是怎么保证的、信任根到底在哪都不清楚,那后面讲的各种防回滚手段,就成了空中楼阁。
我个人习惯,在讲任何安全机制之前,先画一张大图。把固件从出生到退役的整个流程理清楚。这样你才知道,我们在哪个环节插入了安全措施,哪个环节最容易被人钻空子。
2.1 固件更新的生命周期
固件不是写死了就完事的。它有自己的生命周期。我把它分成五个阶段:
- 开发阶段:工程师写代码、编译、签名。这个阶段最容易出纰漏,比如私钥泄露。
- 发布阶段:固件包分发到服务器或OTA平台。这里要防中间人篡改。
- 传输阶段:固件通过网络或本地接口下载到设备。要防重放攻击和截断。
- 更新阶段:设备接收固件,校验签名,写入Flash。这是防回滚的主战场。
- 运行阶段:新固件启动,安全启动链验证每一级代码。这里要防降级攻击。
核心观点:防回滚技术主要作用于「更新阶段」和「运行阶段」的交接处。说白了,就是在写入新固件之前,检查它的版本号是不是比当前的高。
我在项目中遇到过一件事。有个客户,他们的设备在传输阶段做了很完善的TLS加密,但在更新阶段,居然没有检查固件版本号。结果攻击者抓包拿到一个旧版本的固件,直接通过本地串口刷了进去。嗯,那个旧版本有个已知漏洞。所以你看,生命周期每个环节都得守住。
2.2 安全启动链
安全启动链,英文叫Secure Boot Chain。它解决的是一个问题:我怎么知道我当前运行的代码是可信的?
答案是一级验一级。从最底层的硬件开始,逐级向上校验。每一级在加载下一级之前,都要检查它的签名或哈希值。如果对不上,就拒绝启动。
典型的嵌入式安全启动链长这样:
BootROM (不可修改)
↓ 校验
Bootloader (第一阶段)
↓ 校验
Bootloader (第二阶段) / 固件更新代理
↓ 校验
操作系统内核 / 应用程序固件
这里有个关键点:BootROM是硬件固化的,出厂后改不了。它就是整个信任链的起点。如果BootROM被攻破了,那整个安全体系就完了。所以芯片厂商会在BootROM里做死,比如熔断JTAG、禁止读回等。
避坑指南:我曾经见过一个方案,Bootloader校验了内核,但没校验自己的第二阶段。攻击者直接替换了第二阶段的Bootloader,绕过了所有安全校验。记住,安全启动链必须是一环扣一环,不能有断点。
为什么会这样?因为攻击者只要找到链条里最弱的一环,就能撬动整个系统。你想想看,如果第二级Bootloader没有签名校验,那攻击者就可以注入一个恶意Bootloader,然后这个恶意Bootloader再去加载一个带后门的内核。整个链条就崩了。
2.3 信任根的概念
信任根,Root of Trust,简称RoT。它是整个安全体系的基石。说白了,就是系统里绝对可信、不可篡改的那个点。
在嵌入式系统里,信任根通常由硬件提供。常见的形式有:
| 信任根类型 | 载体 | 特点 |
|---|---|---|
| 硬件信任根 | BootROM、eFuse、HSM | 物理不可篡改,出厂即固化 |
| 软件信任根 | 签名公钥、哈希值 | 依赖硬件保护,可更新但风险高 |
| 混合信任根 | 硬件存储密钥 + 软件校验 | 兼顾安全性与灵活性 |
我个人最推荐的是硬件信任根。因为软件信任根有个天然缺陷:它本身需要被加载和校验,那谁来校验它?这就成了「先有鸡还是先有蛋」的问题。硬件信任根不存在这个问题,它从芯片上电那一刻就开始工作,不需要任何外部依赖。
注意:不要把信任根和信任链搞混。信任根是那个起点,信任链是从起点延伸出去的路径。根坏了,链就断了。根还在,链断了还能修。
嗯,这里要特别提一下eFuse。很多芯片会用eFuse来存储根密钥或版本号。eFuse是一次性可编程的,烧进去就改不了。这就很适合做防回滚的版本号存储。我在一个车规级项目里,就是用eFuse来存固件版本号,每次升级成功后就烧写新的版本号。这样攻击者想回滚,eFuse里的版本号比固件里的高,Bootloader直接拒绝加载。
2.4 三者之间的关系
咱们把这三个概念串起来。我用一张图来展示它们的关系:
这张图把三个概念串在了一起。你看,固件更新的生命周期是一条时间线。安全启动链是一条信任线。信任根是这两条线的交汇点。没有信任根,安全启动链就是无源之水。没有安全启动链,固件更新就是裸奔。
我再说一个实际案例。之前做一个IoT网关,用的是某款主流ARM芯片。芯片内置了BootROM作为信任根,支持安全启动。但固件更新代理跑在Linux用户空间,没有做签名校验。结果呢?攻击者通过漏洞拿到了root权限,直接写了一个恶意固件到Flash分区。下次重启时,BootROM校验了Bootloader,通过了。Bootloader校验了内核,也通过了。但内核加载的固件更新代理是恶意的。你看,链条在用户空间断了。后来我们改了架构,把固件更新代理的签名校验下沉到Bootloader里,才堵住这个漏洞。
所以,信任根是硬件给的,但信任链需要你自己去维护。每一级都不能放过。
总结一下:
- 固件更新生命周期:开发→发布→传输→更新→运行。防回滚卡在「更新」和「运行」之间。
- 安全启动链:BootROM→Bootloader→OS/App。一级验一级,不能断。
- 信任根:整个体系的起点。硬件固化,不可篡改。