可信平台模块
可信平台模块 (Trusted Platform Module,TPM) 是一种用于安全加密处理器的国际标准,作为一种集成的微处理器,它可以通过将加密密钥集成到设备中来保护硬件安全。
TPM 可以被用于在各种安全应用场景,例如安全启动,密钥存储与随机数生成。
TPM 仅在具有 TPM 硬件支持的设备上可用。如果设备具有 TPM 支持但并不可用,可能需要在 BIOS 设置中启用。
版本[编辑 | 编辑源代码]
有两个使用不同软件栈的 TPM 规范: 2.0 和 1.2。本文章仅讨论 TPM 2.0,有关 TPM 1.2 的内容参见 /1.2。
如果不确定是哪个版本,可以执行以下命令查看:
$ cat /sys/class/tpm/tpm*/tpm_version_major
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 并投入到实际生活使用的相关信息。
校验支持[编辑 | 编辑源代码]
从 2016 年 7 月 28 日起,所有运行 Windows 10 的电脑都必须带有 TPM 2.0 支持(无论是硬件实现还是软件实现)[1]。从内核版本 3.2 起,Linux 也提供了对 TPM 2.0 的支持[2],并且在默认的 Arch install 后不需要额外步骤来启用。
有两个方法可以验证 TPM 2.0 是否能免需特定软件即可配置:
- 检查日志,例如以 root 身份执行
journalctl -k --grep=tpm
。 - 读取
/sys/class/tpm/tpm0/device/description
[3] 或/sys/class/tpm/tpm0/tpm_version_major
的值。
基于 LUKS 的静态数据加密[编辑 | 编辑源代码]
要使用 TPM 解锁 LUKS 卷,可以使用 Clevis 或 #systemd-cryptenroll。
无论使用哪种方法,加密卷都将使用存储在 TPM 中的密钥解锁,既可在引导时自动解锁,也可以在之后手动解锁。使用 TPM 解锁可以确保设备在满足特定条件后才会解锁,例如固件未被修改,安全启动已经开启(参见 #访问 PCR 寄存器)。
- 这意味着只有当加密硬盘丢失时,数据才会受到保护,而整台设备丢失时,数据无法得到保护。
- 请注意,此方式会让设备更容易受到冷启动攻击,因为就算设备已经关闭很长时间(确保内存完全清除)攻击者也可以开机并等待 TPM 自动加载密钥。这对高价值目标来说是一个潜在隐患。
systemd-cryptenroll[编辑 | 编辑源代码]
参见 systemd-cryptenroll#Trusted Platform Module。
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 (2018-06, Debian)
- 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)包含可在随机读取,但仅能在尾部写入的哈希值,写入时依赖于前一项的哈希值,以此构成一系列区块链。常用于在不同引导间检验设备硬件和软件完整性(例如用于预防邪恶女佣攻击),也可用于解锁加密密钥并确保正在引导正确的操作系统。
TCG PC Client Specific Platform Firmware Profile Specification 定义了正在使用的寄存器,The Linux TPM PCR Registry 确定了使用它们的 Linux 系统组件。
有以下寄存器:
PCR | 用途 | 注释 |
---|---|---|
PCR0 | 核心系统固件可执行码 (又称固件) | 可能会在升级 UEFI 后更改。 |
PCR1 | 核心系统固件数据 (又称 UEFI 设置) | |
PCR2 | 扩展或可插入式可执行码 | |
PCR3 | 扩展或可插入式固件数据 | 将在 UEFI 引导的选择引导设备过程中设定。 |
PCR4 | 引导管理器代码和引导尝试 | 检测引导管理器和固件尝试引导的设备。 |
PCR5 | 引导管理器的配置与数据 | 可以检测引导器配置,包括 GPT 分区表。 |
PCR6 | 从 S4 和 S5 电源状态事件恢复 | |
PCR7 | 安全启动状态 | 包含完整的 PK/KEK/db 内容,以及用于确认每个引导程序的特定证书。[4]
使用 shim 时,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。 | [5] |
PCR151 | 未使用 | |
PCR161 | 调试用 | 可能会在任何时候被使用或是重置。可能在官方固件发布中不可用。 |
PCR23 | 应用支持 | 操作系统可以设定或清除此 PCR。 |
- 使用方式由操作系统决定,在不同的 Linux 发行版和 Windows 设备间的使用方式可能有所不同。
在 Windows 上,BitLocker 使用 PCR8-11 (Legacy) 或 PCR11-14 (UEFI) 用于其自身用途。 文档来自 tianocore[6]。
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 测试工具:源码 - 网页版.