4. 密码学基础

安全启动,说白了就是让芯片只运行你授权的代码。我见过不少产品,功能做得花里胡哨,结果启动链上有个漏洞,整个系统就跟没锁门一样。今天咱们就聊聊英飞凌HSM里这套启动流程到底怎么设计的。

4.1 BootROM:信任的起点

BootROM是芯片上电后执行的第一段代码。它固化在ROM里,出厂后改不了。为什么放在ROM里?因为ROM没法被篡改,这就是信任链的根。

我个人习惯把BootROM比作“看门老头”——他手里有一把钥匙,只认特定的签名。谁来敲门都得亮出身份,否则门不开。

BootROM的核心职责:

  • 初始化硬件(时钟、内存、HSM外设)
  • 验证下一级Bootloader的签名
  • 建立信任链的根
  • 提供回滚保护检查

BootROM里通常包含以下几部分:

模块 功能 存储位置
硬件初始化 配置PLL、SRAM、HSM引擎 ROM
公钥哈希 存储根公钥的哈希值(用于校验公钥完整性) eFuse/OTP
签名验证引擎 调用HSM硬件加速进行ECDSA/RSA验签 ROM
回滚计数器 读取并比较版本号 eFuse/Flash

嗯,这里要注意:公钥本身不放在ROM里,ROM里只存公钥的哈希。公钥放在Flash里,BootROM先算公钥的哈希,跟eFuse里的值比对,一致了才用这个公钥去验签。为什么要绕这么一圈?因为公钥可能更新,但ROM改不了。哈希放eFuse里,更新公钥时只需要烧新的eFuse就行。

4.2 启动链验证:多级签名校验

启动不是一步到位的。你想想看,BootROM才几十KB,它不可能把整个操作系统都验一遍。所以设计上采用链式验证:每一级只验下一级,层层递进。

典型的英飞凌HSM启动链长这样:

BootROM → Bootloader (BL1) → 应用Bootloader (BL2) → OS/App

每一级都做三件事:

  1. 读取下一级镜像:从Flash指定地址加载
  2. 验证签名:用当前级的公钥验下一级的签名
  3. 检查版本号:确保不低于当前运行版本
  4. 跳转执行:通过后把控制权交给下一级

我在项目中遇到过一个问题:客户把三级启动链改成了五级,结果启动时间从200ms飙到了800ms。为什么?每一级验签都要做一次ECDSA P-256运算,大概耗时40-60ms。五级就是200-300ms,再加上镜像加载和哈希计算,时间就上去了。所以我的建议是:启动链别超过三级,除非你有硬实时要求。

经验之谈:

我曾经帮一个客户优化启动时间,把三级验签改成两级——BootROM直接验应用Bootloader,省掉中间那一级。前提是应用Bootloader足够小,能放在BootROM能访问的固定地址。这样启动时间直接砍掉40%。

4.3 签名验证流程详解

签名验证不是简单地把签名解出来比对。完整的流程是这样的:

1. 从Flash读取镜像 + 签名 + 证书链
2. 用根公钥哈希验证证书链中的公钥
3. 用验证通过的公钥验签
4. 计算镜像哈希,与签名中的哈希比对
5. 检查镜像版本号 ≥ 回滚计数器值
6. 全部通过 → 跳转执行

这里有个细节:签名里包含的是镜像哈希的签名,不是镜像本身的签名。为什么?因为非对称签名慢,哈希计算快。先算哈希,再对哈希签名,效率高得多。

我个人习惯在镜像头部放一个结构体,包含版本号、镜像大小、哈希算法ID、签名算法ID、签名值。这样BootROM解析起来方便,不用猜。

避坑指南:

我曾经见过一个案例,开发者在镜像头部放了签名,但没放哈希算法ID。结果BootROM默认用SHA-256,实际镜像用的是SHA-384,验签一直失败。排查了两天才找到原因。所以镜像头部一定要显式声明算法ID,别用默认值。

4.4 回滚保护机制

