4. 度量启动流程:BIOS/UEFI阶段度量、Option ROM度量、OS Loader度量、内核度量
启动度量这件事,说白了就是给系统的每个启动环节拍一张「身份证照片」。从你按下电源键到操作系统跑起来,中间经过的每一段代码都要被记录、被验证。我这些年调试过不少启动失败的板子,十有八九都是某个环节的度量链断了。
咱们这一章就顺着启动流程,把四个关键阶段的度量点挨个捋一遍。
4.1 BIOS/UEFI阶段度量:信任的起点
系统上电后,CPU首先执行的是固化在ROM里的复位向量代码。这段代码是硬件可信根(CRTM),它本身是物理不可篡改的。CRTM会去度量BIOS或UEFI固件的主体部分。
我个人习惯把BIOS/UEFI阶段的度量分成两步:
- CRTM度量BIOS/UEFI主固件:计算主固件代码的哈希值,与存储在TPM PCR[0]中的预期值比对。
- BIOS/UEFI度量自身模块:UEFI启动管理器会逐个度量DXE驱动、ACPI表、SMBIOS表等模块。
关键点:PCR[0]是信任链的锚点。如果CRTM本身被篡改,整个信任链就崩塌了。所以硬件设计上,CRTM必须位于只读存储器中,且物理上受保护。
我在项目中遇到过一种情况:某款国产主板的UEFI固件升级后,PCR[0]的预期值没同步更新,导致每次启动都报度量失败。嗯,这种问题排查起来特别头疼,因为硬件本身没坏,但信任链就是接不上。
4.2 Option ROM度量:容易被忽视的环节
Option ROM是什么?说白了就是插在PCIe槽上的设备自带的固件。显卡、网卡、RAID卡都有。这些固件在系统初始化阶段会被加载执行,但它们的安全性往往被忽视。
你想想看,如果一张网卡的Option ROM被植入了后门,攻击者就能在操作系统启动前拿到网络控制权。这可不是危言耸听,我在做安全审计时就发现过某品牌网卡的Option ROM存在未签名代码。
Option ROM的度量流程是这样的:
- UEFI的PCI总线驱动枚举设备时,会定位Option ROM。
- 驱动调用安全策略模块,计算Option ROM的哈希值。
- 哈希值被扩展到PCR[2]中(部分平台使用PCR[4])。
- 如果Option ROM有数字签名,还会验证签名的有效性。
| 度量对象 | 目标PCR | 度量时机 |
|---|---|---|
| BIOS/UEFI主固件 | PCR[0] | CRTM执行后立即度量 |
| UEFI驱动/应用 | PCR[1] | DXE阶段逐个度量 |
| Option ROM | PCR[2] | PCI枚举阶段 |
| 启动配置数据 | PCR[3] | BDS阶段 |
避坑指南:我曾经遇到过一块RAID卡,它的Option ROM在UEFI模式下工作正常,但切换到Legacy模式后度量就跳过了。后来发现是固件配置表里漏写了Legacy模式的度量入口。所以,测试时一定要覆盖所有启动模式。
4.3 OS Loader度量:信任链的接力棒
UEFI启动管理器在完成自身度量后,会去加载OS Loader(比如Windows的bootmgfw.efi或Linux的shim.efi)。这个环节是信任链从固件层向操作系统层传递的关键节点。
度量过程大致如下:
- UEFI启动管理器读取启动项配置,找到OS Loader的文件路径。
- 调用安全策略模块,计算OS Loader文件的哈希值。
- 哈希值扩展到PCR[4](部分平台使用PCR[5])。
- 如果启用了Secure Boot,还会验证OS Loader的数字签名。
这里有个细节:OS Loader本身也会度量它要加载的内核和驱动。比如Linux的shim会去度量GRUB2,GRUB2再去度量内核。这就是所谓的「嵌套度量」。
个人经验:我在调试Linux安全启动时,发现shim度量GRUB2时会把GRUB2的配置文件也纳入哈希计算。这意味着你改了grub.cfg里的任何参数,度量值都会变。很多运维同学不知道这个,升级内核后启动失败,其实就是配置文件变了导致度量不匹配。
4.4 内核度量:最后的防线
OS Loader把控制权交给内核后,内核会继续度量自身的核心模块。这一步通常由内核的IMA(Integrity Measurement Architecture)机制完成。
IMA会在内核启动早期初始化,然后开始度量:
- 内核代码段和数据段
- 内核模块(.ko文件)
- 关键系统文件(如/etc/shadow、/etc/ssh/sshd_config)
- 可执行文件和共享库
IMA的度量结果会扩展到TPM的PCR[10]中。为什么用PCR[10]?因为前面的PCR[0]-PCR[7]已经被固件和OS Loader占用了,PCR[8]-PCR[9]留给特定用途,PCR[10]正好给IMA用。
# 查看IMA度量日志(Linux)
cat /sys/kernel/security/ima/ascii_runtime_measurements
# 输出示例:
# 10 1234567890abcdef ima-ng sha256:abcdef1234567890 /usr/bin/ssh
# 10 1234567891abcdef ima-ng sha256:fedcba0987654321 /etc/ssh/sshd_config
核心要点:内核度量是信任链的最后一道防线。如果内核本身被篡改,后续所有度量都失去意义。所以内核度量必须在内核启动的最早期完成,越早越好。
我见过一个案例:某云厂商的服务器被入侵,攻击者替换了内核模块。因为IMA度量了所有模块的哈希值,运维团队通过比对PCR[10]的扩展记录,很快就定位到了被篡改的模块。如果没有IMA,这种隐蔽的篡改可能要过很久才能被发现。
4.5 完整的度量信任链
把上面四个阶段串起来,就是一条完整的度量信任链:
CRTM → BIOS/UEFI → Option ROM → OS Loader → 内核
每个环节度量下一个环节,并把度量值扩展到对应的PCR中。任何环节的篡改都会导致PCR值与预期不符,远程证明时就能发现异常。
下面这张图展示了完整的度量流程和PCR分配:
从这张图可以看得很清楚:每个启动环节的度量结果都沉淀到特定的PCR中。远程证明时,验证方只需要比对PCR的最终值,就能判断整个启动过程是否可信。
嗯,度量启动流程就讲到这里。记住一句话:信任链的强度取决于最薄弱的那个环节。Option ROM和内核度量往往是容易被忽略的薄弱点,我在实际项目中没少在这两个地方踩坑。