1. 安全启动概述:什么是安全启动、为什么需要安全启动、安全启动的信任链模型
1.1 什么是安全启动?
安全启动,说白了就是一套「只让可信代码跑起来」的机制。
我习惯这么跟团队讲:你按下电源键,芯片复位,第一条指令从哪里来?从 ROM 里的 BootROM 来。那 BootROM 怎么知道下一级加载的 Bootloader 是原厂的、没被篡改过的?它不知道。所以安全启动要做的,就是在每一级代码跳转之前,先验一验它的「身份证」——数字签名。
嗯,这里要注意:安全启动不是防黑客入侵的万能药。它防的是「启动阶段被植入恶意代码」。你想想看,如果攻击者把你的 Flash 拆下来,焊个恶意 Bootloader 上去,系统照样能开机,但跑的是人家的后门程序。安全启动就是让这种篡改失效。
核心定义:安全启动(Secure Boot)是一种从硬件复位开始,逐级验证代码完整性与合法性的启动流程。只有通过签名的代码才能被执行,未签名或签名无效的代码被拒绝。
1.2 为什么需要安全启动?
我在项目中遇到过一件事:某款 IoT 网关设备,出厂时没开安全启动。结果客户现场被植入挖矿程序,CPU 跑满 100%,网络流量异常。最后定位发现,攻击者通过 UART 接口刷了个修改版的内核。如果当时开了安全启动,这种攻击在第一关就被拦住了。
安全启动的必要性,我总结为三点:
- 防篡改:防止 Bootloader、内核、文件系统被物理替换或修改。
- 防回滚:防止攻击者刷回有已知漏洞的旧版本固件。
- 建立信任根:从硬件不可变区域开始,逐级建立信任链,确保整个启动过程可追溯、可验证。
你可能会问:我的产品是消费级的,也需要吗?我的建议是:只要设备能联网、能处理敏感数据,就应该考虑安全启动。成本增加不大,但安全收益很高。
避坑指南:我曾经见过一个团队,为了省几毛钱的 eFuse 成本,把公钥存在可擦写的 Flash 里。结果攻击者直接替换了公钥,安全启动形同虚设。记住:信任根必须是硬件不可变的,比如一次性编程的 OTP 或 eFuse。
1.3 信任链模型
信任链模型,是安全启动的骨架。我习惯把它画成一条「接力棒」——每一级代码验证下一级,直到操作系统启动完成。
典型的信任链分四层:
- 信任根(Root of Trust, RoT):芯片内部的 BootROM,不可修改。它包含芯片厂商烧录的公钥哈希或公钥本身。
- 一级 Bootloader(SPL / BL1):由 BootROM 加载并验证。通常很小,负责初始化 DDR、时钟等。
- 二级 Bootloader(U-Boot / BL2):由一级 Bootloader 验证。负责加载内核、设备树、ramdisk。
- 操作系统内核:由二级 Bootloader 验证。内核启动后,还可以继续验证内核模块和关键应用。
每一级验证通过后,才把控制权交给下一级。验证失败则进入错误处理流程——通常是死循环或重启。
个人经验:我在调试某款车规级芯片时,发现 BootROM 验证 SPL 时只检查了签名,没检查版本号。结果攻击者刷了个旧版 SPL,绕过了后续的安全补丁。后来我们在 SPL 头部加了版本号字段,并在 BootROM 里做了版本比较。这个坑,大家设计时要注意。
1.4 信任链的 SVG 流程图
下面这张图,是我在培训时经常用的。它把信任链的每一级、验证方式、失败处理都画清楚了。
1.5 信任链的验证流程
我把信任链的验证流程拆成几个关键步骤,方便你对照代码或调试日志:
| 阶段 | 验证者 | 被验证者 | 验证内容 | 失败后果 |
|---|---|---|---|---|
| 1 | BootROM | SPL / BL1 | SPL 的签名 + 哈希 | 芯片无法启动 |
| 2 | SPL | U-Boot / BL2 | U-Boot 的签名 + 哈希 | 进入 SPL 错误循环 |
| 3 | U-Boot | 内核 + 设备树 | 内核镜像的签名 | U-Boot 提示验证失败 |
| 4 | 内核 | 内核模块 / 应用 | 模块签名 / IMA 度量 | 模块加载失败 |
这张表,我建议你打印出来贴在工位上。调试安全启动问题时,先看卡在哪一级,再针对性查日志。
1.6 常见的信任链实现
不同芯片厂商的实现略有差异,但核心思想一致。我列几个常见的:
- ARM TrustZone + TF-A:ARM 架构的标准方案。BL1 在 BootROM 里,BL2 在 Trusted SRAM 里,BL31 是 EL3 运行时固件。
- Intel Boot Guard:Intel 平台的安全启动方案。信任根在 CPU 内部的微码里,验证 BIOS 的 ACM(Authenticated Code Module)。
- U-Boot 的 verified boot:开源方案。U-Boot 自己验证内核和设备树的签名,公钥可以编译进 U-Boot 或存储在 OTP 里。
- OP-TEE + 安全启动:在 TrustZone 的安全世界里做验证,普通世界无法干预。
我的建议:选型时,优先选芯片厂商已经集成好安全启动方案的型号。自己从头实现信任链,坑太多。我见过一个团队自己写 BootROM 验证逻辑,结果漏掉了哈希校验,签名对了但镜像被替换了都没发现。
1.7 安全启动的局限性
安全启动不是银弹。我遇到过几个场景,安全启动完全没用:
- 运行时攻击:安全启动只覆盖启动阶段。系统跑起来后,如果内核有漏洞,攻击者照样能提权。
- 侧信道攻击:通过功耗分析、电磁辐射等手段,可能提取出 BootROM 里的公钥或签名算法。
- 供应链攻击:如果芯片在出厂前就被植入了后门,安全启动也拦不住。
所以,安全启动只是整个安全体系的一环。它和 TEE、SE、加密存储、安全更新等配合使用,才能形成完整防护。
注意:我曾经调试过一个案例,设备开了安全启动,但 U-Boot 的环境变量没锁定。攻击者通过修改 bootargs 传入了恶意内核参数,绕过了内核验证。嗯,环境变量保护也是安全启动的一部分,别忘了。
1.8 小结
安全启动的核心,就是一条从硬件信任根开始的验证链。每一级只信任上一级,验证失败就停止。它防的是启动阶段的代码篡改,但不能替代运行时安全。
我个人习惯在设计初期就把信任链画出来,标清楚每一级的验证方式、公钥存储位置、失败处理策略。这样后期调试时,能快速定位问题出在哪一级。