4. 安全启动与信任链

在 TrustZone 系统中,安全启动不是“把 Secure Boot 开关打开”这么简单,而是一条从芯片上电第一刻就开始逐级传递的信任链。它的核心目标是:每一级启动代码在执行前,都必须先验证下一级镜像的完整性与真实性;只有验证通过,控制权才被移交。这样,即使攻击者篡改了安全 OS 或 TEE 镜像,系统也会在启动阶段拒绝加载,而不是等到运行期才暴露风险。

一、信任根:BootROM 为什么不可替代

信任链必须有一个绝对可信的起点,这个起点就是 BootROM。它固化在芯片内部,通常由 SoC 厂商在流片时写入,外部无法修改。BootROM 在上电后首先运行,负责初始化最小硬件环境,例如时钟、SRAM、串行外设和熔丝控制器,然后从预定义介质读取第一阶段引导程序(BL1 或 FSBL)。

BootROM 的可信性来自三个事实:代码不可改写、执行路径固定、验证公钥或公钥哈希被烧录在 OTP/eFuse 中。因此,BootROM 成为整个信任链的信任根(Root of Trust, RoT)。后续所有镜像的验证,最终都可以追溯到这颗“根”。

信任链的本质不是“信任某一个镜像”,而是“信任根 + 逐级签名验证”的组合。只要根可信,且每一级都严格验证下一级,整条链就可信。

二、从 BootROM 到安全 OS 的启动流程

典型 ARM TrustZone 平台的启动流程可以抽象为以下阶段:

  1. BootROM 阶段:上电复位,读取 eFuse 中的根公钥哈希,加载 BL1 镜像并验证其签名。
  2. BL1 / FSBL 阶段:初始化 DDR、安全外设和 TrustZone 控制器,加载并验证 BL2。
  3. BL2 阶段:加载 BL31(EL3 运行时)、BL32(TEE OS)和 BL33(非安全 U-Boot)。
  4. BL31 阶段:建立 EL3 安全监控器,配置 SCR_EL3、安全内存映射和中断路由。
  5. BL32 阶段:安全 OS 启动,建立安全世界运行环境,等待来自非安全世界的 SMC 调用。
  6. BL33 阶段:非安全引导加载程序启动,最终进入 Rich OS(Linux/Android)。

这条路径中,每一级都携带签名证书链。验证时通常使用“公钥哈希 + 镜像哈希 + 签名”三段式校验:先用 eFuse 中的根公钥哈希验证证书链,再用证书中的公钥验证镜像签名,最后比对镜像哈希。

TrustZone 安全启动信任链:从 BootROM 到安全 OS BootROM 信任根 · eFuse 公钥哈希 BL1 / FSBL 初始化 DDR / TZC BL2 加载 BL31 / BL32 / BL33 BL31 (EL3) 安全监控器 验证签名 验证签名 验证签名 安全世界 (Secure World) BL32 / TEE OS 安全 OS 启动 建立 SMC 服务 安全内存 / TZC 受保护区域 仅安全世界可访问 非安全世界 (Normal World) BL33 / U-Boot 非安全引导 加载 Linux 内核 Rich OS Linux / Android 通过 SMC 调用 TEE 镜像签名验证三段式 ① 根公钥哈希 eFuse 中比对证书链 ② 镜像签名验证 证书公钥验签 ③ 镜像哈希比对 SHA-256 完整性校验

三、镜像签名验证的关键参数与命令

在工程实践中,镜像签名通常由构建系统完成,验证由 BootROM 和各级引导程序完成。以常见的 FIT 镜像和 ARM Trusted Firmware 为例,签名信息会写入镜像头部的证书节点。下面是一个简化的签名与验证配置示例:

# 生成签名密钥对
openssl genrsa -out root_priv.pem 4096
openssl rsa -in root_priv.pem -pubout -out root_pub.pem

# 计算镜像哈希并签名
openssl dgst -sha256 -sign root_priv.pem -out bl32.sig bl32.bin

# 将公钥哈希烧录到 eFuse(示意)
fuse_prog --bank 0 --row 0x20 --value $(sha256sum root_pub.pem | cut -d' ' -f1)

# 启动日志中验证成功的典型输出
NOTICE:  BL1: Booting BL2
NOTICE:  BL2: Loading BL31
NOTICE:  BL2: Loading BL32
NOTICE:  BL31: Secure code at 0x7e000000
NOTICE:  BL32: TEE OS initialized

验证失败时,BootROM 或 BL2 会停止启动并进入错误状态,常见日志如下:

ERROR:   BL1: Image authentication failed
ERROR:   BL1: Hash mismatch for BL2
ERROR:   System halted due to secure boot failure

四、信任根建立与安全启动实战要点

阶段 验证对象 验证者 关键动作
BootROM BL1 BootROM 读取 eFuse 根公钥哈希,验证 BL1 签名
BL1 BL2 BL1 初始化 DDR,验证 BL2 证书链
BL2 BL31 / BL32 / BL33 BL2 分别验证三个镜像的签名与哈希
BL31 EL3 运行时 自身 配置 SCR_EL3、安全中断路由
BL32 安全 OS BL32 建立安全世界,注册 SMC 服务
BL33 Rich OS BL33 启动非安全内核,进入 Normal World
实战中建议开启“安全启动 + 回滚保护”。回滚保护通过单调计数器(Monotonic Counter)记录已使用的最小版本号,防止攻击者将系统降级到存在已知漏洞的旧版本。

五、常见误区与复盘

  • 误区一:只签名不验证。签名只是生成签名值,若启动阶段不执行验证,信任链就是断的。
  • 误区二:根公钥可写。根公钥或哈希必须烧录在 OTP/eFuse 中,不能存放在可被篡改的 Flash 中。
  • 误区三:忽略 BL33 验证。非安全世界同样需要验证,否则攻击者可从 Rich OS 侧破坏系统完整性。
  • 误区四:没有回滚保护。旧版本镜像即使签名有效,也可能存在已知漏洞,必须结合版本号进行限制。

复盘时,可以用“信任链断点排查法”:从 BootROM 开始,逐级确认每一级的验证是否开启、公钥来源是否可信、失败日志是否明确。只要有一级验证缺失或公钥可替换,整条信任链就不可信。安全启动的最终目标,是让安全 OS 在启动时已经处于一个可验证、可度量、可追溯的可信状态,为后续的 TrustZone 安全调用与跨域通信提供坚实基础。