3. 开机启动流程与信任链:BIOS/UEFI启动过程、信任链的建立与传递、度量点分析
各位同学,今天我们聊一个非常核心的话题——开机启动流程与信任链。
很多做可信计算的朋友,一开始都会问一个问题:“度量点到底放在哪里?” 这个问题不搞清楚,后面策略配置、策略比对全都白搭。我个人习惯,每次接手一个新平台,第一件事就是先把启动流程跑一遍,把每个阶段的度量点标出来。
说白了,信任链的建立,就是从“一个可信的起点”开始,一步一步把信任传递下去。如果起点不可信,后面全是白费功夫。
3.1 BIOS vs UEFI:两种启动方式,两种信任模型
先区分两个概念:BIOS(传统) 和 UEFI(现代)。
我在项目中遇到过不少团队,还在用传统 BIOS 启动方式做可信度量,结果发现度量点根本对不上。为什么?因为两者的启动流程完全不同。
| 对比项 | 传统 BIOS | UEFI |
|---|---|---|
| 启动阶段 | POST → 引导扇区 → 引导程序 → OS | SEC → PEI → DXE → BDS → TSL → RT |
| 度量起点 | BIOS ROM(通常无硬件保护) | SEC 阶段(有 CRTM 保护) |
| 度量方式 | 通常依赖外部 TPM 或软件度量 | 原生支持 TCG 协议,UEFI 固件自带度量 |
| 扩展性 | 差,引导扇区大小受限 | 好,支持驱动模块化加载 |
| 安全启动 | 无原生支持 | 支持 Secure Boot |
你想想看,传统 BIOS 的启动流程其实很简单:上电 → POST → 读 MBR → 加载引导程序 → 启动 OS。但问题在于,MBR 是可以被篡改的,而且 BIOS 本身没有对 MBR 做度量。
UEFI 就不一样了。它把启动分成了 7 个阶段,每个阶段都有明确的职责和度量点。嗯,这里要注意,UEFI 的 SEC 阶段是整个信任链的根,也就是我们常说的 CRTM(Core Root of Trust for Measurement)。
3.2 信任链的建立与传递:从 CRTM 到 OS
信任链的建立,其实就是一个“度量-扩展-记录-传递”的循环过程。
我画了一张图,帮你理清这个流程:
这张图的核心逻辑是:前一个阶段度量后一个阶段。CRTM 度量 PEI,PEI 度量 DXE,DXE 度量 BDS……一直传递到 OS 内核。
每个阶段度量完成后,会做三件事:
- 扩展 PCR 寄存器:把度量值哈希后扩展到 TPM 的 PCR 中
- 记录度量日志:把度量事件记录到日志中,供远程验证使用
- 传递控制权:把执行权交给下一个阶段
核心要点:信任链的强度取决于最薄弱的环节。如果 CRTM 本身不可信,整个信任链就崩塌了。所以,CRTM 必须被硬件保护,通常固化在芯片组或 CPU 的微码中。
3.3 度量点分析:在哪里度量?度量什么?
好了,流程清楚了,接下来我们看看具体的度量点。
我在项目中遇到过最典型的问题:度量点选错了,或者漏掉了关键阶段。结果就是,攻击者绕过了度量,直接篡改了某个阶段的代码,而系统却认为一切正常。
下面这张表,是我整理的标准 UEFI 启动各阶段的度量点:
| 阶段 | 度量对象 | PCR 索引 | 度量时机 |
|---|---|---|---|
| SEC | CRTM 自身完整性 | PCR-0 | 上电后立即度量 |
| PEI | PEI 核心、PEIM 模块、S3 恢复代码 | PCR-0 | PEI 阶段初始化时 |
| DXE | DXE 核心、DXE 驱动、ACPI 表、SMBIOS 表 | PCR-1 | DXE 驱动加载时 |
| BDS | 启动策略、启动选项、设备路径 | PCR-2 | BDS 阶段选择启动设备时 |
| TSL | OS 加载器(bootloader)、内核、initrd | PCR-4 | OS 加载器被加载时 |
| RT | OS 内核、关键驱动、安全策略 | PCR-5 ~ PCR-7 | OS 启动过程中 |
你可能会问:为什么 PCR 索引是固定的?
这是 TCG 规范定义的。PCR-0 到 PCR-7 有明确的用途,不能乱用。比如 PCR-0 专门度量固件代码,PCR-1 度量固件配置,PCR-2 度量 Option ROM……
实战小技巧:在做策略配置时,一定要先确认你的平台使用的是哪个 PCR 索引。不同厂商的固件实现可能有细微差异。我建议你先 dump 一次 PCR 值,看看实际度量了哪些内容,再写策略。
3.4 避坑指南:常见度量点配置错误
讲到这里,我想分享几个我在项目中踩过的坑:
- 坑一:只度量了 OS 加载器,没度量固件
我曾经遇到一个客户,只配置了 PCR-4 的度量策略,结果攻击者篡改了 UEFI 固件,系统照样启动。因为 PCR-0 到 PCR-3 根本没被监控。 - 坑二:度量了不该度量的内容
有些固件会把动态数据(比如时间戳)也度量进去,导致每次启动的度量值都不一样。策略比对永远失败。 - 坑三:忽略了 S3 恢复路径
从 S3 睡眠恢复时,系统会跳过部分度量。如果攻击者在 S3 状态下篡改固件,恢复后系统不会重新度量。嗯,这个坑我踩过两次。
重要提醒:度量点配置不是越多越好。度量太多会影响启动性能,而且可能引入不必要的噪声。我的建议是:先覆盖关键路径(固件、OS 加载器、内核),再根据安全需求逐步扩展。
3.5 实战:如何验证信任链是否完整
最后,我们聊聊怎么验证信任链是否真的建立起来了。
我个人习惯用 tpm2-tools 来检查。下面是一个简单的验证流程:
# 1. 读取 PCR 值
tpm2_pcrread sha256:0,1,2,4
# 2. 查看度量日志
tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
# 3. 比对预期值
# 如果 PCR 值与预期一致,说明信任链完整
# 如果不一致,说明某个环节被篡改
你想想看,如果 PCR-0 的值和出厂时记录的值一致,说明固件没有被篡改。如果 PCR-4 的值和已知的 OS 加载器哈希一致,说明 bootloader 是可信的。
这就是信任链的验证逻辑——从根到叶,逐级比对。
好了,这一章的内容就到这里。信任链的建立是整个可信计算体系的基石,后面的策略配置、远程证明都依赖它。希望你能把这张图、这张表记在心里,做项目的时候少踩坑。