2. VxWorks安全启动链设计

VxWorks的安全启动不是单一功能,而是一条从芯片上电到内核接管控制权之间逐级传递信任的链条。它的核心思想是:每一级代码在执行前,都必须先验证下一级镜像的完整性与真实性,只有验证通过才交出控制权。这条链的起点是固化在芯片内部、不可被外部修改的BootROM,终点是完成初始化并进入应用态的内核。任何一级验签失败,启动流程都应在该级终止,而不是“跳过继续”。

理解这条链,需要先明确三个基本对象:信任根(Root of Trust,RoT)、被验证镜像、以及验证策略。信任根通常由芯片内的BootROM代码和其内置的公钥哈希(或公钥本身)构成,它是整条链唯一无条件被信任的部分。被验证镜像包括BootROM之后加载的引导程序(如VxWorks的bootrom.bin或U-Boot)、VxWorks内核镜像(vxWorks)、以及可选的设备树、文件系统或应用镜像。验证策略则规定了“用什么算法、验什么、失败怎么办”。

VxWorks 安全启动信任链:从 BootROM 到内核 ① BootROM(信任根) 固化代码,不可修改 内置公钥哈希 / OTP 验证 bootrom.bin 签名 ② 引导程序 bootrom.bin / U-Boot 验证 vxWorks 镜像签名 检查版本号防回滚 ③ VxWorks 内核 vxWorks 镜像 验证设备树 / 文件系统 启动应用任务 ④ 应用镜像 可选验证 签名 / 哈希 验签流程(以 RSA-2048 + SHA-256 为例) 1. 读取镜像头部签名区与公钥证书 2. 用信任根公钥验证证书链合法性 3. 计算镜像体 SHA-256 摘要 4. 用证书公钥解密签名,比对摘要 5. 比对一致 → 通过;不一致 → 终止启动 防回滚机制(Anti-Rollback) • 镜像头携带单调递增版本号 SVN • OTP / eFuse 中存储当前最低允许版本 • 启动时比较:镜像 SVN ≥ OTP 记录值 • 低于记录值 → 拒绝启动,防止降级攻击 • 升级成功后,OTP 版本号同步递增 验签失败处理策略(工程配置项) • 策略 A:直接停机(Halt),不加载任何后续镜像,适用于高安全等级场景 • 策略 B:回退到备份分区(A/B 分区),需确保备份分区同样经过验签 • 策略 C:进入恢复模式,仅允许通过已认证的调试接口重新烧录 • 禁止策略:跳过验签继续启动(仅用于研发调试,量产必须关闭)

镜像签名与验签流程

VxWorks 镜像的签名通常采用“先哈希、再签名”的方式。以 RSA-2048 + SHA-256 为例,签名方在构建阶段对镜像体计算 SHA-256 摘要,然后用私钥对摘要加密,生成签名值,并将签名值、公钥证书、版本号等信息写入镜像头部的签名区。验签方在启动时读取签名区,先用信任根中预置的公钥(或其哈希)验证证书链,确认公钥来源可信;再用该公钥解密签名值,得到原始摘要;最后对镜像体重新计算 SHA-256,与解密得到的摘要比对。两者一致,说明镜像未被篡改且来源可信。

工程实现中,签名区通常采用固定偏移和固定长度,便于 BootROM 在极早期阶段直接定位。例如,可将签名区放在镜像起始偏移 0x1000 处,长度 512 字节,其中包含 256 字节 RSA 签名、256 字节证书信息。BootROM 只需读取该区域即可完成验证,无需解析完整镜像格式。这种“固定位置、固定长度”的设计,能显著降低信任根代码的复杂度,减少攻击面。

安全启动策略配置

VxWorks 的安全启动策略通常通过配置头文件或启动参数进行设置。以下是一个典型的策略配置示例,用于说明关键字段的含义:

/* 安全启动策略配置示例(教学用) */
#define SECURE_BOOT_ENABLE        1
#define SECURE_BOOT_ALGO          RSA2048_SHA256
#define SECURE_BOOT_ROOT_KEY_HASH "3a7f...c2e1"  /* 信任根公钥哈希 */
#define SECURE_BOOT_FAIL_ACTION   HALT            /* 失败动作:停机 */
#define ANTI_ROLLBACK_ENABLE      1
#define ANTI_ROLLBACK_MIN_SVN     5               /* 最低允许版本号 */
#define SECURE_BOOT_VERIFY_DTB    1               /* 是否验证设备树 */
#define SECURE_BOOT_VERIFY_FS     0               /* 是否验证文件系统 */

其中,SECURE_BOOT_FAIL_ACTION 决定了验签失败后的行为。在高安全等级场景中,应设置为 HALT,即直接停机,不加载任何后续镜像。若系统需要高可用性,可配置为回退到备份分区,但备份分区同样必须经过验签,否则回退机制本身就会成为绕过安全启动的漏洞。ANTI_ROLLBACK_MIN_SVN 则与 OTP 中的版本记录配合使用,防止攻击者将系统降级到存在已知漏洞的旧版本。

防回滚机制

防回滚的核心是“版本号单调递增 + 硬件存储最低允许版本”。每个镜像在构建时都会被赋予一个安全版本号(SVN),该版本号写入镜像头。设备首次烧录或升级时,OTP/eFuse 中会记录当前已接受的最低 SVN。启动时,BootROM 或引导程序会比较镜像 SVN 与 OTP 记录值:若镜像 SVN 小于记录值,则拒绝启动。升级成功后,OTP 中的版本号同步递增,旧版本镜像即使签名合法也无法再被启动。

工程上需要注意:OTP 的写入通常是不可逆的,因此版本号的递增策略必须在产品生命周期内提前规划。例如,若预计未来三年会有 10 次安全升级,则 SVN 应预留足够的递增空间,避免过早耗尽。同时,升级流程中应先验证新镜像的签名和版本号,确认无误后再写入 OTP,防止因升级失败导致设备无法启动。

工程实现要点

在实际项目中,安全启动链的落地需要关注以下几点。第一,信任根的公钥哈希必须通过安全渠道烧录到 OTP 或受保护的 Flash 区域,不能与镜像放在同一可写分区。第二,BootROM 的验签代码应尽量精简,避免引入复杂的解析逻辑,减少被利用的可能。第三,签名私钥必须离线保存,构建服务器只持有公钥,签名操作在隔离环境中完成。第四,调试接口(如 JTAG)在量产版本中应禁用或锁定,防止通过调试通道绕过安全启动。第五,应保留完整的启动日志,记录每一级验签的结果和版本号,便于现场排障和审计。

安全启动链的每一级都应遵循“先验证、后执行”的原则。任何一级跳过验证,都会使整条链的信任传递失效。工程中最常见的错误是:BootROM 验证了引导程序,但引导程序未验证内核,导致攻击者可以替换内核镜像。
防回滚机制依赖 OTP 的不可逆写入,一旦版本号写错或升级流程中断,可能导致设备无法启动。建议在量产前充分测试升级与回滚场景,并保留恢复模式作为最后手段。