2. 安全启动基础:安全启动的概念与重要性、信任根(RoT)建立、安全启动的信任链传递机制
好,我们进入第二章。这一章讲的是安全启动的基础,说白了就是回答三个问题:为什么要做安全启动?信任从哪里开始?信任怎么一级一级传下去?
我在做嵌入式安全这些年,见过太多因为启动阶段被攻破而全盘皆输的项目。有一次,一个做智能门锁的客户找到我,说他们的锁被人用几块钱的烧录器就给破解了——攻击者直接替换了Flash里的固件,门锁就变成了别人的“遥控器”。嗯,这就是典型的启动阶段没有做安全校验的后果。
2.1 安全启动的概念与重要性
安全启动(Secure Boot),简单来说,就是确保设备上电后,执行的每一段代码都是经过认证的、未被篡改的。它不是一个单一的技术,而是一套从硬件到软件的完整校验机制。
核心定义:安全启动保证设备从复位向量开始,到操作系统内核加载完毕,整个执行路径上的所有代码镜像都经过数字签名验证,任何未经签名的代码都无法被执行。
为什么它这么重要?我列几个真实场景你就明白了:
- 防固件逆向:攻击者无法替换成自己的调试固件来dump内存
- 防恶意升级:只有官方签名的固件才能被加载运行
- 防持久化后门:即使设备被物理接触,也无法植入持久性恶意代码
- 满足合规要求:国密标准、等保2.0、GDPR等都对启动安全有明确要求
我个人习惯把安全启动比作“设备的出生证明”——如果出生那一刻就被调包了,后面再怎么加密、再怎么防护都是白搭。
2.2 信任根(RoT)建立
信任根(Root of Trust, RoT)是安全启动的起点。你想想看,如果整个校验链条是环环相扣的,那总得有一个不需要被验证、天生就是可信的东西吧?这个就是信任根。
2.2.1 信任根的类型
| 类型 | 载体 | 特点 | 典型实现 |
|---|---|---|---|
| 硬件信任根 | ROM、eFuse、OTP | 不可篡改、物理隔离 | BootROM中的公钥Hash |
| 软件信任根 | 不可变存储区 | 可更新但需签名 | 安全世界中的初始加载器 |
| 混合信任根 | ROM + 可编程逻辑 | 兼顾安全性与灵活性 | eFuse存储根密钥,ROM执行校验 |
在实际项目中,硬件信任根是最可靠的。我曾经在一个车规级项目中,客户坚持要用纯软件信任根,结果被我们否决了——原因很简单:如果攻击者能通过JTAG或电压故障注入修改软件信任根所在的Flash区域,那整个安全体系就崩塌了。
2.2.2 信任根的建立过程
信任根的建立通常分三步:
- 固化根密钥:在芯片制造阶段,将根公钥的Hash值烧录到一次性可编程(OTP)存储器或eFuse中。这个值一旦写入,物理上就无法修改。
- BootROM固化:芯片上电后,首先执行的是片内BootROM中的代码。这段代码是掩膜在芯片内部的,无法被外部改写。
- 首次校验:BootROM从OTP中读取根公钥Hash,然后验证下一级Bootloader的数字签名。
避坑指南:我曾经在一个项目中,发现工程师把根公钥直接以明文形式存储在Flash里,然后BootROM去读这个公钥来验签。这等于把保险柜的钥匙贴在保险柜外面。正确的做法是:只存储根公钥的Hash,公钥本身放在被签名的镜像中。
2.3 安全启动的信任链传递机制
信任根建立之后,剩下的问题就是:信任怎么传递下去?这就是信任链(Chain of Trust)要做的事。
2.3.1 信任链传递模型
典型的信任链传递是这样的:
- Stage 0(BootROM):上电后执行,验证Stage 1的签名。如果验证失败,进入恢复模式或死循环。
- Stage 1(SPL/FSBL):初始化DDR、时钟等基础外设,验证Stage 2的签名。
- Stage 2(UBoot/LK):加载并验证操作系统内核(如Linux Kernel)的签名。
- Stage 3(OS Kernel):验证文件系统、内核模块、应用程序的签名。
每一级只信任上一级,上一级只负责验证下一级。这就是“信任不传递,只验证”的原则。
重要提醒:信任链中任何一个环节的校验失败,都必须立即停止启动流程,不能有任何“降级”或“跳过”的选项。我见过一个案例,某厂商在调试阶段为了方便,加了一个“跳过签名校验”的GPIO引脚,结果量产时忘了关闭——攻击者只需要拉低这个引脚就能绕过整个安全启动。
2.3.2 信任链的SVG流程图
下面这张图展示了典型的四级信任链传递过程:
2.3.3 信任链中的关键设计原则
在实际工程中,设计信任链要遵循几个原则:
- 最小化原则:信任根越小越好,BootROM代码越少,攻击面就越小。我见过一些芯片的BootROM有几十KB,里面塞了各种调试接口——这其实很危险。
- 单向验证:信任只能从低级向高级传递,不能反向。也就是说,OS Kernel不能去验证BootROM的完整性——因为BootROM已经执行完了,验证它没有意义。
- 防回滚:信任链中要加入版本号检查,防止攻击者用旧版本的签名固件进行降级攻击。这个我在后面讲固件升级时会详细展开。
- 硬件隔离:每一级的代码和数据要有物理或强制的访问控制隔离。比如BootROM不能访问OS Kernel的内存区域,反之亦然。
个人经验:我曾经在一个IoT项目中,发现信任链设计得“太完美”了——四级校验,每一级都用了不同的算法和密钥。结果呢?启动时间从200ms变成了2.8秒,产品经理直接炸了。后来我们做了优化:BootROM到SPL用硬件加速的SM2验签,SPL到UBoot用SM3-HMAC做快速校验,UBoot到Kernel才做完整的SM2签名验证。这样既保证了安全,又把启动时间控制在了500ms以内。
2.4 国密算法在安全启动中的应用
既然我们这门课叫《国密算法启动校验与固件保护技术》,那自然要聊聊国密算法在安全启动中怎么用。
| 国密算法 | 在安全启动中的角色 | 典型应用场景 |
|---|---|---|
| SM2 | 数字签名验签 | 固件镜像签名、Bootloader签名验证 |
| SM3 | 哈希校验 | 固件完整性校验、信任链中的快速校验 |
| SM4 | 对称加密(可选) | 固件镜像加密存储、传输加密 |
在实际项目中,我建议的搭配是:SM2做签名验签,SM3做完整性校验,SM4做加密存储。三者配合,基本能覆盖安全启动的所有需求。
注意:国密算法的实现一定要使用经过国密局认证的硬件密码模块或软件库。我曾经在一个项目中,工程师自己实现了一个SM2验签函数,结果验签速度慢不说,还有侧信道漏洞——攻击者通过分析功耗曲线就能提取出私钥。嗯,这个坑我们后面会专门讲。
2.5 本章小结
好,我们来捋一下这一章的核心内容:
- 安全启动是设备安全的第一道防线,确保从复位开始执行的每一段代码都是可信的。
- 信任根(RoT)是安全启动的基石,通常固化在芯片的BootROM和OTP中,物理上不可篡改。
- 信任链传递采用“逐级验证”的机制,每一级只验证下一级,任何一级失败则立即停止启动。
- 国密算法(SM2/SM3/SM4)可以完美嵌入安全启动流程,满足国内合规要求。