远程证明概览

远程证明是验证机密虚拟机实例的身份是否合法以及是否在预期状态下运行的过程。认证可帮助您在向系统授予对受保护资源的访问权限之前评估系统的可信度。

认证方和模型

认证过程通常涉及三方:

  • 证明者。在 Google Cloud上,这是机密虚拟机实例上的工作负载,需要访问受保护的资源。为了提高对机密虚拟机实例未遭到入侵且不是冒名顶替者的信任度,虚拟机及其主机在启动过程中会测量虚拟机的虚拟硬件和软件状态。

  • 验证方。验证方是一个外部系统,用于验证来自机密虚拟机实例的证据,并根据其证明政策进行检查,以确保虚拟机配置符合预期。如果证据通过了必要的检查,验证方会返回证据的签名版本,称为证明结果。

    验证方可以是预先存在的服务(例如 Google Cloud Attestation 或 Intel Trust Authority),也可以是您自己构建的服务。

  • 依赖方。依赖方控制对证明者所需的受保护资源的访问权限。收到认证结果后,依赖方会根据其访问政策检查证据中的值。如果值匹配,则允许证明者访问资源。

    在 Google Cloud 上,依赖方通常是工作负载身份池,验证方作为 OpenID Connect (OIDC) 提供方添加。

各方之间的互动方式取决于您的架构所遵循的证明模型。远程证明过程 (RATS) 架构 RFC 定义了两种主要的证明模型:护照模型和背景调查模型。两者之间的主要区别在于哪一方拥有证明者的已验证身份:证明者还是依赖方。

Passport 型号

护照模型使用以下流程来确认证明者的身份并授予对所请求资源的访问权限:

  1. 证明方会向验证方发送其身份证据。

  2. 如果证据被视为可信,验证方会向证明方发送证明结果,该结果可能采用证明令牌的形式。

  3. 证明方将证明结果发送给依赖方。

  4. 依赖方会检查证明结果是否满足特定条件。如果结果符合预期,则依赖方会允许证明方访问请求的资源。

在护照模型中,证明方和依赖方需要就证明结果应是什么样子达成一致,这意味着他们需要就验证方达成一致。

证明护照模型

背景调查模型

背景调查模型使用以下流程来确认证明者的身份并授予对所请求资源的访问权限:

  1. 证明方会向信赖方发送其身份证据。

  2. 依赖方将证据转发给验证方。

  3. 如果证据被视为可信,验证方会向依赖方发送证明结果,通常以证明令牌的形式发送。

  4. 依赖方会检查证明结果是否满足特定条件。如果结果符合预期,则依赖方会允许证明方访问请求的资源。

认证背景调查模型

在后台检查模型中,依赖方会确定其所需的证明证据,并选择验证方。

认证方架构和证据

本部分介绍了作为证明方的机密虚拟机实例如何提供其身份的防篡改证据。

信任根

在可信执行环境 (TEE)(例如机密虚拟机实例)中,信任根是基础安全组件,其他信任关系都建立在信任根之上。信任根提供加密功能,具有防篡改功能,且无法由主机操作系统修改。

信任根属于 TEE 内的信任边界,称为可信计算基 (TCB)。TCB 是客户虚拟机及其主机上的一组硬件和软件,负责环境隔离(通过内存加密和 Hypervisor 隔离等机制)和测量以维护环境的完整性等职责。

TEE 支持测量、存储和报告功能的信任根:

  • 用于衡量的信任根是启动 TEE 启动过程衡量的代码。

  • 存储信任根以测量寄存器的形式为测量提供受保护的内存。

  • 用于报告的信任根为测量链提供完整性和真实性保护。它会从存储信任根检索测量结果,并将其捆绑到名为“报价”或“证明报告”的已签名证据包中。此软件包使用 TEE 驻留认证密钥进行签名,并且可以包含加密 Nonce,以确保证据是最新证据并受到保护,免受重放攻击。

以下信息详细介绍了不同机密计算技术的信任根的不同方法。

AMD SEV

具有 AMD SEV 的机密虚拟机实例通过使用基于安全强化型虚拟机 vTPM 的测量来证明其环境和配置。AMD 安全处理器和 AMD SEV 仅用于内存加密。

信任根如下:

  • 用于衡量的信任根:虚拟机实例固件

  • 存储信任根:安全强化型虚拟机 vTPM

  • 报告信任根:安全强化型虚拟机 vTPM,使用私有证明密钥对证明报告进行签名

