Part 1 of 2:
Trusting Confidential Computing in the Cloud
Running TEEs in the cloud without trusting the cloud provider
See the second post in this series:
Reverse Engineering Google's Proprietary Hypervisor
Introduction
Trusted Execution Environments (TEEs) let users send private data to third-party servers without trusting the server operator or cloud provider. For this to work, the data must stay private. TEEs can only guarantee this privacy if users verify the remote code that processes the data. However, that raises a basic question: how can they verify the code?
Earlier TEE technologies, such as Intel SGX, achieve this by isolating a single program from the rest of the computer, including the operating system. This simplifies verification but breaks compatibility with most software since even simple programs typically depend on an operating system for networking and file access. More recent TEE technologies, such as Intel TDX, are much more flexible. These newer TEEs use Confidential VMs (CVMs) to run an entire operating system within a trusted environment. Programs can be packaged into compact, bootable Linux images, enabling almost any unmodified software to run securely in a TEE.
Despite the advantages of CVM-based TEEs, one major drawback undermines confidence in their security. CVMs are harder to verify than previous TEE technologies because the verifier must check the entire boot process rather than just a single program. In Intel TDX TEEs, boot integrity is guaranteed by recording each boot stage, from the initial firmware to the point where the first process runs in the operating system. These records are combined into a set of hashes called measurements. Then, once the VM finishes booting, the software running within it can produce cryptographically signed reports, called quotes, containing these measurements. Today, cloud-compatible systems for verifying these quotes still require trust in the cloud provider or server operator.
To properly verify a quote, the verifier must know which measurements to expect from the VM. But this requires independently simulating the boot process, factoring in not just the remote application but also the operating system, firmware, and environment that loaded it. Several tools simulate this boot process, but they support only the QEMU hypervisor and OVMF firmware. By contrast, cloud providers like Google use proprietary hypervisors and firmware, which make the measurement process far harder to predict. Even the same VM image can produce dozens of valid measurements depending on environmental factors such as RAM size. Additionally, cloud providers regularly update their hypervisors and firmware, which change the measurements produced by newly deployed TDX images. These unpredictable changes make it hard for verifiers to reliably check measurements against expected values.
In practice, most deployments sidestep this problem by letting the cloud provider record the boot process and sign the measurements itself using software called a vTPM. But this undermines a core advantage of CVMs: eliminating the need to trust infrastructure operators. A user can only be fully confident that software in a CVM is safe to trust if they verify a quote directly from the CPU. To achieve this, they must independently simulate the boot process of a cloud-hosted CVM and compute its expected measurements. However, this requires software capable of precisely modeling the environment and boot process of cloud VMs, regardless of any updates to the cloud infrastructure.
To solve this problem, I built a tool called Attest, which can verify quotes even when the VM is running in the cloud. Attest uses the VM image file, firmware, and relevant environment details from the VM (such as available RAM) to compute expected measurements for both cloud and self-hosted environments. By allowing verifiers to independently generate and compare these measurements with those signed by the CPU, Attest enables trust in a VM’s integrity without requiring trust in the cloud provider.
Interactive Demo: The TDX Boot Process
This section walks through a real TDX boot process step by step and demonstrates how measurements are recorded and verified.
In TDX, a quote has two parts, both signed by a secret Intel key embedded in the CPU: the data (chosen by software running in the CVM), and several “measurement registers” that record the boot process. Each register is a protected storage slot in memory that stores a single hash. Every new piece of security-critical data is hashed with the register’s previous value to form a chain. Any change to this data alters the final register value, so any difference in the boot process can be detected.
Four TDX measurement registers are responsible for tracking the boot process: MRTD, RTMR0, RTMR1, and RTMR2. The CPU first reads the firmware that loads the VM and hashes it into MRTD. Next, the firmware records the VM’s initial environment into RTMR0. Subsequent steps in the boot process are recorded into RTMR1 or RTMR2, depending on which part of the process is being recorded.
The interactive diagram below illustrates the measurement sequence from a real Intel TDX VM instance. You can press play or scrub through the timeline to watch how the registers update at each stage. Clicking an event reveals detailed information about the data recorded at that stage.
All of these steps happen on the remote machine being verified. To check a quote, however, the verifier must independently reconstruct the expected register values for a trusted VM image and compare them to the quote signature produced by the CPU. Because each register is a hash chain, every boot event must be reproduced identically and in the same order.
Interactive Demo: Verifying a TDX Quote
The data needed to reproduce boot events comes from several sources. constant events are straightforward to verify because their values can be hardcoded. image events can be derived directly from the VM image. If the VM image is built reproducibly, anyone can rebuild it from source code and obtain the same image event hashes. This ties a TDX quote to the source code of the software that produced it. The environment events are the most complicated to reproduce since they depend on details like memory layout and hardware configuration, which vary across machines. The second post in this blog series covers how these details can ultimately be derived from a few basic machine details.
Only the RAM size, number of attached storage disks, and ACPI tables (which describe the attached hardware) are needed to reproduce RTMR0 for a given firmware. Attest’s proof-generation library packages these three values alongside each quote so the verifier can reliably reconstruct RTMR0 and verify the VM’s integrity. This lets the verifier validate every part of the VM’s environment except for dynamic elements that don’t need to be verified, such as the amount of available RAM or attached storage.
The interactive diagram below demonstrates the verification process. The simulation’s inputs are at the top. The left panel displays the VM’s reported environment details, while the right panel shows hashes calculated by rebuilding the VM image from source and hashing its components. Below the inputs, the main panel visualizes each boot event as it is reconstructed in sequence using the supplied inputs. At the bottom, you can observe how the rebuilt register values are checked against those in the signed quote.
Click the buttons next to each input to see how different changes affect verification. For example, clicking the filesystem toggle simulates a running VM instance whose filesystem differs from the published source code. This simulates a case where someone added a file or replaced a program with a backdoored copy before deploying. The boot process records this modified filesystem, so the signed quote reflects the change, but the verifier’s hashes are based on the original source code. When the two sides disagree, RTMR2 doesn’t match, and verification fails. Experiment with each input to see which registers are affected.
This protocol is implemented in the Attest GitHub repo as a Rust library and CLI tool for generating and verifying quotes. Nearly every input to the verification process can be reconstructed independently, except one: Attest does not attempt to rebuild the ACPI tables. Instead, it relies on the VM’s reported hashes. This is safe as long as the VM image is configured to process the ACPI tables in a sandbox, which is covered in part three of this series.
Conclusion
This work depended on understanding exactly what Google’s firmware records during boot, a process they don’t document publicly. Since Google doesn’t allow booting modified firmware and both their firmware and hypervisor are closed source, I had no way to inspect the underlying values hashed at each boot stage. Instead, I had to manually reverse-engineer these values. Now, Attest can extract all necessary values directly from Google’s firmware without simulating anything in a virtual machine. The next post in this series explains how this works.