可信平台模块 (Trusted Platform Module,TPM) 是一种用于安全加密处理器的国际标准,作为一种集成的微处理器,它可以通过将加密密钥集成到设备中来保护硬件安全。
TPM 可以被用于在各种安全应用场景,例如安全启动,密钥存储与随机数生成。
TPM 仅在具有 TPM 硬件支持的设备上可用。如果设备具有 TPM 支持但并不可用,可能需要在 BIOS 设置中启用。
查看 TPM 版本
绝大多数现代的计算机都支持 TPM 2.0,因为自 2016 年后,这是 Windows 10 的强制性认证的一部分[1]。要检查设备是否支持,请使用如下方法:
- 检查日志,例如以 root 身份运行
journalctl -k --grep=tpm
。 - 读取
/sys/class/tpm/tpm0/device/description
[2]或/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 或传统引导(Legacy boot)下的系统只能使用 TPM 1.2。
某些 TPM 芯片可以通过硬件升级在 2.0 和 1.2 间切换(往往只能执行有限次)。
用法
tpm2-software 社区提供了许多学习如何配置 TPM 2.0 并投入到实际生活使用的相关信息。
LUKS 数据加密
可以使用安全保存在 TPM 中的密钥来加密卷。这可以确保仅在 TPM 生效,同时满足一些特定条件的前提下,硬盘才会解密,例如硬件完整性或安全启动的状态(参见 #访问 PCR 寄存器)。
此机制可以用于在引导时自动解密根文件系统,类似于 Windows 上的 BitLocker 和 macOS 上的 FileVault。当硬盘从原设备上被拆下时,这能有效地保护其中的数据,但当整个设备都被盗,数据保护仍然只能依赖于最原始的方法,如密码和系统设置。要缓解这个问题,可以尝试:
- 使用不同的机制加密用户数据(用户的 home 目录等),例如 fscrypt 或 systemd-homed。
- 使用 TPM PIN 以避免无人监管的自动解锁,这是一个 TPM 安全属性。
systemd-cryptenroll 和 Clevis 可以使用存储在 TPM 中的密钥加密 LUKS 卷。此外,systemd-cryptenroll 可以将加密绑定到签名策略,而不是静态 PCR 值上(参见 systemd-cryptenroll(1))。
SSH
要使用 TPM 保护 SSH 密钥,有以下两种方式:
- ssh-tpm-agent — 使用 TPM 支持密钥的,与 ssh-agent 兼容的代理服务。
- https://github.com/Foxboron/ssh-tpm-agent || ssh-tpm-agent包
- 参见 Store ssh keys inside the TPM: ssh-tpm-agent.
- tpm2-pkcs11 — 适用于 TPM 2.0 硬件的 PKCS#11 接口。
- https://github.com/tpm2-software/tpm2-pkcs11 || tpm2-pkcs11包
- 参见 SSH configuration 与 Using a TPM for SSH authentication (2020-01)。
GnuPG
自从 2.3 版本后,GnuPG 就支持将兼容的密钥迁移到 TPM 中。参见 Using a TPM with GnuPG 2.3 以获得方法。
其他 TPM 2.0 使用例
- Configuring Secure Boot + TPM 2
- Using the TPM - It's Not Rocket Science (Anymore) - Johannes Holland & Peter Huewe (2020-11, Youtube): examples for OpenSSL with tpm2-tss-engine包
访问 PCR 寄存器
平台配置寄存器(Platform Configuration Registers,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 内容,以及用于确认每个引导程序的特定证书。[3]
使用 shim 时,shim 会将自身的 MokList、 MokListX、和 MokSBState 添加到其后。 |
固件,shim(添加 MokList,MokListX,和 MokSBState) |
PCR81 | 内核参数哈希值 | GRUB, systemd-boot |
PCR91 | initrd 和 EFI Load Options 的哈希值 | Linux(检测 initrd 和 EFI Load Options,本质上是内核参数选项) |
PCR101 | 保留以供未来使用 | |
PCR111 | 统一内核映像哈希值 | systemd-stub(7) |
PCR121 | 覆盖内核参数,证书 | systemd-stub(7) |
PCR131 | 系统拓展 | systemd-stub(7) |
PCR141 | shim 的 MokList,MokListX,和 MokSBState[4]。 | shim |
PCR151 | 未使用 | |
PCR161 | 调试用,可能会在任何时候被使用或是重置。可能在官方固件发布中不可用。 | |
PCR23 | 应用支持,操作系统可以设定或清除此 PCR。 |
- 使用方式由操作系统决定,在不同的 Linux 发行版和 Windows 设备间的使用方式可能有所不同。
在 Windows 上,BitLocker 使用 PCR8-11 (Legacy) 或 PCR11-14 (UEFI) 用于其自身用途。 文档来自 tianocore[5]。
tpm2-totp包 通过人工观察和专用可信设备进行此检查。
当前 PCR 的值可以通过 systemd-analyze(1) 查看:
$ systemd-analyze pcrs
也可以通过来自 tpm2-tools包 的 tpm2_pcrread(1) 查看:
# tpm2_pcrread
排错
使用 TPM 2.0 后 LUKS2 在解锁时仍然需要密码
如果在遵循了上述指引后,在使用 TPM 2.0 硬件模块内的密钥解锁 LUKS2 设备时,仍然在 initrams 引导阶段被要求输入密码,可能需要在早启动阶段加载控制特定 TPM 2.0 硬件的内核模块(可以通过 systemd-cryptenroll --tpm2-device=list
获取其名)。
参见
- Gentoo:Trusted Platform Module
- TPM-JS 测试工具:源码 - 网页版.