SEV 信任根

如需了解在安全强化型虚拟机 vTPM 中的哪些位置记录了哪些测量结果,请参阅 vTPM 平台配置寄存器。

AMD SEV-SNP

具有 AMD SEV-SNP 的机密虚拟机实例主要通过 AMD 安全处理器(用于处理初始启动测量)来证明其环境和配置。

对于引导加载程序、内核和用户空间测量,可以使用基于安全强化型虚拟机 vTPM 的测量。

信任根如下:

  • 用于衡量的信任根:AMD 安全处理器 + 虚拟机实例固件

  • 存储信任根:AMD 安全处理器 + 安全强化型虚拟机 vTPM

  • 用于报告的信任根:

    • 初始启动测量:AMD 安全处理器,使用芯片驻留的版本芯片认可密钥 (VCEK) 对证明报告进行签名

    • 引导加载程序、内核和用户空间测量:安全强化型虚拟机 vTPM

SNP 信任根

如需了解 AMD 安全处理器中记录了哪些测量结果,请参阅 AMD SEV-SNP 测量结果寄存器。

如需了解在安全强化型虚拟机 vTPM 中的哪些位置记录了哪些测量结果,请参阅 vTPM 平台配置寄存器。

Intel TDX

采用 Intel TDX 的机密虚拟机实例通过 Intel TDX 模块证明其环境和配置。Intel TDX 模块在隔离的信任域中测量虚拟机客机的固件,并将这些测量结果存储在信任域测量 (MRTD) 中。启动链中的后续测量结果会测量到运行时测量寄存器 (RTMR) 中。

信任根如下:

  • 用于衡量的信任根:Intel TDX 模块

  • 存储信任根:信任域测量 (MRTD) 和运行时测量寄存器 (RTMR)

  • 报告信任根:Intel TDX 模块内的信任域引用 Enclave (TDQE),用于生成认证密钥以对认证引用进行签名

TDX 信任根

如需了解 TDX 测量寄存器中记录的测量值,请参阅 Intel TDX 测量寄存器。

硬件和软件信任根

您与主机管理程序的隔离级别取决于认证链是锚定在软件信任根还是硬件信任根中:

  • 软件信任根(依赖于 Hypervisor):信任链始于由云服务提供商管理的软件。客机的虚拟固件充当测量的信任根,而主机 Hypervisor 的安全强化型虚拟机 vTPM 充当存储和报告的信任根。在 Google Cloud上,这两个组件均由 Google 控制。

  • 硬件信任根(Hypervisor 隔离):信任链始于云服务商无法控制的专用 CPU 安全子系统:AMD 安全处理器或 Intel TDX 模块。此硬件会测量初始状态,并使用融合到处理器中或在处理器中派生的密钥对证明报告或报价进行签名。在 CPU 上,启动链中的后续软件组件(包括虚拟固件和引导加载程序)在受硬件加密和访问权限控制保护的内存中运行。这样可以从信任根中移除主机管理程序:即使恶意方入侵了管理程序,也无法修改受硬件保护的测量结果或伪造证明报告。

根据您的机密虚拟机实例配置,可以使用以下一种或多种机制来测量和证明其启动状态:

  • 安全强化型虚拟机 vTPM(软件信任根):使用 AMD SEV 进行证明时,需要使用安全强化型虚拟机 vTPM。AMD SEV-SNP 和 Intel TDX 机密虚拟机实例仍具有安全强化型虚拟机 vTPM,但您可以选择是否将其用作信任链的一部分。

    安全强化型虚拟机 vTPM 会将引导加载程序、内核和用户空间测量结果记录到 PCR 中。由于它由主机管理程序管理,因此它会在重新启动期间维护密钥封装等功能的状态。

  • AMD 安全处理器(硬件信任根):适用于 AMD SEV-SNP 机密虚拟机实例。在客户机启动之前,AMD 安全处理器会将初始启动状态(包括虚拟固件)测量到其 MEASUREMENT 寄存器中,并使用其 VCEK 对 ATTESTATION_REPORT 进行签名。

    您可以单独验证 AMD 安全处理器证明报告,也可以将其与安全强化型虚拟机 vTPM 报价相结合,以验证启动链的其余部分。

  • Intel TDX 测量寄存器(硬件信任根):适用于 Intel TDX 机密虚拟机实例。Intel TDX 模块在信任域测量 (MRTD) 中记录构建时虚拟固件测量,并将引导加载程序、内核和用户空间测量扩展到隔离信任域内的运行时测量寄存器 (RTMR) 中,而无需 vTPM。

    您可以单独验证 Intel TDX 模块报价,以涵盖整个启动链。Intel TDX 机密虚拟机实例中存在安全强化型虚拟机 vTPM,可用于 TPM 功能(例如密钥封装)。

