Linux 可信启动深度解析:从UEFI到操作系统的信任链

发布于:2025-09-09 ⋅ 阅读:(30) ⋅ 点赞:(0)

引言

在探讨了解学习虚拟化的安全方案(如HyperEnclave)时,我们经常会遇到动态信任根(DRTM)的概念。但DRTM的有效性,又依赖于一个稳固的静态信任根(Static Root of Trust for Measurement, SRTM)。这条SRTM信任链,构成了整个平台可信度的基石。

本文档的目的,就是完整地、系统性地梳理这条信任链。我们将从PC上电的瞬间开始,一路追踪信任的“接力棒”是如何从UEFI固件,传递给GRUB 2引导加载程序,并最终由Linux内核接管,将其延伸至每一个运行中的应用程序。


一、 可信根基:TPM与核心概念

在深入流程之前,必须先对齐几个贯穿始终的核心概念。

1.1 什么是“度量” (Measurement)?

在可信计算的语境里,“度量”就是一个动作:对一段数据(比如一个文件或一段代码)计算其密码学哈希值(如SHA-256)

这个哈希值就像是这段数据的“数字指纹”,任何微小的改动都会导致指纹发生天翻地覆的变化。这个动作本身不提供安全,它只是提供了一种可验证的、唯一的身份标识

1.2 信任链与TPM PCR

“信任链”(Chain of Trust)的思想很简单:信任是需要传递的。就像接力赛,第一棒运动员(信任的根源)必须是可信的,然后他把接力棒(控制权)交给第二棒时,必须先保证第二棒也是可信的。

TPM(可信平台模块)就是这个过程中的“公证员”和“记事本”。它内部有一组特殊的寄存器,叫平台配置寄存器(Platform Configuration Registers, PCRs)

PCR有一个独一无二的特性:你不能直接写入一个值,你只能对它执行Extend(扩展)操作。

Extend操作的本质是:PCR_new_value = HASH(PCR_old_value || new_data_hash)

这个特性使得PCR成为了一个完美的、防篡改的启动日志。任何对启动流程的偏离,都会在这本“只能追加、不能修改”的日志上留下清晰的痕迹。


二、 阶段一:固件的可信启动 (UEFI)

信任链的源头,始于PC上电后运行的第一行代码——UEFI固件。它的启动过程并非一个单一步骤,而是遵循业界标准(如PI-Spec)的一个分阶段的初始化序列。

2.1 引导的起点:从SEC到DXE的初始化

UEFI的启动可以大致分为几个关键阶段,每一步都为下一步构建基础。

DRAM可用
CPU Cache as RAM
度量PEI代码
度量DXE核心
PEI Phase (Pre-EFI Initialization)
DXE Phase (Driver Execution Environment)
BDS Phase (Boot Device Selection)
OS引导加载程序 (GRUB 2)
SEC Phase (Security)
上电

图1: UEFI 启动阶段总览

  1. SEC (Security) Phase - 安全阶段:
  • 这是CPU在加电后执行的第一段代码,通常由处理器的微码和固件中的一小段汇编代码组成,是平台的静态信任根度量(Static Root of Trust for Measurement, SRTM)的起点,也被称为核心信任根度量(Core Root of Trust for Measurement, CRTM)

  • 它的核心任务非常单纯:建立一个临时的运行环境(通常是使用CPU的缓存作为临时内存),并找到、验证、启动下一阶段(PEI)。作为信任链的第一环,它会度量PEI阶段的代码,并将结果ExtendPCR[0] 中。

  1. PEI (Pre-EFI Initialization) Phase - EFI前期初始化阶段:
  • PEI的主要职责是初始化主内存(DRAM)。一旦DRAM可用,后续的复杂任务才有了运行空间。

  • 它会进行最核心的平台硬件发现(如CPU、芯片组),并将这些信息组织成一个“交接清单”(Hand-Off Block List, HOBs),传递给下一阶段。在交接前,它会度量DXE阶段的核心代码,并继续ExtendPCR[0]

  1. DXE (Driver Execution Environment) Phase - 驱动执行环境阶段:
  • 这是UEFI的“主舞台”。DXE阶段的核心是一个分发器(Dispatcher),它会根据依赖关系,循环加载和执行一系列的DXE驱动,完成对平台上几乎所有硬件的初始化。

  • 在这个阶段,各种UEFI服务和协议被创建和发布,比如文件系统服务、块设备I/O服务,以及我们可信启动所依赖的 TPM服务协议(EFI_TCG2_PROTOCOL)。所有被加载的DXE驱动,也都会被度量并继续ExtendPCR[0]。到DXE阶段结束时,系统已经是一个功能完备的“小型操作系统”。

2.2 引导设备选择 (BDS):UEFI如何找到GRUB

