2. 度量架构设计:PCR寄存器详解、度量事件日志格式、度量代理架构

度量架构,说白了就是固件信任链的“记账本”和“审计员”。

我刚开始接触TPM时,总觉得PCR就是个计数器。后来踩了坑才明白——PCR的设计直接决定了度量结果能不能被信任。这一章,咱们就把PCR寄存器、事件日志和度量代理这三个核心组件拆开揉碎了讲。

2.1 PCR寄存器:信任链的“指纹锁”

PCR(Platform Configuration Register)是TPM内部的一组寄存器。它的特殊之处在于:只能扩展,不能直接写。

核心公式:

PCR新值 = SHA256( PCR旧值 || 新度量值 )

这意味着:你永远无法从PCR当前值反推出历史度量数据。这就是“单向哈希链”的威力。

TPM 2.0规范定义了至少24个PCR,每个都有特定用途。我整理了一张常用PCR分配表:

PCR索引 用途 度量内容
0 BIOS/固件代码 BIOS ROM、微码补丁
1 主机平台配置 主板型号、芯片组配置
2 Option ROM代码 显卡、网卡等扩展ROM
3 Option ROM配置 扩展卡的配置数据
4 MBR/VBR代码 主引导记录、卷引导记录
5 MBR/VBR配置 引导分区表、启动配置
6 状态转换 平台休眠/唤醒状态
7 安全策略 Secure Boot策略、DBX
8-15 操作系统使用 OS Loader、内核、驱动

我的经验:实际排查时,PCR 0和PCR 7是最常出问题的。有一次客户说系统启动总报度量失败,我一看PCR 0的值跟预期对不上——结果是BIOS升级后微码变了,但白名单没更新。这种坑,你排查时一定要先确认固件版本。

2.2 度量事件日志:PCR的“解释器”

PCR本身只存哈希值,不存度量过程。那你怎么知道某个PCR值是怎么算出来的?

答案就是:度量事件日志(Event Log)。

事件日志记录了每一次度量操作的详细信息。TPM 2.0的事件日志格式遵循TCG EFI平台规范,每个事件条目包含:

  • PCR索引:这次度量扩展到了哪个PCR
  • 事件类型:比如EV_EFI_BOOT_SERVICES_APPLICATION
  • 度量值:实际扩展的哈希值
  • 事件数据:被度量对象的原始信息(比如文件的GUID、路径)
  • 数字签名:可选,用于验证日志完整性

我习惯把事件日志比作“审计底稿”。PCR是最终结论,事件日志就是得出这个结论的每一步计算过程。没有日志,你根本没法排查度量问题。

注意:事件日志存储在内存中,系统重启就没了。如果你需要事后分析,必须在启动阶段就把日志抓出来保存。我曾经因为没及时保存日志,排查一个启动漏洞时只能靠猜——那感觉,别提多难受了。

下面是一个简化的事件日志条目示例:

PCR Index: 4
Event Type: EV_EFI_BOOT_SERVICES_APPLICATION
Digest: 0xA1B2C3D4E5F6...
Event Data:
  - Image GUID: 12345678-1234-1234-1234-123456789ABC
  - Image Path: \EFI\Microsoft\Boot\bootmgfw.efi
  - Image Size: 0x123456
  - Load Address: 0x7C00000

2.3 度量代理架构:谁来做度量?

PCR和事件日志是“数据”,那“谁”来执行度量操作?

答案是:度量代理(Measurement Agent)。

在UEFI固件中,度量代理通常是一个DXE驱动或SMM模块。它的工作流程是这样的:

  1. 拦截加载事件:当UEFI引导管理器要加载某个镜像时,度量代理先截获
  2. 计算哈希:对镜像内容做SHA256/SHA384
  3. 扩展PCR:把哈希值扩展到对应的PCR
  4. 记录日志:把这次度量事件写入Event Log
  5. 放行执行:允许镜像继续加载

度量代理的架构设计,直接决定了整个信任链的安全性。我画了一张架构图,帮你理解各组件的关系:

度量代理架构与信任链 度量代理 (Measurement Agent) UEFI引导管理器 度量引擎 TPM 2.0 事件日志 (Event Log) PCR寄存器 (0-23) 说明: 度量代理拦截UEFI引导管理器的加载请求,计算哈希后同时扩展TPM PCR和记录事件日志。 PCR保证度量结果的不可篡改性,事件日志提供可审计的详细记录。

2.4 度量代理的三种实现模式

在实际项目中,度量代理的实现方式主要有三种。我根据经验做了个对比:

模式 实现位置 优点 缺点
DXE驱动模式 UEFI DXE阶段 开发简单,调试方便 容易被绕过(SMM更安全)
SMM模式 系统管理模式 权限高,难以绕过 性能开销大,开发复杂
混合模式 DXE + SMM 兼顾性能和安全性 架构复杂,调试困难

我建议:如果你的产品对安全等级要求高(比如服务器、金融终端),优先考虑SMM模式。虽然开发周期会长一些,但安全收益是值得的。我之前做过一个项目,客户坚持用DXE模式,结果被攻击者用SMM漏洞绕过了度量——嗯,后来他们还是改成了混合模式。

2.5 度量代理的常见漏洞

度量代理本身也可能有漏洞。我总结了几类常见问题:

  • TOCTOU漏洞:度量时和加载时的镜像内容不一致。攻击者可以在度量完成后、加载前篡改镜像
  • 日志伪造:事件日志没有签名保护,攻击者可以篡改日志内容
  • PCR扩展遗漏:某些加载事件没有被度量代理拦截,导致PCR值不完整
  • 哈希算法降级:攻击者诱导度量代理使用弱哈希算法(比如SHA1)

避坑指南:我曾经排查过一个案例,度量代理在计算哈希时只读了镜像的前4KB。攻击者把恶意代码藏在镜像后面,度量结果看起来是合法的,但实际执行的是恶意代码。所以,度量一定要覆盖整个镜像,别偷懒。

2.6 实战:如何验证度量代理是否正常工作

排查度量问题时,我一般按这个步骤来:

  1. 抓取事件日志:在启动阶段用工具(比如Linux的tpm2_eventlog)导出日志
  2. 解析日志条目:检查每个事件的PCR索引、度量值是否合理
  3. 重放度量过程:用同样的镜像和算法重新计算哈希,对比PCR值
  4. 验证日志完整性:如果日志有签名,验证签名是否有效
  5. 检查覆盖范围:确认所有关键组件(Bootloader、OS Loader、内核)都被度量

举个例子,如果你发现PCR 4的值跟预期不符,可以这样排查:

# 导出事件日志
tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements > eventlog.txt

# 查找PCR 4相关事件
grep "PCR: 4" eventlog.txt

# 重算哈希
sha256sum /EFI/Microsoft/Boot/bootmgfw.efi

# 对比PCR值
tpm2_pcrread sha256:4

如果重算的哈希跟日志里记录的不一致,那问题就出在度量代理本身——它可能没读到正确的镜像内容。

度量架构设计,说白了就是三个问题:度量什么?怎么度量?谁来度量?PCR解决了“度量什么”,事件日志解决了“怎么度量”,度量代理解决了“谁来度量”。这三者缺一不可,任何一个环节出问题,整个信任链就断了。