测量寄存器

机密虚拟机的信任根以测量寄存器 (MR) 的形式为测量提供受保护、防篡改的存储空间。这些测量寄存器的名称因所使用的机密计算技术而异:

  • AMD SEV:平台配置寄存器 (PCR)。这些密钥位于安全强化型虚拟机 vTPM 中。

    安全强化型虚拟机 vTPM 使用三个 PCR 组,这些 PCR 组存储相同的测量值,但使用不同的算法进行哈希处理:SHA-1、SHA-256 和 SHA-384。

  • AMD SEV-SNP:启动 MEASUREMENT 注册。它位于 AMD 安全处理器内部。

    安全强化型虚拟机 vTPM 中的 PCR 也用于存储引导加载程序、内核和用户空间测量结果。

  • Intel TDX:信任域的构建时测量 (MRTD) 和运行时测量寄存器 (RTMR)。

    对于需要 TPM 接口的软件,安全强化型虚拟机 vTPM PCR 中也提供测量结果。

只有信任根可以更改寄存器值。测量寄存器通常包含一个加密摘要,代表单个事件或一组事件。

对于单个事件(例如虚拟机的启动测量或构建时测量),信任根通常会直接写入寄存器,并使寄存器在 TEE 的剩余生命周期内不可变。

在启动链中较晚加载的组件(例如引导加载程序、内核和用户空间)可能会将多个事件的测量结果记录到单个寄存器中。为了存储一组事件的测量值,测量寄存器会公开一个 extend 命令,该命令会将现有寄存器值与新的事件摘要串联起来,对串联后的值进行哈希处理,然后存储生成的摘要。此过程由以下公式表示:

\(MR_{new}=hash(MR_{old}\;∥\;hash(measured\;data))\)

由于哈希函数是单向的,因此在不以相同顺序提供相同测量值的情况下,很难复制相同的测量寄存器值。虽然此属性有助于确定虚拟机完整性,但它可能会使基于特定测量寄存器值制定政策变得具有挑战性。这是因为测量输入(例如软件或固件更新,或测量顺序更改)的微小变化会导致寄存器值不同,从而可能导致基于这些值的政策不稳定,并增加维护负担。如果您需要根据测量寄存器值制定政策,请尝试选择更稳定的寄存器值,例如 vTPM 上的 PCR 0 或 PCR 7。

事件日志

当测量值被写入或扩展到测量寄存器时,系统会将一个或多个日志写入客户机操作系统的文件系统,以记录发生的测量事件。

这些事件日志有以下用途:

  • 验证方可以重放事件日志,使用模拟的度量寄存器逐步执行机密虚拟机实例的度量过程。如果验证方计算的最终摘要与证明方报告的最终摘要一致,则可以提高对事件日志和机密虚拟机实例的启动过程均未被篡改的信任度。

  • 重放后,验证方可以解析事件日志,以将证据与证明政策进行比较。验证方可能要求证明方满足特定条件(例如启用安全启动或使用特定的机密计算技术),然后才会返回成功的证明结果。

事件日志存储在客户机操作系统的文件系统中的以下位置:

机密计算技术 要验证的 MR 日志类型 用于事件日志重放的客机操作系统路径
AMD SEV、AMD SEV-SNP、Intel TDX vTPM 平台配置寄存器 (PCR) 可信计算组织 (TCG) 事件日志 /sys/kernel/security/tpm0/binary_bios_measurements
Intel TDX RTMR[0]、RTMR[1]、RTMR[2] 机密计算事件日志 (CCEL) /sys/firmware/acpi/tables/data/CCEL

详细了解事件日志重放和解析。

报价和证明报告

报告信任根通过使用认证密钥对测量结果进行签名,为存储在测量寄存器中的摘要提供完整性和真实性保护。生成的二进制 blob 称为 vTPM 的 PCR 报价、AMD SEV-SNP 的证明报告和 Intel TDX 的报价。

