1. 安全启动概述:什么是安全启动、为什么需要安全启动、安全启动的信任链模型

1.1 什么是安全启动?

安全启动,说白了就是一套「只让可信代码跑起来」的机制。

我习惯这么跟团队讲:你按下电源键,芯片复位,第一条指令从哪里来?从 ROM 里的 BootROM 来。那 BootROM 怎么知道下一级加载的 Bootloader 是原厂的、没被篡改过的?它不知道。所以安全启动要做的,就是在每一级代码跳转之前,先验一验它的「身份证」——数字签名。

嗯,这里要注意:安全启动不是防黑客入侵的万能药。它防的是「启动阶段被植入恶意代码」。你想想看,如果攻击者把你的 Flash 拆下来,焊个恶意 Bootloader 上去,系统照样能开机,但跑的是人家的后门程序。安全启动就是让这种篡改失效。

核心定义:安全启动(Secure Boot)是一种从硬件复位开始,逐级验证代码完整性与合法性的启动流程。只有通过签名的代码才能被执行,未签名或签名无效的代码被拒绝。

1.2 为什么需要安全启动?

我在项目中遇到过一件事:某款 IoT 网关设备,出厂时没开安全启动。结果客户现场被植入挖矿程序,CPU 跑满 100%,网络流量异常。最后定位发现,攻击者通过 UART 接口刷了个修改版的内核。如果当时开了安全启动,这种攻击在第一关就被拦住了。

安全启动的必要性,我总结为三点:

  • 防篡改:防止 Bootloader、内核、文件系统被物理替换或修改。
  • 防回滚:防止攻击者刷回有已知漏洞的旧版本固件。
  • 建立信任根:从硬件不可变区域开始,逐级建立信任链,确保整个启动过程可追溯、可验证。

你可能会问:我的产品是消费级的,也需要吗?我的建议是:只要设备能联网、能处理敏感数据,就应该考虑安全启动。成本增加不大,但安全收益很高。

避坑指南:我曾经见过一个团队,为了省几毛钱的 eFuse 成本,把公钥存在可擦写的 Flash 里。结果攻击者直接替换了公钥,安全启动形同虚设。记住:信任根必须是硬件不可变的,比如一次性编程的 OTP 或 eFuse。

1.3 信任链模型

信任链模型,是安全启动的骨架。我习惯把它画成一条「接力棒」——每一级代码验证下一级,直到操作系统启动完成。

典型的信任链分四层:

  1. 信任根(Root of Trust, RoT):芯片内部的 BootROM,不可修改。它包含芯片厂商烧录的公钥哈希或公钥本身。
  2. 一级 Bootloader(SPL / BL1):由 BootROM 加载并验证。通常很小,负责初始化 DDR、时钟等。
  3. 二级 Bootloader(U-Boot / BL2):由一级 Bootloader 验证。负责加载内核、设备树、ramdisk。
  4. 操作系统内核:由二级 Bootloader 验证。内核启动后,还可以继续验证内核模块和关键应用。

每一级验证通过后,才把控制权交给下一级。验证失败则进入错误处理流程——通常是死循环或重启。

个人经验:我在调试某款车规级芯片时,发现 BootROM 验证 SPL 时只检查了签名,没检查版本号。结果攻击者刷了个旧版 SPL,绕过了后续的安全补丁。后来我们在 SPL 头部加了版本号字段,并在 BootROM 里做了版本比较。这个坑,大家设计时要注意。

1.4 信任链的 SVG 流程图

下面这张图,是我在培训时经常用的。它把信任链的每一级、验证方式、失败处理都画清楚了。

安全启动信任链模型 安全启动信任链模型 信任根 (BootROM) 一级 Bootloader (SPL) 二级 Bootloader (U-Boot) 操作系统内核 关键应用 / 内核模块 验证签名+哈希 验证签名+哈希 验证签名+哈希 IMA / 模块签名验证 验证失败 → 进入错误处理 (死循环 / 重启 / 报警) 关键点 信任根必须硬件不可变 每级只信任上一级 验证失败立即停止

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 小结

安全启动的核心,就是一条从硬件信任根开始的验证链。每一级只信任上一级,验证失败就停止。它防的是启动阶段的代码篡改,但不能替代运行时安全。

我个人习惯在设计初期就把信任链画出来,标清楚每一级的验证方式、公钥存储位置、失败处理策略。这样后期调试时,能快速定位问题出在哪一级。