3. 安全启动信任链架构
安全启动的本质不是“把固件加密”,而是让芯片在每一次上电时,都能从一段无法被篡改的代码开始,逐级验证后续代码的完整性与合法性。Silicon Labs 的 Secure Vault 系列(如 EFR32MG24、EFR32BG24)把这条验证路径固化在硬件与不可变 ROM 中,形成一条从复位向量到应用固件的信任链。理解这条链的关键,是分清三个角色:不可变 ROM 引导、一级引导(First Stage Bootloader,FSBL)、二级引导(Second Stage Bootloader,SSBL),以及它们之间“谁验证谁、谁把控制权交给谁”的传递关系。
不可变 ROM 引导:信任的根
芯片复位后,CPU 从 ROM 中的复位向量开始执行。这段 ROM 代码在制造时写入,用户无法擦除或修改,因此它天然成为信任根(Root of Trust)。ROM 引导做的事情非常克制:初始化最小必要的时钟与安全外设,读取芯片配置区(如 Secure Vault 的密钥存储、生命周期状态),然后决定从哪里加载下一级引导。它不解析复杂的文件系统,也不执行用户代码,只做“取指—校验—跳转”这一件事。
ROM 引导验证的对象是存放在 Flash 中的一级引导镜像。验证依据是镜像头部的元数据:镜像长度、版本、以及一段由厂商私钥签名的摘要。ROM 内部固化了对应的公钥或公钥哈希,因此攻击者即使替换 Flash 内容,也无法伪造出能通过校验的签名。校验通过后,ROM 把控制权交给 FSBL;校验失败则进入锁定或复位循环,不会执行任何未验证代码。
一级引导与二级引导的分工
一级引导(FSBL)通常由芯片厂商提供或由用户在受控环境下烧录,它的职责是“把信任扩展到可升级区域”。FSBL 会验证二级引导(SSBL)的签名,并可能承担密钥轮换、防回滚检查、以及从外部 Flash 或 OTA 暂存区加载镜像的工作。二级引导则更接近应用:它验证主应用固件,处理应用镜像的完整性,并最终跳转到应用入口。
这种两级划分不是冗余。FSBL 代码量小、变更少,适合放在受保护区域;SSBL 可以随产品迭代更新,承担更灵活的加载策略。两者之间的边界由安全策略决定:如果产品不需要 OTA,可以只保留 FSBL 直接验证应用;如果需要多镜像切换或差分升级,SSBL 就是必要的中间层。
信任链传递机制:公钥的“接力”
信任链能够传递,靠的是公钥的逐级固化或逐级验证。ROM 中固化的是 FSBL 公钥(或其哈希),FSBL 镜像中携带 SSBL 公钥,SSBL 镜像中携带应用公钥。每一级在跳转前,用自己信任的公钥去验证下一级镜像的签名。这样,攻击者要篡改应用,就必须同时篡改 SSBL 的签名;要篡改 SSBL,又必须篡改 FSBL 的签名;而 FSBL 的签名验证依赖 ROM 中的公钥,ROM 不可改,链条就断不了。
实际工程中,公钥通常不是直接明文存放,而是存放其哈希值,镜像中携带完整公钥。验证时先对公钥做哈希,与固化哈希比对,再用该公钥验证签名。这样做的好处是节省 ROM 空间,同时避免公钥被替换。Silicon Labs 的 Secure Vault 还支持密钥在安全存储中加密保存,只有安全域代码才能读取,进一步降低密钥泄露风险。
启动阶段度量与验证流程
“度量”与“验证”是两个容易混淆的概念。度量(Measurement)是计算镜像的哈希值并记录,用于后续审计或远程证明;验证(Verification)是把计算出的哈希与签名中的摘要比对,决定是否放行。安全启动必须做验证,度量则是可选增强。在 EFR32 上,度量值可以写入安全存储区,供应用启动后读取并上报。
一次典型的启动验证流程如下:复位后 ROM 读取 FSBL 镜像头,计算镜像体的 SHA-256,用 ROM 内公钥验证 ECDSA 签名,同时检查版本计数器是否低于已记录的最低版本。三项都通过,跳转 FSBL。FSBL 对 SSBL 重复同样的过程,SSBL 再对应用重复。任何一项失败,芯片进入锁定状态,只有通过调试接口或特定恢复流程才能解锁。
工程实现中的关键参数与观察点
以 EFR32MG24 为例,FSBL 通常占用 Flash 起始的 32 KB 左右,SSBL 占用接下来的 32~64 KB,应用从 0x00010000 之后开始。镜像头一般包含 magic、版本、镜像长度、签名算法、公钥哈希、签名值等字段。开发时可以用 Simplicity Studio 的 Secure Boot 配置工具生成密钥对和签名后的镜像,也可以使用 commander 工具链完成烧录与校验。
# 示例:使用 commander 对应用镜像签名并生成带元数据的 GBL 文件
commander gbl create app.gbl --app app.s37 \
--sign key.pem --version 0x00010002 \
--secure-boot
# 烧录 FSBL、SSBL 与应用
commander flash fsbl.s37 --address 0x00000000
commander flash ssbl.s37 --address 0x00008000
commander flash app.gbl --address 0x00010000
启动后可以通过串口日志观察验证结果。正常启动时,FSBL 会打印类似 FSBL: verify SSBL OK, version 0x00010001 的信息;如果签名不匹配,则输出 FSBL: signature verify failed, halt 并停止。调试阶段还可以读取安全存储中的度量寄存器,确认每一级的哈希值与预期一致。判断启动是否成功,不能只看“程序跑起来了”,而要确认日志中每一级验证都明确通过,且版本计数器符合预期。
总结来看,安全启动信任链的稳固性来自三个设计:ROM 不可改、公钥逐级固化、验证失败即锁定。FSBL 与 SSBL 的分层让信任可以延伸到可升级区域,而度量与版本计数器则让启动过程可审计、可防回滚。理解每一级“验证谁、用什么验证、失败怎么办”,就能在实际项目中正确配置镜像布局、密钥存储和启动策略,而不是把安全启动当成一个开关。