对于不同的机密计算技术,二进制 blob 中的内容有所不同:

  • AMD SEV:安全强化型虚拟机 vTPM 会从其一个 PCR 库(SHA-1、SHA-256 或 SHA-384)中读取值,按数字顺序串联这些值,然后使用与 PCR 库相同的哈希算法对结果进行哈希处理,以创建摘要。此摘要以及验证方提供的可选 Nonce 会放入 TPMS_ATTEST 结构中,并由 vTPM 的私有证明密钥签名,以创建 PCR 引用。

    如需详细了解 TPMS_ATTEST 结构,请参阅可信平台模块库,第 2 部分:结构 (PDF)。

  • AMD SEV-SNP:AMD 安全处理器会根据在机密虚拟机实例 UEFI 执行之前进行的初始启动测量生成 SHA-384 摘要。

    此摘要、其他虚拟机数据以及验证方提供的可选 Nonce 会放入 ATTESTATION_REPORT 结构中,该结构由 AMD 安全处理器的版本芯片认可密钥 (VCEK) 签名,以创建证明报告。

    如需详细了解 ATTESTATION_REPORT 结构,请参阅 SEV 安全嵌套分页固件 ABI 规范 (PDF)。

  • Intel TDX:TDX 模块会将 MRTD 和 RTMR 值、其他虚拟机数据以及验证方提供的可选 Nonce 放入 TDREPORT_STRUCT 结构中。

    创建报价是一个多步骤流程。首先,CPU 内部的预配认证 Enclave 会从融合到 CPU 中的加密密钥派生预配认证密钥 (PCK)。然后,CPU 内的 Quoting Enclave 会生成一个私有证明密钥,该密钥使用预配认证密钥进行签名。然后,使用私有证明密钥对 TDREPORT_STRUCT 进行签名,以创建报价。

    如需详细了解 TDREPORT_STRUCT 结构,请参阅 Intel Trust Domain Extensions (Intel TDX) 信任域扩展模块基础架构规范 (PDF)。

代言广告

不同类型的背书可用作机密虚拟机实例在预期硬件、vTPM 和固件配置上运行的证据。

证书

X.509 v3 证书用作主机中使用正版 AMD 或 Intel 硬件或机密虚拟机实例使用安全强化型虚拟机 vTPM 的证据。

每种机密计算技术的证书名称都不同:

  • AMD SEV:认证密钥 (AK) 证书

  • AMD SEV-SNP:版本芯片认可密钥 (VCEK) 证书

  • Intel TDX:预配认证密钥 (PCK) 证书

对于 AMD SEV,该证书用于验证安全强化型虚拟机 vTPM。主机向 Google 的证书授权机构服务器发出请求,并直接将证书自动预配到机密虚拟机实例的 vTPM 非易失性存储空间中。客户机可以通过使用 go-tpm-tools 等软件向 vTPM 请求此证书来单独检索此证书。

对于 AMD SEV-SNP 和 Intel TDX,主机从 CPU 中提取硬件证据,并将其呈现给 Google 管理的缓存。此缓存存储之前从 AMD 密钥分发服务和 Intel 预配证书服务中提取的证书。成功提供硬件证据后,证书会缓存到主机的磁盘中,并与客户机共享。客户可以单独检索这些证书,以使用 go-sev-guest 和 go-tdx-guest 等软件验证硬件。

证书包含以下信息:

  • 证书颁发者身份,可以是 AMD、Google 或 Intel。

  • 公共证明密钥,用于验证 PCR 引用 (vTPM)、证明报告 (SEV-SNP) 和证明引用 (Intel TDX) 上的签名。

  • 仅限硬件证明:主机固件运行所在的硬件微代码和固件 TCB 版本。

  • 仅限硬件认证:将证书绑定到特定物理处理器的证据,该证据已使用处理器中的私钥进行签名,无法被窃取。对于 AMD SEV-SNP,此证据是平台 ID。对于 Intel TDX,证据是平台清单。

固件

对于硬件证明,固件启动认可可直接从虚拟机实例获取,也可在线下载。启动认可文件是经过签名的二进制序列化协议缓冲区,用于确认机密虚拟机实例的虚拟固件未被篡改。

虚拟机启动时,AMD 安全处理器或 Intel TDX 模块会在固件二进制文件执行之前对其进行哈希处理。此 SHA-384 摘要存储在 AMD SEV-SNP 的 MEASUREMENT 字段中,以及 Intel TDX 的 MRTD 中。