DXE阶段完成后,控制权交给BDS(Boot Device Selection)阶段。这本质上就是我们熟知的UEFI启动管理器。在执行引导加载程序之前,BDS自身也会被度量到PCR[0]中,至此,PCR[0]完整地记录了整个固件的启动链条。

  1. 读取NVRAM启动变量:
  • BDS会读取主板上非易失性存储器(NVRAM)中存储的启动变量。最重要的变量是 BootOrder,它定义了启动项的尝试顺序,如 [Boot0001, Boot0002, Boot0000]

  • 每一个启动项(如Boot0001)都是一个详细的记录,它包含了:

  • 设备路径: 指向一个具体的物理设备(如某一块硬盘的某个分区)。

  • 文件路径: 指向该设备上要执行的EFI应用程序的路径。

  • 描述: 一个用户可见的字符串,如 “ubuntu” 或 “Windows Boot Manager”。

  1. 定位GRUB:
  • BDS会按照BootOrder的顺序,尝试加载第一个启动项。例如,对于Boot0001 (“ubuntu”),它会根据设备路径找到ESP分区(EFI System Partition,一个标准的FAT32分区),然后在这个分区上根据文件路径找到GRUB的核心镜像,例如 \EFI\ubuntu\grubx64.efi

  • 备用路径(Fallback Path): 如果所有BootOrder中的启动项都失败了,或者BootOrder为空,BDS会尝试一个标准的备用路径:\EFI\BOOT\BOOTX64.EFI

2.3 Secure Boot与度量:信任的第一次传递

在BDS最终决定要执行某个EFI应用程序(如grubx64.efi)的那一刻,Secure Boot和TPM度量机制会介入,完成信任的第一次传递。

  1. Secure Boot验证:
  • 在执行grubx64.efi之前,UEFI会用其内置的**签名数据库(db)**中的公钥,去验证这个文件的数字签名。

  • 同时,它会检查这个文件的签名哈希是否位于**禁止签名数据库(dbx)**的黑名单中。

  • 只有签名有效且不在黑名单中,程序才被允许执行。

  1. 第一环度量:
  • 在验证签名的同时,UEFI固件也扮演了第一个度量者的角色。它会度量启动过程中加载的关键组件,并将哈希值扩展到PCR中:

  • PCR[0]: 度量UEFI固件自身的核心代码、启动设置等。

  • PCR[2]: 度量加载的第三方UEFI驱动或扩展ROM。

  • PCR[4]: 度量被选中的引导加载程序(如grubx64.efi)的完整镜像。

  • PCR[7]: 度量Secure Boot的策略和密钥状态。

  1. 交接控制权:
  • 至此,在将控制权交给GRUB之前,UEFI已经完成了两件大事:通过签名验证了GRUB的身份合法性,并通过度量记录下了GRUB的数字指纹。然后,它才会真正跳转到grubx64.efi的入口点开始执行。
2.4 SEC阶段如何与TPM交互?

一个关键问题是:在SEC阶段,主内存(DRAM)都尚未初始化,系统环境极其简陋,它怎么可能有TPM的“驱动”来操作寄存器呢?

答案是:它没有现代意义上的“驱动”,它拥有的是更底层的、固化在自身代码中的“直接操作能力”。

  • CRTM的特殊身份: SEC阶段执行的代码,即核心信任根度量(CRTM),不是一个通用的程序。它是由芯片或主板制造商编写的、高度特权化、平台专属的一小段代码。它被认为是隐式可信的,是信任的绝对源头。

  • 硬编码的通信能力: CRTM的代码直接包含了与TPM芯片进行最低级别通信所需要的所有指令。它知道要通过哪个总线(如LPC或SPI总线)、向哪个具体的I/O端口或内存映射地址(MMIO)发送什么样字节序列,来命令TPM执行“扩展PCR[0]”这个动作。这个最原始的“TPM驱动”被**硬编码(Hard-coded)**在了CRTM内部。

  • 设计的安全性: 正因为它不依赖任何外部加载的驱动,所以它的行为是确定的、不受外部环境影响的,这恰恰是作为信任根所必需的。


三、 阶段二:引导加载程序的接力 (GRUB 2)

现在,信任链的接力棒传递到了GRUB 2手中。

3.1 GRUB自我唤醒并延续信任链

GRUB 2的核心镜像(core.img)已经在内存中运行,但它非常小,功能有限。它需要找到自己的“大部队”——配置文件和各种模块。

  1. GRUB的自我定位与配置加载:
  • GRUB现在是“醒着”的。它会启用自己内置的、微型的文件系统驱动(例如fat.mod可能已经嵌入core.img中),更重要的是,它会加载更强大的文件系统驱动(如ext4.mod)。

  • 它根据安装时配置的“前缀”(prefix)信息,去另一个分区(通常是Linux的/boot分区,格式为ext4等)下的/grub/目录中,寻找并读取它的“施工图纸”—— grub.cfg 文件。这个文件包含了所有启动菜单项和要执行的命令。

  1. 解析配置并度量:
  • GRUB开始逐行解析grub.cfg。当它遇到一个被选择的menuentry(启动项)时,它会严格按照里面的命令执行。一个用于可信启动的配置片段可能如下:
