跳转至内容

可信平台模块 (TPM)

来自 ArchWiki

本文章或章节需要扩充。

原因: 需要澄清 TPM 1.2 和 2.0 之间的使用差异、针对“邪恶女仆攻击”的防御以及可信启动。PCR 寄存器密封和与 LUKS 结合使用。(请在 Talk:Trusted Platform Module 中讨论)

可信平台模块 (TPM) 是一项国际标准,用于安全加密处理器,它是一个专用的微处理器,通过将加密密钥集成到设备中来保护硬件。

实际上,TPM 可用于各种不同的安全应用,例如 安全启动、密钥存储和 随机数生成

TPM 自然只能在支持 TPM 硬件的设备上运行。如果您的硬件支持 TPM 但未显示出来,可能需要在 BIOS 设置中启用它。

注意 TPM 有两个非常不同的规格:2.0 和 1.2,它们使用不同的软件堆栈。本文仅介绍 TPM 2.0,有关较旧的 TPM 1.2,请参阅 /1.2

检查 TPM 支持

大多数现代计算机都支持 TPM 2.0,因为它自 2016 年以来已被 要求用于 Windows 10 认证。要检查您系统上的支持情况,请使用以下任何方法:

  • 检查日志,例如,通过以 root 身份运行 journalctl -k --grep=tpm
  • 读取 /sys/class/tpm/tpm0/device/description[1]/sys/class/tpm/tpm0/device/firmware_node/description/sys/class/tpm/tpm0/tpm_version_major 的值。
$ cat /sys/class/tpm/tpm0/device/description
TPM 2.0 Device
  • 使用 systemd-analyze(1) 检查 TPM 2.0 和所需的软件依赖项。
    $ systemd-analyze has-tpm2

TPM 2.0 允许直接通过 /dev/tpm0 (一次一个客户端) 访问,通过 /dev/tpmrm0 进行内核管理访问,或者通过 tpm2-abrmd 资源管理器守护进程进行管理访问。 根据 systemd 项目成员的说法,已不再推荐使用 tpm2-abrmd。用户空间工具方面有两种选择,Intel 的 tpm2-tools 和 IBM 的 ibm-tssAUR

TPM 2.0 需要 UEFI 启动;BIOS 或传统启动系统只能使用 TPM 1.2。

一些 TPM 芯片可以通过固件升级在 2.0 和 1.2 之间切换 (此操作只能进行有限次数)。

用法

可以在 tpm2-software 社区中找到许多信息资源,以了解如何在日常应用程序中配置和使用 TPM 2.0 服务。

LUKS 加密