您可以使用该摘要从 Google 下载启动认可,使用 gcetcbendorsement 等工具验证签名是否源自 Google,然后验证固件测量结果与认可中记录的 SHA-384 摘要是否一致。

除了固件验证之外,您还可以使用启动认可中的某些属性来强制执行访问权限政策,例如最低安全版本号 (SVN)、vCPU 数量、内存配置或 UEFI 的系列 ID。

如需了解详情,请参阅验证机密虚拟机实例的固件。

验证方事件日志重放和解析

除了直接验证证明方提供的证据之外,验证方还可以重放证明方提供的事件日志,以根据其度量寄存器值验证其完整性。

为此,验证方会为其证明政策中需要检查的每个测量寄存器创建一个模拟版本。然后,它会使用事件日志中的事件填充该模拟寄存器。如果模拟寄存器的最终值与等效的实际测量寄存器中存储的值匹配,则会提高对事件日志和机密虚拟机实例的启动过程均未被篡改的信任度。

通过这种方式验证日志后,可以对其进行解析,以获取验证方或依赖方可作为政策依据的各个测量值。

构建您自己的事件日志重放和解析工具

虽然您可以自行构建软件来重放和解析事件日志,但我们建议您使用 go-eventlog 等成熟软件,以帮助您避免常见陷阱,例如可信计算组和机密计算事件日志格式的 EventType 漏洞。

如果您仍想构建自己的重放和解析软件,以下基于 vTPM 的示例可以帮助您初步了解,但您应根据自己的机密虚拟机实例生成的事件日志来实现。

以下示例包含 Ubuntu 24.04 vTPM 事件日志中的部分事件,这些事件会测量到 PCR 0 中。事件日志已使用以下命令通过 tpm2_eventlog 从二进制转换为 ASCII:

sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements

日志中的 PCR 0 事件如下所示:

---
version: 1
events:
- EventNum: 0
  PCRIndex: 0
  EventType: EV_NO_ACTION
  Digest: "0000000000000000000000000000000000000000"
  EventSize: 41
  SpecID:
  - Signature: Spec ID Event03
    platformClass: 0
    specVersionMinor: 0
    specVersionMajor: 2
    specErrata: 0
    uintnSize: 2
    numberOfAlgorithms: 3
    Algorithms:
    - Algorithm[0]:
      algorithmId: sha1
      digestSize: 20
    - Algorithm[1]:
      algorithmId: sha256
      digestSize: 32
    - Algorithm[2]:
      algorithmId: sha384
      digestSize: 48
    vendorInfoSize: 0
- EventNum: 1
  PCRIndex: 0
  EventType: EV_NO_ACTION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "0000000000000000000000000000000000000000"
  - AlgorithmId: sha256
    Digest: "0000000000000000000000000000000000000000000000000000000000000000"
  - AlgorithmId: sha384
    Digest: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  EventSize: 160
  Event: "53503830302d313535204576656e7433792b000056aca511a145224ba54128607dac543b0d476f6f676c652c20496e632e0016476f6f676c6520436f6d7075746520456e67696e650001000d476f6f676c652c20496e632e00792b000004322e37000300000028000000468e85a27fa36a458c790c1fe48b65ff4600690072006d007700610072006500520049004d0000000000000000000000000000000000"
- EventNum: 2
  PCRIndex: 0
  EventType: EV_NO_ACTION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "0000000000000000000000000000000000000000"
  - AlgorithmId: sha256
    Digest: "0000000000000000000000000000000000000000000000000000000000000000"
  - AlgorithmId: sha384
    Digest: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  EventSize: 288
  Event: "53503830302d313535204576656e7433792b000056aca511a145224ba54128607dac543b0d476f6f676c652c20496e632e0016476f6f676c6520436f6d7075746520456e67696e650001000d476f6f676c652c20496e632e00792b000004322e370001000000a800000068747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f6763655f7463625f696e746567726974792f6f766d665f7836345f63736d2f3834383939616564336339653837363735666638303966356665613365366638383733353533643166303130306464623961653333323639323832356163636537333866343562646563323738613430393864316332376534393533373134332e66642e7369676e65640000000000000000000000000000"