menuentry 'Arch Linux (Trusted Boot)' {

# 1. 动态加载TPM模块,让GRUB具备与TPM交互的能力

insmod tpm

# 2. 加载Linux内核。加载tpm.mod后,

# linux命令会自动触发度量行为

linux /boot/vmlinuz-linux root=UUID=... ro quiet

# 3. 加载initramfs。同样,会被度量

initrd /boot/initramfs-linux.img

}
  • 度量grub.cfg本身: GRUB会度量它解析的这些命令文本,并将结果扩展到PCR中(如PCR[8]),以确保配置本身未被篡改。

  • 度量内核: 当执行linux命令时,GRUB首先将/boot/vmlinuz-linux文件完整读入内存,对其内容进行哈希计算(度量),然后通过tpm.mod将哈希值Extend到指定的PCR寄存器中(通常也是PCR[8]PCR[10])。

  • 度量initramfs: 同样,initrd命令也会触发对/boot/initramfs-linux.img的度量,并将哈希值扩展到PCR中。

硬件 (Hardware)
GRUB 2 (内存中)
硬盘 (Disk)
1. 读取文件至内存
2. 对内存中的数据进行哈希
3. 准备哈希值
4. 请求扩展PCR
TPM 芯片
GRUB 核心
哈希计算引擎
TPM 模块
/boot/vmlinuz (内核文件)

图2:GRUB 2 度量内核的详细流程

3.2 控制权的第二次交接 (GRUB -> Kernel)

完成所有度量后,GRUB将CPU的控制权正式交给内核的入口点。信任链的接力棒,至此成功传递给了操作系统。


四、 阶段三:内核的全面守护 (IMA)

当内核开始运行时,信任链并没有结束,而是进入了一个更精细、更持续的阶段。Linux内核通过**完整性度量架构(Integrity Measurement Architecture, IMA)**来接管度量的职责。

4.1 IMA简介:将信任扩展到整个文件系统

IMA的目标,是将信任链从启动阶段的几个关键文件,延伸到系统运行过程中访问的每一个文件(包括应用程序、配置文件、库文件等)。

4.2 IMA-Measure:运行时度量

这是IMA最基础的功能。它的工作流程如下:

用户 应用程序 内核 IMA TPM 执行 /usr/bin/cat 系统调用: execve("/usr/bin/cat") (Hook) 执行前触发IMA 读取 /usr/bin/cat 文件内容 计算文件哈希值 将哈希值 Extend 到 PCR[10] 扩展成功 度量完成, 允许执行 继续执行程序 用户 应用程序 内核 IMA TPM

图2: IMA 度量流程

  • 钩子 (Hook): IMA在内核的关键路径(如文件打开、执行execve、内存映射mmap)上设置了钩子。

  • 度量: 每当有文件要被访问或执行时,钩子被触发,IMA子系统会先计算该文件的哈希值。

  • 扩展: 计算出的哈希值被扩展到 PCR[10](IMA专用的PCR寄存器)。

  • 记录日志: 同时,IMA会将这次度量的详细信息(文件名、哈希值)记录在内存中的一个日志里,该日志可以通过/sys/kernel/security/ima/ascii_runtime_measurements查看。

通过这个机制,任何在系统运行时被加载的文件,都会留下“指纹”,确保了系统的动态可审计性。

4.3 IMA-Appraise:运行时强制访问控制

IMA-Appraise是IMA的进阶功能。它不仅度量,还会进行强制性的验证

  • 系统会预先为所有可信文件计算哈希,并将这些哈希值作为扩展属性(security.ima)存储在文件元数据中,并进行签名。

  • IMA-Appraise启用时,每次文件被度量后,IMA会:

  1. 检查文件是否有security.ima属性。

  2. 验证属性中的哈希签名是否有效。

  3. 比较实时计算的哈希值与属性中存储的“黄金哈希值”是否一致。

  • 只有三者全部通过,才允许访问。否则,直接拒绝! 这将可信启动从一个“只记录、不阻止”的模型,变成了一个主动防御的强制访问控制系统。

五、 总结:一条完整的静态信任根 (SRTM) 链

综上所述,一条完整的Linux静态信任根链条,是一个分工明确、层层递进的接力过程:

| 阶段 | 负责组件 | 核心动作 | 主要度量目标 | 主要影响的PCR |

| :— | :— | :— | :— | :— |

| 阶段一 | UEFI 固件 | Secure Boot验证、度量 | 固件代码、扩展ROM、引导加载程序 | PCR[0-7] |

| 阶段二 | GRUB 2 | 解析配置、度量 | grub.cfg命令、内核、initramfs | PCR[8-9] |

| 阶段三 | Linux 内核 (IMA) | Hook关键路径、度量 | 应用程序、库、配置文件等 | PCR[10] |

从硬件上电到每一个应用被执行,每一步的控制权交接都伴随着“验证”与“度量”,确保了信任从一个绝对可信的硬件根(TPM),一路传递到运行中的整个操作系统,最终形成了一个坚实、可审计、可验证的安全基础。


网站公告

今日签到

点亮在社区的每一天
去签到