TPM 基础:它到底是什么?

好,我们正式开始聊 TPM。很多朋友一听到「TPM 芯片」就觉得是个黑盒子,神秘得很。其实说白了,它就是一块专门干「脏活累活」的安全协处理器。我最早接触 TPM 是在一个工控项目里,客户要求必须用 TPM 存密钥,我当时还嘀咕:不就是个加密芯片吗?后来踩了坑才明白——它远不止「存个密钥」那么简单。

TPM 是什么?

TPM,全称 Trusted Platform Module,可信平台模块。你可以把它理解成主板上一个「自带保险柜的小电脑」。它有自己的处理器、非易失性存储、随机数发生器,甚至还有独立的时钟。它不依赖操作系统,也不依赖 CPU 的信任——它自己就是信任的起点。

核心要点:TPM 是一个独立的硬件安全元件,它的所有操作都在芯片内部完成,外部无法直接读取内部数据。这就是「硬件隔离」的底气。

我习惯把 TPM 比作「保安室里的保险箱」。保安(TPM)可以帮你开锁、换锁、检查门有没有被撬,但你永远拿不到保险箱的钥匙本身。你只能拿到保安给你的「开锁凭证」。

TPM 的主要功能

TPM 的功能很多,但核心就三块:密钥生成、安全存储、平台度量。我们一个一个说。

1. 密钥生成

TPM 内部有一个硬件随机数发生器(HRNG),它产生的随机数质量远高于软件伪随机数。TPM 可以用它生成 RSA、ECC、对称密钥等各种密钥对。

关键点在于:私钥永远不出芯片。生成时私钥直接写入 TPM 的 NVRAM,你拿到的只是公钥或者一个句柄。我曾经在项目里看到有人试图用 OpenSSL 生成密钥再导入 TPM,这其实绕过了 TPM 的安全优势——因为私钥在导入前已经在内存里暴露过了。

我的习惯:能用 TPM 生成的密钥,绝不在外部生成。哪怕多花几毫秒,也值得。

2. 安全存储

TPM 的存储分两类:

  • 持久存储(NVRAM):存放密钥、证书、度量值。容量通常不大,几 KB 到几十 KB。
  • 易失存储(RAM):运行时临时存放会话密钥、平台配置寄存器(PCR)值等。

TPM 的存储有一个重要特性:密封(Sealing)。你可以把数据「绑定」到特定的平台状态(比如 PCR 值)。只有平台状态匹配时,TPM 才允许解密。这比单纯加密强得多——你想想看,就算有人把硬盘拆走,换到另一台机器上也解不开。

注意:TPM 的 NVRAM 有写入次数限制。频繁写入会磨损存储单元。我在一个日志记录项目里就吃过这个亏——每写一次日志就更新一次 NVRAM,结果芯片提前报废了。

3. 平台度量

这是 TPM 最核心也最容易被忽视的功能。平台度量指的是:TPM 在系统启动过程中,逐级测量固件、引导加载器、操作系统内核的哈希值,并把这些值「扩展」到 PCR 中。

扩展操作是:PCR[n] = SHA256(PCR[n] || 新度量值)。这样 PCR 就记录了整个启动链的「指纹」。任何一环被篡改,最终的 PCR 值都会不同。

我记得有一次调试 Secure Boot 失败,怎么都找不到原因。后来用 TPM 工具读出 PCR 值,发现 PCR[0] 和 PCR[1] 跟预期对不上——原来是 BIOS 里一个隐藏的选项改了微码加载顺序。没有 TPM 度量,这种问题排查起来简直大海捞针。

TPM 的架构与规范

TPM 的规范由 TCG(Trusted Computing Group)制定。目前主流的是 TPM 2.0,它比 1.2 版本灵活得多。

架构概览

我画了一张简化的架构图,帮你理解 TPM 内部是怎么分工的:

TPM 2.0 内部架构图 TPM 2.0 内部架构 TPM 芯片边界 核心引擎 命令解析 & 调度 会话管理 授权验证 密码模块 RSA / ECC / AES SHA-1 / SHA-256 HRNG 存储模块 NVRAM PCR 寄存器 易失内存 I/O 接口 LPC / SPI / I²C 命令缓冲区 属性存储 持久化密钥 平台配置 说明:各模块通过内部总线通信,核心引擎负责调度所有操作。密码模块不直接暴露给外部。

TPM 2.0 规范要点

TPM 2.0 相比 1.2 有几个重要变化:

特性 TPM 1.2 TPM 2.0
算法支持 仅 RSA + SHA-1 RSA、ECC、SM2、SHA-256 等
密钥层次 固定层次 灵活层次(可自定义)
授权机制 仅密码 密码 + HMAC + 策略
PCR 数量 固定 24 个 可配置(通常 32+)
命令集 固定命令 可扩展命令

我个人更推荐新项目直接上 TPM 2.0。1.2 的 SHA-1 已经不够安全了,而且算法扩展性太差。我在一个金融项目里被迫用 TPM 1.2,结果客户要求支持 SM2 国密算法,1.2 根本做不到,最后只能换芯片——教训深刻。

TPM 的通信方式

TPM 通常通过 LPC 总线或 SPI 总线与 CPU 通信。在 UEFI 环境下,我们通过 TIS(TPM Interface Specification)协议访问 TPM。UEFI 的 TCG2 协议封装了这些底层细节,你只需要调用 EFI_TCG2_PROTOCOL 的接口就行。

一个简单的 TPM 操作流程大概是:

  1. 发送命令(如 TPM2_CC_CreatePrimary)到 TPM
  2. TPM 解析命令,执行操作
  3. TPM 返回响应(包含状态码和数据)
  4. UEFI 解析响应,提取结果

嗯,这里要注意:TPM 命令是同步的,发送后必须等待响应。我曾经在中断里调用 TPM 命令,结果死锁了——因为 TPM 操作本身会占用总线,中断上下文里等不到响应。

TPM 与 UEFI 的关系

UEFI 是 TPM 最重要的「搭档」。在 UEFI 启动过程中,TPM 负责度量每个启动组件:

  • BIOS 固件 → 度量到 PCR[0]
  • Option ROM → 度量到 PCR[2]
  • UEFI 引导加载器 → 度量到 PCR[4]
  • 操作系统内核 → 度量到 PCR[7]

这些 PCR 值就是后续「远程证明」和「密钥释放」的依据。说白了,TPM 帮你回答了三个问题:

  • 谁启动了系统?(度量链)
  • 启动过程有没有被篡改?(PCR 值)
  • 现在可以信任这个平台吗?(远程证明)

一个小技巧:调试 TPM 时,可以用 tpm2_pcrread 命令(Linux 下)或者 UEFI Shell 下的 tpm2 工具查看当前 PCR 值。对比预期值,能快速定位启动链中的异常环节。

总结一下

TPM 不是什么玄学。它就是一块专门干安全活的小芯片,能生成密钥、安全存储、度量平台状态。TPM 2.0 是当前的主流,算法灵活、架构清晰。在 UEFI 环境下,TPM 是安全启动和远程证明的基石。