- EventNum: 3
  PCRIndex: 0
  EventType: EV_S_CRTM_VERSION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "4031fe1129fb826f12dcad169992cca9f4f56aa3"
  - AlgorithmId: sha256
    Digest: "fa129a8f82b65bcbce8f9e8e5f6de509beff9b1df33714116bf918c5a3bba45d"
  - AlgorithmId: sha384
    Digest: "21d340a4a30bb8865486d150cd9ceb46100662b92f336d38b87d70b373ca15c4c60878336924baa818dc2aceaeb40ea6"
  EventSize: 48
  Event: "47004300450020005600690072007400750061006c0020004600690072006d0077006100720065002000760032000000"
- EventNum: 4
  PCRIndex: 0
  EventType: EV_NONHOST_INFO
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "2b106cedd1631981619790bbc1afaa80cc6ecd3e"
  - AlgorithmId: sha256
    Digest: "6ac9241348a80c5755a63bcd1865b9f6d5720f6e925dc869bb4694281c1510c5"
  - AlgorithmId: sha384
    Digest: "1167e32c3814259ea4809234cccfbd2785c32bde882833bb199d6df6bd989a49f45663e63ce11699fcd01250050f042c"
  EventSize: 32
  Event: "474345204e6f6e486f7374496e666f0001000000000000000000000000000000"
- EventNum: 19
  PCRIndex: 0
  EventType: EV_SEPARATOR
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  - AlgorithmId: sha384
    Digest: "394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0"
  EventSize: 4
  Event: "00000000"

重置机密虚拟机实例后,其 PCR 会初始化为零。随着事件的发生,PCR 0 (PCRIndex: 0) 的 SHA-256 库中的值会发生如下变化(EV_NO_ACTION 事件不会扩展寄存器):

  1. 寄存器的值与分配给 PCR 0 的下一个事件 EV_S_CRTM_VERSION 的 SHA-256 摘要串联。串联结果会再次进行 SHA-256 哈希处理,然后存储在寄存器中。PCR 0 的 SHA-256 十六进制摘要现在为 0c3684a7571193d76a68e489ded7bf186fc2fb1efe0c6dd9ce147960bbc57365。

  2. EV_NONHOST_INFO 事件也采用相同的流程。PCR 0 的 SHA-256 十六进制摘要现在为 509f590b71fb22c9a6eef647e3c23611d13e599a6e15fdbb4db56ea4c2cb878d。

  3. EV_SEPARATOR 事件也使用相同的流程,该事件表示对特定寄存器的测量扩展已完成。EV_SEPARATOR 是一个 32 位零值 (\x00*4)。这使得 PCR 0 的最终 SHA-256 十六进制摘要为 a0b5ff3383a1116bd7dc6df177c0c2d433b9ee1813ea958fa5d166a202cb2a85。

以下 Python 代码通过创建模拟的 Compute Engine PCR 0 演示了上述过程。该代码不是事件日志重放,因为其事件摘要派生自已知值。创建正确的事件日志重放时,您必须改为从虚拟机实例的事件日志中读取摘要。

import hashlib