回滚攻击是什么?黑客拿到一个旧版本固件,里面有已知漏洞,然后强制设备降级到这个版本。如果不做保护,你的安全更新就白费了。

英飞凌HSM支持两种回滚保护方式:

方式 原理 优点 缺点
eFuse计数器 每次升级烧断一根eFuse,BootROM检查版本号≥已烧断数 不可逆,安全性高 eFuse数量有限(通常16-32根)
Flash版本号 在Flash中存储版本号,BootROM比较 可多次升级 Flash可被擦写,安全性较低

我建议的做法是:关键安全更新用eFuse计数器,普通功能更新用Flash版本号。比如修复了远程代码执行漏洞的版本,必须烧eFuse,防止黑客降级回去。

回滚保护的检查时机:

  • 每次启动时,BootROM读取镜像版本号
  • 与eFuse/Flash中的回滚计数器比对
  • 如果镜像版本号 < 回滚计数器值,拒绝启动
  • 如果镜像版本号 ≥ 回滚计数器值,允许启动

关键设计原则:

回滚计数器只能增加,不能减少。eFuse烧断了就接不回去,Flash里的计数器也要用特殊保护(比如写保护位)。我曾经见过一个产品,回滚计数器放在普通Flash区域,黑客直接擦掉整个Flash,计数器归零,然后刷回旧版本。这就是设计缺陷。

4.5 安全启动流程图

下面这张图展示了完整的启动流程。我把它画成了SVG,方便你理解各环节的关系。

英飞凌HSM安全启动流程图 英飞凌HSM安全启动流程图 上电复位 BootROM执行 读取BL1镜像 验证公钥哈希 ECDSA验签 + 版本号比对 镜像哈希 vs 签名哈希 启动失败 / 进入恢复模式 跳转执行BL1 说明: 每一级Bootloader重复上述流程(读取→验公钥→验签→版本检查→跳转),直到最终OS/App启动。 eFuse回滚计数器在BootROM阶段读取,后续各级只读不写。

4.6 实际部署中的注意事项

部署安全启动时,有几个坑我踩过,分享给你:

  • 公钥哈希的保护:eFuse烧录后要锁定,防止被篡改。我见过有人忘了锁,结果攻击者直接改哈希,用自己的公钥替换了。
  • 签名算法的选择:英飞凌HSM支持ECDSA和RSA。我个人偏好ECDSA P-256,密钥短、速度快、安全性够。RSA-2048也行,但验签慢一些。
  • 版本号管理:版本号要单调递增,不能回退。建议用时间戳或递增计数器,别用语义化版本号(比如v2.1.3),因为比较起来麻烦。
  • 恢复机制:万一签名验证失败,设备不能变砖。要留一个恢复模式,比如通过串口或USB刷入新固件。但这个恢复模式本身也要有签名保护,否则就是后门。

重要提醒:

我曾经帮一个客户做安全审计,发现他们的恢复模式没有签名验证,任何人都能通过串口刷任意固件。这等于安全启动白做了。恢复模式必须跟正常启动一样严格,甚至更严格——因为攻击者可能物理接触设备。

4.7 性能与安全的权衡

安全启动不是免费的。每次验签都要消耗时间和算力。我整理了一个参考数据:

操作 耗时(典型值) 说明
SHA-256(256KB镜像) ~5ms HSM硬件加速
ECDSA P-256验签 ~40ms HSM硬件加速
RSA-2048验签 ~60ms HSM硬件加速
eFuse读取 ~1ms 直接内存映射
Flash读取(256KB) ~10ms Quad SPI模式

所以一个三级启动链,总耗时大概在150-200ms。如果你的产品要求1秒内启动,这个时间是可以接受的。但如果要求100ms以内,就得考虑优化了——比如减少启动级数,或者用更大的镜像块减少读取次数。

嗯,安全启动这块内容比较多,但核心就三点:BootROM是信任根、链式验证层层把关、回滚保护防止降级攻击。把这三点吃透了,英飞凌HSM的安全启动方案你就能拿捏住。