2、安全启动基础:可信根(Root of Trust)、信任链(Chain of Trust)、安全启动流程、与安全固件更新的关系
安全启动(Secure Boot)是嵌入式系统安全防御体系的第一道闸门,其核心目标是从系统上电复位开始,逐级验证固件镜像的完整性与真实性,确保只有经过授权且未被篡改的代码才能在MCU上执行。要深入理解安全启动,必须首先厘清四个相互关联的核心概念:可信根(Root of Trust, RoT)、信任链(Chain of Trust)、安全启动的具体执行流程,以及安全启动与安全固件更新(Secure Firmware Update)之间的协同关系。本章将逐一剖析这些基础概念,并结合实际MCU平台(如STM32H7、NXP i.MX RT系列)的典型实现,帮助学员建立完整的安全启动知识框架。
上图清晰地展示了安全启动三大核心要素之间的逻辑关系:可信根作为硬件层面的信任锚点,为信任链提供初始验证依据;信任链则通过逐级签名验证,将信任从BootROM扩展到应用固件;安全启动流程则是这一系列验证动作的具体执行路径。三者相互依存,共同构成了MCU安全启动的完整闭环。
2.1 可信根(Root of Trust)
核心原理
可信根是安全启动体系中无条件信任的硬件实体,它本身不需要被验证,因为其物理实现被固化在芯片内部,无法通过软件手段修改。在MCU中,可信根通常由以下三部分构成:
- BootROM:芯片出厂时固化的只读代码,上电后CPU首先执行它。BootROM包含初始引导逻辑、安全配置读取逻辑以及第一级签名验证算法。
- OTP(一次性可编程)存储器 / eFuse:用于永久存储根公钥的哈希值、安全启动使能位、调试接口锁定位等关键安全参数。OTP一旦写入便不可更改,这保证了攻击者无法通过修改密钥来绕过验证。
- 硬件加密引擎:如AES、RSA、ECC加速器,以及真随机数发生器(TRNG),为签名验证提供硬件级支持,防止软件侧密钥泄露。
关键理解:可信根的本质是“信任的起点”。在密码学中,任何信任链都必须有一个无需自证的起点。MCU的BootROM和OTP正是这个起点。即使攻击者完全控制了外部Flash中的固件,只要无法篡改BootROM和OTP,就无法伪造合法的签名链。
判断方法与操作流程
在实际MCU选型与配置中,工程师需要确认以下可信根要素:
- 确认芯片是否提供硬件BootROM安全启动支持(而非仅靠外部软件引导)。
- 确认OTP/eFuse的容量与分区,是否足够存储根密钥哈希(通常为SHA-256或SHA-512值)以及安全配置位。
- 确认芯片是否支持密钥撤销与更新机制(部分高端MCU支持多级OTP密钥槽)。
- 在开发阶段,通过芯片厂商提供的烧录工具(如STM32CubeProgrammer、NXP Flashloader)将根公钥哈希写入OTP,并锁定调试端口。
案例拆解:STM32H7系列可信根配置
以STM32H7为例,其BootROM位于系统存储区(System Memory),出厂时固化了USB/UART/SPI等多种引导模式。开发者需要将自定义的根公钥哈希(SHA-256)烧录到OTP区域(选项字节)。具体步骤如下:
1. 使用STM32CubeProgrammer连接MCU(通过ST-Link)。
2. 在“OTP”选项卡中,选择要写入的OTP区域(如0x1FFF7000)。
3. 输入根公钥的SHA-256哈希值(64字节十六进制)。
4. 使能“RDP”(读保护)级别2,永久禁用调试接口。
5. 烧录后,MCU每次上电都会从OTP读取该哈希,用于验证外部Flash中的二级引导加载器签名。
此案例中,OTP中的哈希值即为可信根。一旦写入并锁定,任何试图修改该哈希的行为都会导致芯片永久报废(RDP级别2不可逆),从而保证了信任锚点的绝对安全。
常见误区:部分开发者误以为将根公钥直接存储在外部Flash中即可。这是严重错误——外部Flash可被物理篡改或替换,攻击者只需替换Flash芯片并放入自己生成的密钥对即可完全绕过安全启动。可信根必须存储在MCU内部不可变介质中。
2.2 信任链(Chain of Trust)
核心原理
信任链是安全启动的“传递机制”。由于BootROM容量有限,无法承载复杂的应用固件验证逻辑,因此需要将验证过程分层。每一级固件负责验证下一级固件的签名,直到最终的应用固件通过验证并执行。典型的信任链结构如下:
| 层级 | 固件实体 | 存储位置 | 验证者 | 验证内容 |
|---|---|---|---|---|
| 第0级 | BootROM | 芯片内部ROM | 硬件(无需验证) | 自身完整性(由硬件保证) |
| 第1级 | 二级引导加载器(FSBL/SSBL) | 外部Flash起始扇区 | BootROM | FSBL的签名与哈希 |
| 第2级 | 应用固件(App) | 外部Flash应用分区 | FSBL | App的签名与哈希 |
| 第3级 | 运行时配置/脚本 | 外部Flash数据分区 | App | 配置文件的完整性(可选) |
信任链的每一环都使用上一级固件中嵌入的公钥来验证下一级固件的签名。这种设计使得即使应用固件被攻破,攻击者也无法向上回溯修改更高级别的固件,因为每一级的公钥都存储在受保护的存储介质中。
操作流程与设计要点
- 密钥分层管理:建议使用独立的密钥对分别签名FSBL和应用固件。即使应用密钥泄露,攻击者也无法签名新的FSBL。
- 签名算法选择:推荐使用RSA-2048或ECC-256。RSA验证速度较慢但兼容性好;ECC验证速度快且密钥更短,适合资源受限的MCU。
- 哈希算法:使用SHA-256或SHA-512,确保固件完整性校验的强度。
- 防回滚机制:在固件头中增加版本号字段,并在OTP中存储最低允许版本号。验证时比较版本号,防止攻击者将固件回滚到存在已知漏洞的旧版本。
实战经验:在NXP i.MX RT系列中,BootROM支持“High Assurance Boot (HAB)”,允许开发者配置最多4个密钥槽。建议将生产密钥与开发密钥分离,开发阶段使用测试密钥,量产前烧录生产密钥并锁定OTP。
案例拆解:信任链验证失败排查
某工业控制项目使用NXP i.MX RT1052,安全启动配置完成后,设备上电后无法启动,串口无输出。排查过程如下:
- 初始现象:上电后LED无规律闪烁,串口无任何打印信息。
- 分析判断:BootROM执行后,未能通过FSBL验证,进入恢复模式。
- 关键数据:通过JTAG读取BootROM状态寄存器,错误码为0x0A(签名验证失败)。
- 实际操作:使用NXP提供的
hab_status命令检查HAB状态,发现事件日志显示“SRK Hash mismatch”(SRK哈希不匹配)。进一步比对OTP中烧录的SRK哈希值与实际签名使用的SRK公钥哈希,发现开发者在生成密钥对后,烧录OTP时使用了错误的哈希值(将公钥文件本身当作哈希写入)。 - 结果对比:重新生成正确的SRK哈希并烧录后,设备正常启动。
- 复盘经验:密钥生成与烧录流程必须自动化,避免人工复制粘贴哈希值导致错误。建议使用脚本从公钥文件自动提取SHA-256哈希并写入OTP。
2.3 安全启动流程
核心原理与执行步骤
安全启动流程是可信根和信任链在具体MCU上的落地执行。不同厂商的流程略有差异,但总体遵循以下步骤:
- 上电复位:CPU从固定地址(如0x00000000或0x1FFF0000)取指,执行BootROM代码。
- 初始化安全基础设施:BootROM配置时钟、SRAM、加密引擎,并读取OTP中的安全配置(如启动模式、密钥索引、调试锁定状态)。
- 加载并验证FSBL:BootROM根据启动引脚配置,从外部Flash(或USB/UART)加载FSBL镜像到SRAM,使用OTP中的根公钥验证FSBL的签名。验证内容包括:签名有效性、镜像哈希、版本号(防回滚)。
- 跳转执行FSBL:验证通过后,CPU跳转到FSBL入口地址。FSBL继续初始化DDR、外设等,并加载应用固件。
- 验证并执行应用固件:FSBL使用自身嵌入的应用公钥验证应用固件签名,验证通过后跳转执行。
- 运行时安全监控(可选):部分MCU支持在运行时周期性地重新验证关键内存区域的完整性,防止运行时代码注入。
流程中的关键决策点
| 决策点 | 判断条件 | 动作 |
|---|---|---|
| 签名验证失败 | 签名无效或哈希不匹配 | 进入恢复模式(等待重新烧录)或执行备份固件 |
| 版本号过低 | 固件版本 < OTP中最低版本 | 拒绝启动,防止回滚攻击 |
| 调试接口未锁定 | RDP级别 < 2 | 允许调试,但存在安全风险(生产环境必须锁定) |
| 密钥索引无效 | OTP中密钥槽为空或无效 | 启动失败,进入安全错误状态 |
重要提醒:安全启动流程中,恢复模式是一个潜在的攻击面。如果恢复模式允许通过UART/USB下载任意固件,攻击者可能利用这一点绕过安全启动。生产环境中应禁用恢复模式,或要求恢复模式也必须经过签名验证。
案例拆解:安全启动流程优化
某汽车电子Tier 1供应商在MCU上实现安全启动时,发现启动时间过长(从复位到应用执行耗时约800ms),不满足整车厂500ms的要求。分析发现耗时主要消耗在RSA-2048签名验证上(BootROM验证FSBL约300ms,FSBL验证App约500ms)。优化措施:
- 将签名算法从RSA-2048切换为ECC-256,验证速度提升约5倍。
- 将FSBL与应用固件合并为一个镜像,减少一次签名验证。
- 利用MCU的硬件加密引擎并行处理哈希计算。
优化后启动时间降至约180ms,满足要求。此案例说明,安全启动流程需要在安全强度与启动性能之间做出权衡,工程师应根据实际应用场景选择合适的算法与镜像布局。
2.4 安全启动与安全固件更新的关系
核心原理
安全启动与安全固件更新(Secure Firmware Update)是相辅相成的两个安全机制。安全启动解决的是“启动时”的信任问题,而安全固件更新解决的是“运行中”的信任问题。两者共同构成了固件生命周期的安全闭环:
- 安全启动:确保设备每次上电时,只运行经过签名的固件。
- 安全固件更新:确保设备在运行过程中,只接受经过签名的固件更新包,并安全地写入Flash。
安全固件更新通常包含以下关键步骤:
- 固件包生成:在开发服务器上,使用私钥对固件镜像进行签名,生成包含固件数据、签名、版本号、设备ID等信息的更新包。
- 传输与接收:通过UART、CAN、以太网或无线方式将更新包传输到MCU。传输过程可使用TLS/DTLS加密,防止窃听。
- 验证与解密:MCU使用预先存储的公钥验证更新包签名,并使用对称密钥解密固件内容(如果固件加密)。
- 写入与切换:将新固件写入备用Flash分区(A/B分区方案),写入完成后更新启动标志,下次启动时从新分区启动。
- 回滚机制:如果新固件启动失败,启动加载器自动回滚到旧固件分区。
安全启动在固件更新中的作用
安全启动机制在固件更新过程中扮演着“最后一道防线”的角色。即使更新包在传输过程中被篡改,或者MCU的Flash被物理攻击者直接写入恶意固件,安全启动也能在下次上电时检测到签名无效并拒绝执行。因此,安全启动是安全固件更新成功与否的最终验证者。
协同设计要点:安全启动与固件更新必须共享同一套密钥管理体系。如果固件更新使用独立的密钥对,则需要在FSBL中同时嵌入更新验证公钥和启动验证公钥。建议使用统一的密钥管理平台,避免密钥碎片化。
案例拆解:OTA更新失败后的安全启动恢复
某物联网设备使用ESP32-S2(支持Secure Boot V2),通过Wi-Fi进行OTA更新。一次OTA过程中,网络中断导致固件写入不完整。设备重启后,BootROM验证新固件签名失败,但发现备份分区中的旧固件签名有效,于是自动回滚到旧固件,设备恢复正常运行。整个过程用户无感知。
此案例展示了安全启动与A/B分区回滚机制的完美配合。如果没有安全启动,设备将启动到损坏的固件,导致变砖;如果没有A/B分区,设备将无法回滚到旧版本。两者缺一不可。
| 安全机制 | 作用阶段 | 防护目标 | 依赖的硬件资源 |
|---|---|---|---|
| 安全启动 | 上电复位至应用执行 | 防止篡改固件、防止回滚 | BootROM、OTP、加密引擎 |
| 安全固件更新 | 运行期间固件升级 | 防止恶意更新包、防止传输窃听 | 安全存储(密钥)、通信加密模块 |
| A/B分区回滚 | 更新失败后恢复 | 防止设备变砖 | Flash双分区、启动标志 |
最佳实践:在MCU资源允许的情况下,建议将安全启动与固件更新整合到同一个安全服务组件中。例如,使用ARM TrustZone技术,将安全启动、密钥管理、固件验证等功能隔离在安全世界中,应用代码运行在普通世界中,即使应用被攻破,也无法访问安全密钥。
综上所述,可信根、信任链、安全启动流程与安全固件更新构成了MCU安全启动的完整知识体系。工程师在实际项目中,应首先明确可信根的硬件实现,然后设计合理的信任链层级,再结合具体的启动流程进行配置,最后将安全启动与固件更新机制统一规划。只有将这四者有机结合,才能构建起真正可靠的安全启动防线。