def CalculatePCR0(version_num: int, mem_encrypt_enum: int):
  """Calculates the expected SHA-256 PCR 0 value given the
  Compute Engine firmware version and Confidential Computing technology
  that's in use.

  This code uses derived values for events instead of reading digests from an
  event log. It's intended to demonstrate how to simulate the extend function
  used in measurement registers.

  While the code should provide correct values for PCR 0 in
  Compute Engine VM instances, for other PCRs and true event log replay
  you should read in digests from an event log instead of using derived values.

  PCR 0 measurements include:
    * EV_S_CRTM_VERSION: The firmware version string, in UTF-16 little-endian
      form. This value remains stable as long as the firmware version stays the
      same.
    * EV_NONHOST_INFO: This value changes based on the Confidential Computing
      technology that's in use.
    * EV_SEPARATOR: A 32-bit zero value to split UEFI and bootloader
      measurements.

  Args:
    version_num (int): The Compute Engine firmware version number. The
      value is 2.

    mem_encrypt_enum (int): The type of Confidential Computing technology used
      on the VM:

      0: None
      1: AMD SEV
      2: AMD SEV-ES
      3: Intel TDX
      4: AMD SEV-SNP

  Returns:
    A hexstring representing the expected PCR 0 digest.
  """
  # Create a hash object to act as PCR 0, and initialize it with zeroes.
  h = hashlib.sha256()
  h.update(b'\x00' * h.digest_size)

  # Update the hash object with the EV_S_CRTM_VERSION event, with a hard-coded
  # firmware version `version_num`.
  #
  # This code uses derived values for events. To use the digest supplied in an
  # event log for event log replay, you need to read in the event digest, and
  # then convert it to bytes before updating the hash object, similar to the
  # following:
  #
  # h.update(bytes.fromhex('fa129a8f82b65bcbce8f9e8e5f6de509beff9b1df33714116bf918c5a3bba45d'))
  #
  h.update(
          hashlib.sha256(
              # The firmware uses UCS-2 encoding, so we match it by encoding to
              # the equivalent UTF-16 little-endian. An extra null byte is
              # needed to match the required byte length.
              f'GCE Virtual Firmware v{version_num}\x00'.encode('utf-16-le')).digest()
          )

  # Create a new hash object to act as PCR 0 and update it with the previous
  # hash object's digest. This simulates the first part of the register EXTEND
  # function.
  h2 = hashlib.sha256()

  h2.update(h.digest())

  # Update the hash object with the EV_NONHOST_INFO event, which includes
  # `mem_encrypt_enum`, the Confidential Computing technology in use. Performing
  # this update completes the simulated EXTEND function.

  h2.update(
          hashlib.sha256(
              b'GCE NonHostInfo\x00'
              + (mem_encrypt_enum).to_bytes(1, byteorder='little')
              + (b'\x00' * 15)
              ).digest()
          )

  # Create a new hash object to act as PCR 0 and update it with the previous
  # hash object's digest. This simulates the first part of the register EXTEND
  # function.
  h3 = hashlib.sha256()
  h3.update(h2.digest())

  # Update the hash object with the EV_SEPARATOR event. Performing this update
  # completes the simulated EXTEND function.
  h3.update(hashlib.sha256(b'\x00' * 4).digest())

  # There are more PCR 0 events, but they're all `EV_NO_ACTION` and don't
  # affect the register value. Return the final simulated register value.
  digest = h3.hexdigest()
  return digest

print('\nPCR 0 simulation')
print('\nConfidential Computing type\tDigest')
# Compute Engine firmware version 2, no Confidential Computing
# Expected hexdigest: d0c70a9310cd0b55767084333022ce53f42befbb69c059ee6c0a32766f160783
print(f'None\t\t\t\t{CalculatePCR0(2, 0)}')

# Compute Engine firmware version 2, AMD SEV
# Expected hexdigest: a0b5ff3383a1116bd7dc6df177c0c2d433b9ee1813ea958fa5d166a202cb2a85
print(f'AMD SEV\t\t\t\t{CalculatePCR0(2, 1)}')

# Compute Engine firmware version 2, AMD SEV-SNP
# Expected hexdigest: 50597a27846e91d025eef597abbc89f72bff9af849094db97b0684d8bc4c515e
print(f'AMD SEV-SNP\t\t\t{CalculatePCR0(2, 4)}')

# Compute Engine firmware version 2, Intel TDX
# Expected hexdigest: 0cca9ec161b09288802e5a112255d21340ed5b797f5fe29cecccfd8f67b9f802
print(f'Intel TDX\t\t\t{CalculatePCR0(2, 3)}')

print()

依赖方配置

根据使用的是护照模型还是背景调查模型,依赖方会从证明方或验证方接收证明结果。

然后,依赖方会验证其在证明结果中收到的声明是否与预期值匹配。如果值匹配,则依赖方允许证明方以本地身份访问资源。

在 Google Cloud 中配置信赖方的常见模式是使用工作负载身份联合,并将证明者视为联合身份:

  1. 将验证方作为 OIDC 提供方添加到工作负载身份池。之后,附加到机密虚拟机实例工作负载的服务账号可以充当联合身份并访问所需资源。

  2. 定义验证方证明声明必须匹配的值,以便向证明方授予对资源的访问权限。

    在 Google Cloud中,这涉及将证明声明映射到属性,以便 Identity and Access Management (IAM) 可以将其作为联合身份必须通过的条件进行处理,从而以主账号身份进行身份验证。

    然后,您可以通过向所需资源的允许政策添加其联合主账号的角色绑定,向证明者授予对资源的直接访问权限。对于不支持联合身份的服务,您可以通过服务账号模拟提供对资源的访问权限。

除了工作负载身份联合之外,您还可以编写代码来直接解析证明令牌的声明。如需查看示例,请参阅机密虚拟机上的 vTPM 远程证明。