远程证明是指验证机密虚拟机实例的身份是否合法,以及该实例是否在预期状态下运行的过程。在授予系统对受保护资源的访问权限之前,证明可以帮助您评估系统的可信度。
认证方和认证模型
证明流程通常涉及三方:
证明者。在 Google Cloud上,这是机密虚拟机实例上的工作负载,需要访问受保护的资源。为了提高对机密虚拟机实例未遭入侵且不是冒名顶替者的信任度,虚拟机及其主机在启动过程中会测量虚拟机的虚拟硬件和软件状态。
验证方。验证方是一个外部系统,用于验证机密虚拟机实例提供的证据,并根据其证明政策检查该证据,以确保虚拟机配置符合预期。如果证据通过了所需的检查,验证工具会返回证据的签名版本,称为证明结果。
验证器可以是预先存在的服务,例如 Google Cloud Attestation 或 Intel Trust Authority,也可以是您自行构建的服务。
信赖方。信赖方控制着证明者所需的受保护资源的访问权限。在收到证明结果后,信赖方会根据其访问政策检查证据中的值。如果值匹配,则允许证明者访问资源。
在 Google Cloud 中,信赖方通常是工作负载身份池,验证方作为 OpenID Connect (OIDC) 提供方添加。
各方如何互动取决于您的架构所遵循的证明模型。远程证明程序 (RATS) 架构 RFC 定义了两种主要的证明模型:护照模型和背景检查模型。两者之间的主要区别在于,证明者的已验证身份由哪一方持有:证明者还是依赖方。
护照型号
护照模型使用以下流程来确认证明者的身份,并授予对所请求资源的访问权限:
证明者向验证者发送其身份证明。
如果证据被视为可信,验证方会向证明方发送证明结果,该结果可能以证明令牌的形式呈现。
证明者将证明结果发送给信赖方。
信赖方会检查证明结果是否满足特定条件。如果结果符合预期,信赖方会允许证明方访问所请求的资源。
在护照模型中,证明者和信赖方需要就证明结果的呈现方式达成一致,这意味着他们需要就验证者达成一致。
背景调查模式
背景调查模型使用以下流程来确认证明者的身份,并授予对所请求资源的访问权限:
证明者向信赖方发送其身份证明。
信赖方将证据转发给验证方。
如果证据被视为可信,验证方会将证明结果(通常以证明令牌的形式)发送给依赖方。
信赖方会检查证明结果是否满足特定条件。如果结果符合预期,信赖方会允许证明方访问所请求的资源。
借助背景调查模型,信赖方可以确定所需的证明证据,并选择验证方。
证明者架构和证据
本部分介绍了作为证明者的机密虚拟机实例如何提供防篡改的身份证明。
信任根
在可信执行环境 (TEE)(例如机密虚拟机实例)中,信任根是一种基础安全组件,其他信任均由此建立。信任根提供加密功能,具有防篡改能力,并且无法被主机操作系统修改。
信任根位于 TEE 内的信任边界内,称为可信计算基 (TCB)。TCB 是客户机虚拟机及其主机上的一组硬件和软件,负责执行环境隔离(通过内存加密和 Hypervisor 隔离等机制)和采取措施来维护环境完整性等任务。
TEE 支持用于测量、存储和报告功能的信任根:
用于测量的信任根是启动 TEE 启动过程测量的代码。
存储的信任根以测量寄存器的形式为测量提供受屏蔽的内存。
报告的信任根可为衡量链提供完整性和真实性保护。它从存储的信任根检索度量值,并将这些度量值捆绑到已签名的证据包中,该证据包称为“引用”或“证明报告”。此软件包使用 TEE 常驻证明密钥进行签名,并且可以包含加密 Nonce,以确保证据是最新证据,并防范重放攻击。
以下信息详细介绍了不同机密计算技术的信任根的不同方法。
AMD SEV
使用 AMD SEV 的机密虚拟机实例通过基于安全强化型虚拟机 vTPM 的度量来证明其环境和配置。AMD 安全处理器和 AMD SEV 仅用于内存加密。
信任根如下:
用于衡量的信任根:虚拟机实例固件
存储的信任根:安全强化型虚拟机的 vTPM
报告的信任根:安全强化型虚拟机的 vTPM,使用私有证明密钥对证明报告进行签名
如需了解安全强化型虚拟机 vTPM 中记录了哪些测量结果以及记录在何处,请参阅 vTPM 平台配置寄存器。
AMD SEV-SNP
启用 AMD SEV-SNP 的机密虚拟机实例主要通过 AMD 安全处理器证明其环境和配置,该处理器负责处理初始启动测量。
对于引导加载程序、内核和用户空间测量,可以使用基于安全强化型虚拟机 vTPM 的测量。
信任根如下:
用于衡量的信任根:AMD 安全处理器 + 虚拟机实例固件
存储的信任根:AMD 安全处理器 + 安全强化型虚拟机 vTPM
报告的信任根:
初始启动测量:AMD 安全处理器,使用芯片驻留版本芯片认可密钥 (VCEK) 对证明报告进行签名
引导加载程序、内核和用户空间测量:安全强化型虚拟机 vTPM
如需了解 AMD 安全处理器中记录的衡量指标,请参阅 AMD SEV-SNP 衡量寄存器。
如需了解安全强化型虚拟机 vTPM 中记录了哪些测量结果以及记录在何处,请参阅 vTPM 平台配置寄存器。
Intel TDX
采用 Intel TDX 的机密虚拟机实例通过 Intel TDX 模块证明其环境和配置。Intel TDX 模块在隔离的信任网域内测量虚拟机 guest 的固件,并将这些测量结果存储在信任网域的测量结果 (MRTD) 中。启动链中的后续测量结果会测量到运行时测量寄存器 (RTMR) 中。
信任根如下:
用于衡量的信任根:Intel TDX 模块
存储的信任根:信任域的度量 (MRTD) 和运行时度量寄存器 (RTMR)
报告的信任根:Intel TDX 模块内的 Trust Domain Quoting Enclave (TDQE),用于生成证明密钥以对证明引用进行签名
如需了解在 TDX 测量寄存器中记录了哪些测量结果,请参阅 Intel TDX 测量寄存器。
软件和硬件证明
Google Cloud 中的机密计算技术可以视为软件或硬件证明,具体取决于其信任根。
软件证明表示信任根基于软件:虚拟固件是测量的信任根,而存储的信任根是安全强化型虚拟机的 vTPM。vTPM 由宿主机的 Hypervisor 管理,而固件由客机虚拟机管理。在 Google Cloud上,这两个组件均由 Google 控制。
经过硬件证明是指测量结果由服务提供商控制范围之外的专用硬件进行管理和保护。在 Google Cloud上,此硬件包括用于 AMD SEV-SNP 的 AMD 安全处理器(仅用于启动度量)和用于 Intel TDX 的 Intel TDX 模块。
硬件证明会从测量和存储的信任根中移除服务提供商的 Hypervisor,并在专用硬件中隔离测量结果。即使恶意方获得了对主机 hypervisor 的控制权,他们也无法伪造证明报告或引用,因为他们无权修改专用硬件的寄存器。
Google Cloud 提供的机密计算技术分为以下几类:
AMD SEV:经过软件证明。虚拟固件会测量自身,并将测量结果存储在安全强化型虚拟机的 vTPM 中。
AMD SEV-SNP:经过硬件和软件混合证明。启动测量结果(包括虚拟固件的测量结果)由 AMD 安全处理器记录并存储,因此可进行硬件证明。引导加载程序、内核和用户空间测量结果存储在安全强化型虚拟机的 vTPM 中,从而使它们能够通过软件证明。您可以选择仅使用硬件证明的测量结果、仅使用软件证明的测量结果,或同时使用两者。
Intel TDX:经过硬件证明。TDX 模块会测量虚拟固件,所有测量结果都存储在 Intel TDX 模块中。安全强化型虚拟机的 vTPM 仍然是系统的一部分,但除非您运行需要 TPM 接口的软件,否则它不属于 TCB。
测量寄存器
机密虚拟机的信任根以测量寄存器 (MR) 的形式为测量提供安全强化型、防篡改的存储空间。这些测量寄存器的名称因所用的机密计算技术而异:
AMD SEV:平台配置寄存器 (PCR)。这些密钥位于安全强化型虚拟机的 vTPM 内。
安全强化型虚拟机的 vTPM 使用三个 PCR 库来存储相同的度量值,但这些度量值使用不同的算法进行哈希处理:SHA-1、SHA-256 和 SHA-384。
AMD SEV-SNP:启动
MEASUREMENT寄存器。它位于 AMD 安全处理器内部。安全强化型虚拟机 vTPM 中的 PCR 还用于存储引导加载程序、内核和用户空间测量结果。
Intel TDX:信任域 (MRTD) 和运行时测量寄存器 (RTMR) 的 build-time 测量。
对于需要 TPM 接口的软件,安全强化型虚拟机的 vTPM PCR 中也提供衡量结果。
只有信任根可以更改寄存器值。衡量寄存器通常保存单个加密摘要,该摘要表示单个事件或一组事件。
对于单个事件(例如虚拟机的启动时测量或 build-time 测量),信任根通常直接写入寄存器,并在 TEE 的剩余生命周期内使该寄存器保持不可变状态。
启动链中稍后加载的组件(例如引导加载程序、内核和用户空间)可能会将多个事件的测量结果记录到单个寄存器中。为了存储一组事件的测量结果,测量寄存器公开了一个 extend 命令,该命令会将现有寄存器值与新的事件摘要连接起来,对连接后的值进行哈希处理,然后存储生成的摘要。此流程可用以下公式表示:
由于哈希函数是单向的,因此很难在不以相同顺序提供相同衡量数据的情况下复制相同的衡量寄存器值。虽然此属性有助于确定虚拟机的完整性,但可能会使基于特定测量寄存器值制定政策变得困难。这是因为测量输入(例如软件或固件更新,或测量顺序变化)的微小变化会导致寄存器值发生变化,从而使这些值成为潜在的不稳定政策依据,并增加维护负担。如果您需要根据测量寄存器值制定政策,请尝试选择更稳定的寄存器值,例如 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 摘要。
此摘要、其他虚拟机数据以及验证方提供的可选随机数会放入
ATTESTATION_REPORT结构中,该结构由 AMD 安全处理器的版本芯片认可密钥 (VCEK) 签名,以创建证明报告。如需详细了解
ATTESTATION_REPORT结构,请参阅 SEV 安全嵌套分页固件 ABI 规范 (PDF)。Intel TDX:TDX 模块将 MRTD 和 RTMR 值、其他虚拟机数据以及验证方提供的可选随机数放入
TDREPORT_STRUCT结构中。创建报价是一个多步骤流程。首先,CPU 内部的 Provisioning Certification Enclave 会从熔入 CPU 的加密 Secret 中派生出 Provisioning Certification Key (PCK)。然后,CPU 内部的引用 Enclave 会生成一个私有证明密钥,该密钥使用配置认证密钥进行签名。然后,使用私有证明密钥对
TDREPORT_STRUCT进行签名,以创建引用。如需详细了解
TDREPORT_STRUCT结构,请参阅 Intel Trust Domain Extensions (Intel TDX) Module Base Architecture Specification (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 配置证书服务拉取的证书。成功呈现硬件证据后,证书会缓存到主机的磁盘,并与 guest 共享。Guest 可以单独检索这些证书,以使用 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 事件不会扩展寄存器):
寄存器的值与分配给 PCR 0 的下一个事件的 SHA-256 摘要
EV_S_CRTM_VERSION连接在一起。串联结果会再次进行 SHA-256 哈希处理,然后存储在寄存器中。PCR 0 的 SHA-256 hexdigest 现在为0c3684a7571193d76a68e489ded7bf186fc2fb1efe0c6dd9ce147960bbc57365。EV_NONHOST_INFO事件也采用相同的流程。PCR 0 的 SHA-256 hexdigest 现在为509f590b71fb22c9a6eef647e3c23611d13e599a6e15fdbb4db56ea4c2cb878d。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 中配置信赖方的常见模式是使用工作负载身份联合,并将证明者视为联合身份:
将验证程序作为 OIDC 提供方添加到工作负载身份池。之后,附加到保密虚拟机实例工作负载的服务账号便可以作为联合身份进行操作,并访问所需资源。
定义验证方证明声明必须匹配的值,以便向证明方授予对资源的访问权限。
在 Google Cloud中,这涉及将证明声明映射到属性,以便 Identity and Access Management (IAM) 可以将它们处理为条件,联合身份必须满足这些条件才能以主账号的身份进行身份验证。
然后,您可以向证明者授予对资源的直接访问权限,方法是向所需资源的允许政策添加其联合身份的主账号的角色绑定。 对于不支持联合身份的服务,您可以通过服务账号模拟来提供对资源的访问权限。
除了使用工作负载身份联合会,您还可以编写代码来直接解析证明令牌的声明。如需查看示例,请参阅机密虚拟机上的 vTPM 远程证明。