可以使用安全存储在 TPM 中的密钥来加密卷。这种方法可确保您的驱动器在 TPM 不存在且特定条件(例如固件的完整性或 安全启动状态)不满足时保持锁定状态(请参阅 #访问 PCR 寄存器)。

此机制可用于在启动过程中自动解密根卷,类似于 Windows 上的 BitLocker 或 macOS 上的 FileVault。虽然这为将驱动器从带 TPM 的计算机上移除提供了强大的保护,但如果整个 PC 被盗,数据保护将仅依赖于基本措施,如用户密码和系统设置。为了缓解这种情况,您可以:

  • 考虑使用其他机制加密用户数据,例如单个主目录,例如 fscryptsystemd-homed
  • 使用 TPM PIN 来利用 TPM 的安全属性,同时避免完全无人值守解锁。
警告 请注意,此方法会使您更容易受到 冷启动攻击 的影响。

systemd-cryptenrollClevis 允许使用存储在 TPM 中的密钥来锁定 LUKS 卷。此外,systemd-cryptenroll 支持将加密绑定到签名策略,而不是静态 PCR 值(请参阅 systemd-cryptenroll(1))。

SSH

对于 TPM 密封的 SSH 密钥,有两种选择:

  • ssh-tpm-agent — 兼容 ssh-agent 的代理,使用 TPM 后备密钥。
https://github.com/Foxboron/ssh-tpm-agent || ssh-tpm-agent
请参阅 Store ssh keys inside the TPM: ssh-tpm-agent
  • tpm2-pkcs11 — 用于可信平台模块 2.0 硬件的 PKCS#11 接口。
https://github.com/tpm2-software/tpm2-pkcs11 || tpm2-pkcs11
请参阅 SSH configurationUsing a TPM for SSH authentication (2020-01)。

systemd-creds

systemd-creds 使用 TPM 安全地存储和检索 systemd 单元使用的凭据。

GnuPG

本文章或章节需要扩充。

原因: 添加有关探测 TPM 以了解其支持哪些密钥的说明。(请在 Talk:Trusted Platform Module 中讨论)

GnuPG 从 2.3 版本开始支持将兼容的密钥移至 TPM。有关说明,请参阅 Using a TPM with GnuPG 2.3

OpenSSL

有实现将密钥存储在 TPM 中的 OpenSSL provider 和 OpenSSL 引擎。

  • tpm2-openssl — TPM2 集成的 OpenSSL Provider。
https://github.com/tpm2-software/tpm2-openssl || tpm2-openssl
  • tpm2-tss-engine — TPM2 设备的 OpenSSL 引擎。
https://github.com/tpm2-software/tpm2-tss-engine || tpm2-tss-engine
请参阅 Using the TPM - It's Not Rocket Science (Anymore) - Johannes Holland & Peter Huewe (2020-11, Youtube)

TPM 2.0 使用的其他优秀示例

访问 PCR 寄存器

本文章或章节需要扩充。

原因: 仅列出有用的 PCR 并给出实际使用示例,而不是列出所有现有的 PCR,可能更明智。(请在 Talk:Trusted Platform Module#PCR register table 中讨论)

平台配置寄存器 (PCR) 允许通过哈希值将密钥的加密绑定到特定的软件版本和系统状态,这样,只有在使用特定的受信任软件和/或配置时,才能访问(可能“解封”)已注册的密钥。

PCR 用于平台硬件和软件在启动之间的完整性验证(例如,防止 “邪恶女仆攻击”)。

TCG PC Client Specific Platform Firmware Profile Specification》定义了使用的寄存器,而《The Linux TPM PCR Registry》则分配了使用它们的 Linux 系统组件。

寄存器是:

PCR 描述 由...扩展
PCR0 核心系统固件可执行代码(又称固件)。如果升级 UEFI,它可能会改变。 固件
PCR1 核心系统固件数据(又称 UEFI 设置;例如,已配置的启动顺序) 固件
PCR2 扩展或可插入的可执行代码(又称 OpROMs 固件
PCR3 扩展或可插入的固件数据。在启动设备选择 UEFI 启动阶段设置。 固件
PCR4 启动管理器代码和启动尝试。测量启动管理器和固件尝试启动的设备。 固件
PCR5 启动管理器配置和数据。可以测量引导加载程序的配置;包括 GPT 分区表。 固件
PCR6 从 S4 和 S5 电源状态事件恢复 固件
PCR7 安全启动状态。包含 PK/KEK/db 的全部内容,以及用于验证每个启动应用程序的特定证书[2] 固件,shim (添加 MokList, MokListX 和 MokSBState)
PCR81 内核命令行哈希 GRUB
PCR91 initramfs 和 EFI 加载选项的哈希 Linux (测量 initramfs 和 EFI 加载选项,本质上是内核命令行选项)
PCR101 预留给未来使用
PCR111 统一内核镜像的哈希 systemd-stub(7)
PCR121 已覆盖的内核命令行、凭据 systemd-stub(7)
PCR131 系统扩展 systemd-stub(7)
PCR141 shim 的 MokList, MokListX 和 MokSBState。[3] shim
PCR151 LUKS 卷密钥的哈希 systemd-cryptsetup
PCR161 调试。可以随时使用和重置。可能未包含在官方固件版本中。
PCR23 应用程序支持。操作系统可以设置和重置此 PCR。
  1. 由操作系统定义的用例,可能因不同的 Linux 发行版和 Windows 设备而异。

在 Windows 上,BitLocker 使用 PCR8-11(传统)或 PCR11-14(UEFI)来实现其自身目的。来自 tianocore 的文档[4]

tpm2-totp 可帮助用户和专用可信设备进行此检查。

当前 PCR 值可以使用 systemd-analyze(1) 列出。

$ systemd-analyze pcrs

或者,也可以使用 tpm2_pcrread(1) (来自 tpm2-tools)。

# tpm2_pcrread

PCR 策略

使用 TPM2,可以将密钥(例如 LUKS 根解密密钥)绑定到签名策略,而不是原始 PCR 值。这些策略通过允许 PCR 值变化来增加灵活性,前提是这些值有一个有效的 PCR 签名,该签名与已注册密钥的公钥匹配。例如,与其简单地将加密密钥绑定到 PCR7 值(仅检查安全启动未被禁用或篡改),不如将其绑定到 PCR 策略,该策略验证启动一个已知的 统一内核镜像 (UKI),并在启动过程中测量其所有组件。请参阅 systemd-cryptenroll(1) § TPM2_PCRs_and_policies

下面的示例允许在启动过程中(即在 initramfs 阶段)解密根分区,而加密密钥在系统完全启动后不可访问。有关不同启动阶段的多个信任策略的示例,请参阅 ukify(1)

首先生成必要的签名密钥

# ukify genkey \
        --pcr-private-key=/etc/systemd/tpm2-pcr-private-key.pem \
        --pcr-public-key=/etc/systemd/tpm2-pcr-public-key.pem
注意 /etc/systemd/tpm2-pcr-public-key.pem 是默认路径,如果存在,systemd-cryptenroll 会自动识别该文件。

创建 /etc/kernel/uki.conf 或从 /usr/lib/kernel/uki.conf 复制模板。虽然 PCR 策略可以在没有安全启动的情况下使用,但最好也签名您的 UKI,因此请根据需要使用您的密钥更新以下内容:

/etc/kernel/uki.conf/
[UKI]
SecureBootSigningTool=systemd-sbsign
SignKernel=true
SecureBootPrivateKey=/etc/kernel/secure-boot-private-key.pem
SecureBootCertificate=/etc/kernel/secure-boot-certificate.pem
Splash=/usr/share/systemd/bootctl/splash-arch.bmp

[PCRSignature:initrd]
Phases=enter-initrd
PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key.pem
PCRPublicKey=/etc/systemd/tpm2-pcr-public-key.pem

要生成 UKI,请使用一个默认读取 /etc/kernel/uki.conf 的工具,例如 kernel-installmkinitcpio

最后,将 TPM2 策略注册到您的 LUKS 卷中。

# systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto /dev/disk/by-label/root

使用 # ukify inspect /path/to/uki 检查 UKI,确保它包含 .pcrsig 部分。

还要检查 LUKs 卷是否已注册公钥。

# cryptsetup luksDump /dev/disk/by-label/root | grep pubkey 
        tpm2-pubkey:
                    .....
        tpm2-pubkey-pcrs: 11
注意 启动此 UKI 需要 mkinitcpio 的 systemd hook。

故障排除

TPM2 LUKS2 解锁仍要求输入密码

如果您按照上述 说明 使用 TPM2 硬件模块中注册的密钥自动解锁 luks2 设备,但仍在 initramfs 启动阶段收到输入密码的提示。您可能需要 提前加载 负责处理您的特定 TPM2 模块的内核模块(您可以使用 systemd-cryptenroll --tpm2-device=list 获取其名称)。

尝试创建 NULL primary 时发生 TPM 错误 (714)

从 Linux Kernel 6.10 开始,CONFIG_TCG_TPM2_HMAC 默认启用,现在 TPM 必须支持 AES-128-CFB 进行会话加密。不支持此模式的 TPM,例如较旧的 Intel PTT,将无法初始化驱动程序,从而导致 A TPM error (714) occurred attempting to create NULL primary。更换硬件是唯一的完整解决方案。 systemd-cryptenroll 也需要 AES-128-CFB 支持,因此禁用内核选项是不够的,它会失败并产生此错误:TPM device not usable as it does not support the required functionality (AES-128-CFB missing?).

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.