From 05bc741b3cb761fe25212fc22f04e0c7404e81c0 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Thu, 25 Jun 2026 18:07:34 -0700 Subject: [PATCH 01/18] feat: add TDX measurement verification mode --- Cargo.lock | 2 + dstack-attest/src/attestation.rs | 45 +- dstack-attest/src/v1.rs | 120 ++++- dstack-attest/tests/sev_snp_verify.rs | 4 +- dstack-mr/src/kernel.rs | 85 +++- dstack-mr/src/lib.rs | 2 + dstack-mr/src/main.rs | 98 +++- dstack-mr/src/measurement.rs | 49 ++ dstack-mr/src/sev.rs | 101 +++-- dstack-mr/src/tdvf.rs | 416 ++++++++++++----- dstack-mr/src/tdx.rs | 625 ++++++++++++++++++++++++++ dstack-types/Cargo.toml | 2 + dstack-types/src/lib.rs | 481 +++++++++++++++++++- gateway/src/config.rs | 7 + gateway/src/main_service.rs | 30 +- verifier/src/verification.rs | 283 +++++++++++- vmm/src/app.rs | 89 ++-- vmm/src/app/image.rs | 35 +- vmm/src/config.rs | 7 + vmm/vmm.toml | 3 + 20 files changed, 2223 insertions(+), 261 deletions(-) create mode 100644 dstack-mr/src/measurement.rs create mode 100644 dstack-mr/src/tdx.rs diff --git a/Cargo.lock b/Cargo.lock index 7d475254e..c60356720 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2695,6 +2695,8 @@ dependencies = [ name = "dstack-types" version = "0.5.11" dependencies = [ + "ciborium", + "hex", "or-panic", "parity-scale-codec", "serde", diff --git a/dstack-attest/src/attestation.rs b/dstack-attest/src/attestation.rs index 4f177343b..c56652799 100644 --- a/dstack-attest/src/attestation.rs +++ b/dstack-attest/src/attestation.rs @@ -32,6 +32,7 @@ use tpm_qvl::verify::VerifiedReport as TpmVerifiedReport; pub use tpm_types::TpmQuote; use crate::amd_sev_snp::VerifiedAmdSnpReport; +use crate::v1::{strip_tdx_event_log_for_config, strip_tdx_runtime_event_log}; pub use crate::v1::{Attestation as AttestationV1, PlatformEvidence, StackEvidence}; pub const SNP_REPORT_DATA_RANGE: std::ops::Range = 0x50..0x90; @@ -596,17 +597,24 @@ impl VersionedAttestation { } } - /// Strip data for certificate embedding (e.g. keep RTMR3 event logs only). + /// Strip data for certificate embedding. pub fn into_stripped(self) -> Self { match self { Self::V0 { mut attestation } => { - if let Some(tdx_quote) = attestation.tdx_quote_mut() { - tdx_quote.event_log = tdx_quote - .event_log - .iter() - .filter(|e| e.imr == 3) - .map(|e| e.stripped()) - .collect(); + match &mut attestation.quote { + AttestationQuote::DstackTdx(tdx_quote) => { + tdx_quote.event_log = strip_tdx_event_log_for_config( + std::mem::take(&mut tdx_quote.event_log), + &attestation.config, + ); + } + AttestationQuote::DstackGcpTdx(quote) => { + quote.tdx_quote.event_log = strip_tdx_runtime_event_log(std::mem::take( + &mut quote.tdx_quote.event_log, + )); + } + AttestationQuote::DstackAmdSevSnp(_) + | AttestationQuote::DstackNitroEnclave(_) => {} } Self::V0 { attestation } } @@ -983,17 +991,16 @@ pub enum AttestationQuote { DstackTdx(TdxQuote), DstackGcpTdx(DstackGcpTdxQuote), DstackNitroEnclave(DstackNitroQuote), - /// Keep this last to preserve SCALE discriminants for existing variants. DstackAmdSevSnp(SnpQuote), } impl AttestationQuote { pub fn mode(&self) -> AttestationMode { match self { - AttestationQuote::DstackTdx { .. } => AttestationMode::DstackTdx, - AttestationQuote::DstackAmdSevSnp { .. } => AttestationMode::DstackAmdSevSnp, - AttestationQuote::DstackGcpTdx { .. } => AttestationMode::DstackGcpTdx, - AttestationQuote::DstackNitroEnclave { .. } => AttestationMode::DstackNitroEnclave, + AttestationQuote::DstackTdx(_) => AttestationMode::DstackTdx, + AttestationQuote::DstackAmdSevSnp(_) => AttestationMode::DstackAmdSevSnp, + AttestationQuote::DstackGcpTdx(_) => AttestationMode::DstackGcpTdx, + AttestationQuote::DstackNitroEnclave(_) => AttestationMode::DstackNitroEnclave, } } } @@ -1665,6 +1672,14 @@ impl Attestation { .map_err(|_| anyhow!("Quote lock poisoned"))?; let mode = AttestationMode::detect()?; + let config = match mode { + AttestationMode::DstackAmdSevSnp + | AttestationMode::DstackTdx + | AttestationMode::DstackGcpTdx => { + read_vm_config().context("Failed to read vm config")? + } + AttestationMode::DstackNitroEnclave => String::new(), + }; let runtime_events = match mode { AttestationMode::DstackTdx | AttestationMode::DstackGcpTdx => { RuntimeEvent::read_all().context("Failed to read runtime events")? @@ -1713,9 +1728,7 @@ impl Attestation { let config = match "e { AttestationQuote::DstackAmdSevSnp(_) | AttestationQuote::DstackTdx(_) - | AttestationQuote::DstackGcpTdx(_) => { - read_vm_config().context("Failed to read vm config")? - } + | AttestationQuote::DstackGcpTdx(_) => config, AttestationQuote::DstackNitroEnclave(quote) => { let os_image_hash = quote .decode_image_hash() diff --git a/dstack-attest/src/v1.rs b/dstack-attest/src/v1.rs index a91e9393a..7c36618d9 100644 --- a/dstack-attest/src/v1.rs +++ b/dstack-attest/src/v1.rs @@ -10,6 +10,53 @@ use tpm_types::TpmQuote; pub const ATTESTATION_VERSION: u64 = 1; +const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; +const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; + +fn is_tdx_acpi_data_event(event: &TdxEvent) -> bool { + event.imr == 0 + && event.event_type == TDX_ACPI_DATA_EVENT_TYPE + && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD +} + +pub(crate) fn strip_tdx_runtime_event_log(event_log: Vec) -> Vec { + event_log + .into_iter() + .filter(|event| event.imr == 3) + .map(|event| event.stripped()) + .collect() +} + +pub(crate) fn strip_tdx_measurement_event_log(event_log: Vec) -> Vec { + event_log + .into_iter() + .filter_map(|event| { + if is_tdx_acpi_data_event(&event) || event.imr == 3 { + Some(event.stripped()) + } else { + None + } + }) + .collect() +} + +pub(crate) fn is_tdx_measurement_config(config: &str) -> bool { + serde_json::from_str::(config) + .map(|config| config.tdx_attestation_variant.is_measurement()) + .unwrap_or(false) +} + +pub(crate) fn strip_tdx_event_log_for_config( + event_log: Vec, + config: &str, +) -> Vec { + if is_tdx_measurement_config(config) { + strip_tdx_measurement_event_log(event_log) + } else { + strip_tdx_runtime_event_log(event_log) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "kind", content = "data")] pub enum PlatformEvidence { @@ -92,14 +139,14 @@ impl PlatformEvidence { } pub fn into_stripped(self) -> Self { + self.into_stripped_for_config("") + } + + pub fn into_stripped_for_config(self, config: &str) -> Self { match self { Self::Tdx { quote, event_log } => Self::Tdx { quote, - event_log: event_log - .into_iter() - .filter(|event| event.imr == 3) - .map(|event| event.stripped()) - .collect(), + event_log: strip_tdx_event_log_for_config(event_log, config), }, Self::GcpTdx { quote, @@ -107,11 +154,7 @@ impl PlatformEvidence { tpm_quote, } => Self::GcpTdx { quote, - event_log: event_log - .into_iter() - .filter(|event| event.imr == 3) - .map(|event| event.stripped()) - .collect(), + event_log: strip_tdx_runtime_event_log(event_log), tpm_quote, }, other => other, @@ -242,9 +285,10 @@ impl Attestation { } pub fn into_stripped(self) -> Self { + let config = self.stack.config().to_string(); Self { version: self.version, - platform: self.platform.into_stripped(), + platform: self.platform.into_stripped_for_config(&config), stack: self.stack, } } @@ -414,6 +458,60 @@ mod tests { ); } + fn boot_event(idx: usize) -> TdxEvent { + TdxEvent { + imr: 0, + event_type: idx as u32, + digest: vec![idx as u8; 48], + event: String::new(), + event_payload: vec![0xff; idx + 1], + } + } + + fn acpi_data_event(idx: usize) -> TdxEvent { + TdxEvent { + imr: 0, + event_type: TDX_ACPI_DATA_EVENT_TYPE, + digest: vec![idx as u8; 48], + event: String::new(), + event_payload: TDX_ACPI_DATA_EVENT_PAYLOAD.to_vec(), + } + } + + fn runtime_event() -> TdxEvent { + RuntimeEvent { + event: "app-id".into(), + payload: vec![0x42], + } + .into() + } + + #[test] + fn measurement_stripping_keeps_only_acpi_data_digests_and_runtime_payloads() { + let mut event_log = (0..20).map(boot_event).collect::>(); + event_log[3] = acpi_data_event(3); + event_log[8] = acpi_data_event(8); + event_log[15] = acpi_data_event(15); + event_log.push(runtime_event()); + + let stripped = strip_tdx_measurement_event_log(event_log); + + assert_eq!(stripped.len(), 4); + assert_eq!( + stripped[0..3] + .iter() + .map(|event| event.digest.clone()) + .collect::>(), + vec![vec![3u8; 48], vec![8u8; 48], vec![15u8; 48]] + ); + assert!(stripped[0..3] + .iter() + .all(|event| event.imr == 0 && event.event_payload.is_empty())); + assert_eq!(stripped[3].imr, 3); + assert_eq!(stripped[3].event, "app-id"); + assert_eq!(stripped[3].event_payload, vec![0x42]); + } + #[test] fn sev_snp_with_report_data_patches_report_and_stack() { let mut report = vec![0x11; 1184]; diff --git a/dstack-attest/tests/sev_snp_verify.rs b/dstack-attest/tests/sev_snp_verify.rs index 933311264..510c6b1a1 100644 --- a/dstack-attest/tests/sev_snp_verify.rs +++ b/dstack-attest/tests/sev_snp_verify.rs @@ -95,7 +95,7 @@ fn verify_sev_snp_attestation_bin() { // image build's digest.sev.txt. assert_eq!( hex::encode(&binding.os_image_hash), - "32b4767373ad7fa0f9c418925006194d5c3f5619529f309fe81156789fecd8bc", + "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda", "derived os_image_hash" ); // The HOST_DATA-bound app identity is recovered from the mr_config document. @@ -111,7 +111,7 @@ fn verify_sev_snp_attestation_bin() { // Forged / tampered quote coverage (all offline, using the real fixture). // --------------------------------------------------------------------------- -const OS_IMAGE_HASH: &str = "32b4767373ad7fa0f9c418925006194d5c3f5619529f309fe81156789fecd8bc"; +const OS_IMAGE_HASH: &str = "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda"; fn decoded_attestation() -> dstack_attest::attestation::Attestation { let versioned = diff --git a/dstack-mr/src/kernel.rs b/dstack-mr/src/kernel.rs index 878a2b012..a4e969563 100644 --- a/dstack-mr/src/kernel.rs +++ b/dstack-mr/src/kernel.rs @@ -7,6 +7,19 @@ use anyhow::{bail, Context, Result}; use object::pe; use sha2::{Digest, Sha384}; +/// QEMU's TDX setup-header patch places the initrd at a memory-dependent +/// address below this guest-memory size. At and above this threshold the +/// patched kernel Authenticode hash is stable for a given kernel/initrd pair. +pub const TDX_KERNEL_HASH_STABLE_MIN_MEMORY: u64 = 0xB0000000; +/// QEMU's low-memory initrd placement also resolves to the same below-4G +/// placement at exactly 2 GiB, so it shares the high-memory patched kernel hash. +pub const TDX_KERNEL_HASH_COMPAT_2G_MEMORY: u64 = 0x80000000; + +pub fn tdx_kernel_hash_uses_precomputed_high_mem(memory_size: u64) -> bool { + memory_size == TDX_KERNEL_HASH_COMPAT_2G_MEMORY + || memory_size >= TDX_KERNEL_HASH_STABLE_MIN_MEMORY +} + /// Calculates the Authenticode hash of a PE/COFF file fn authenticode_sha384_hash(data: &[u8]) -> Result> { let lfanew_offset = 0x3c; @@ -177,8 +190,8 @@ fn patch_kernel( 0x37ffffff }; - let lowmem = if mem_size < 0xb0000000 { - 0xb0000000 + let lowmem = if mem_size < TDX_KERNEL_HASH_STABLE_MIN_MEMORY { + TDX_KERNEL_HASH_STABLE_MIN_MEMORY } else { 0x80000000 }; @@ -211,6 +224,19 @@ fn patch_kernel( Ok(kd) } +/// Compute the first RTMR[1] event digest: the Authenticode SHA-384 hash of the +/// kernel after QEMU applies its setup-header patches. +pub(crate) fn patched_kernel_authenticode_sha384( + kernel_data: &[u8], + initrd_size: u32, + mem_size: u64, + acpi_data_size: u32, +) -> Result> { + let kd = patch_kernel(kernel_data, initrd_size, mem_size, acpi_data_size) + .context("Failed to patch kernel")?; + authenticode_sha384_hash(&kd).context("Failed to compute kernel hash") +} + /// Measures a QEMU-patched TDX kernel image. pub(crate) fn rtmr1_log( kernel_data: &[u8], @@ -218,9 +244,8 @@ pub(crate) fn rtmr1_log( mem_size: u64, acpi_data_size: u32, ) -> Result>> { - let kd = patch_kernel(kernel_data, initrd_size, mem_size, acpi_data_size) - .context("Failed to patch kernel")?; - let kernel_hash = authenticode_sha384_hash(&kd).context("Failed to compute kernel hash")?; + let kernel_hash = + patched_kernel_authenticode_sha384(kernel_data, initrd_size, mem_size, acpi_data_size)?; Ok(vec![ kernel_hash, measure_sha384(b"Calling EFI Application from Boot Option"), @@ -236,3 +261,53 @@ pub(crate) fn measure_cmdline(cmdline: &str) -> Vec { utf16_cmdline.extend([0, 0]); measure_sha384(&utf16_cmdline) } + +#[cfg(test)] +mod tests { + use super::*; + + fn initrd_addr(kernel: &[u8]) -> u32 { + u32::from_le_bytes(kernel[0x218..0x21c].try_into().unwrap()) + } + + #[test] + fn tdx_kernel_patch_uses_precomputed_digest_at_2g_and_high_memory() { + let mut kernel = vec![0u8; 0x1000]; + // Linux boot protocol >= 2.12 with XLF_CAN_BE_LOADED_ABOVE_4G makes + // QEMU derive the initrd address from available low memory. + kernel[0x206..0x208].copy_from_slice(&0x020cu16.to_le_bytes()); + kernel[0x236..0x238].copy_from_slice(&0x0040u16.to_le_bytes()); + + let below_2g = patch_kernel(&kernel, 0x100000, 0x80000000 - 0x1000, 0x28000).unwrap(); + let at_2g = patch_kernel(&kernel, 0x100000, 0x80000000, 0x28000).unwrap(); + let between_2g_and_high_mem = patch_kernel( + &kernel, + 0x100000, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY - 0x1000, + 0x28000, + ) + .unwrap(); + let at_threshold = patch_kernel( + &kernel, + 0x100000, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY, + 0x28000, + ) + .unwrap(); + let above_threshold = patch_kernel( + &kernel, + 0x100000, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY + 0x4000_0000, + 0x28000, + ) + .unwrap(); + + assert_ne!(initrd_addr(&below_2g), initrd_addr(&at_2g)); + assert_ne!( + initrd_addr(&between_2g_and_high_mem), + initrd_addr(&at_threshold) + ); + assert_eq!(initrd_addr(&at_2g), initrd_addr(&at_threshold)); + assert_eq!(initrd_addr(&at_threshold), initrd_addr(&above_threshold)); + } +} diff --git a/dstack-mr/src/lib.rs b/dstack-mr/src/lib.rs index ad71c0aee..2513c2897 100644 --- a/dstack-mr/src/lib.rs +++ b/dstack-mr/src/lib.rs @@ -17,9 +17,11 @@ pub type RtmrLogs = [RtmrLog; 3]; mod acpi; mod kernel; mod machine; +pub mod measurement; mod num; pub mod sev; mod tdvf; +pub mod tdx; mod uefi_var; mod util; diff --git a/dstack-mr/src/main.rs b/dstack-mr/src/main.rs index 2dca7574f..a6ace663f 100644 --- a/dstack-mr/src/main.rs +++ b/dstack-mr/src/main.rs @@ -4,17 +4,51 @@ //! `dstack-mr` CLI. //! -//! Currently exposes the AMD SEV-SNP `os_image_hash` computation used by the -//! image build to emit `digest.sev.txt`. +//! Exposes build-time OS-image measurement material/hash computations. use anyhow::{bail, Context, Result}; +use dstack_types::OsImageMeasurementDocument; +use serde_json::Value; use std::path::Path; -const USAGE: &str = "usage: dstack-mr sev-os-image-hash "; +const USAGE: &str = "\ +usage: + dstack-mr measure-os + dstack-mr inspect-measurement + dstack-mr sev-os-image-hash + dstack-mr tdx-os-image-measurement + dstack-mr tdx-os-image-hash + +features: + cbor-measurement-v2"; fn main() -> Result<()> { let mut args = std::env::args().skip(1); match args.next().as_deref() { + Some("measure-os") => { + let image_dir = args.next().context(USAGE)?; + let document = dstack_mr::measurement::os_image_measurement_document_for_image_dir( + Path::new(&image_dir), + ) + .context("failed to compute os image measurement document")?; + println!( + "{}", + serde_json::to_string(&document) + .context("failed to serialize os image measurement document")? + ); + Ok(()) + } + Some("inspect-measurement") => { + let measurement_json = args.next().context(USAGE)?; + let document = inspect_measurement(Path::new(&measurement_json)) + .context("failed to inspect os image measurement document")?; + println!( + "{}", + serde_json::to_string_pretty(&document) + .context("failed to serialize decoded measurement document")? + ); + Ok(()) + } Some("sev-os-image-hash") => { let image_dir = args.next().context(USAGE)?; let hash = dstack_mr::sev::sev_os_image_hash_for_image_dir(Path::new(&image_dir)) @@ -22,6 +56,26 @@ fn main() -> Result<()> { println!("{}", hex::encode(hash)); Ok(()) } + Some("tdx-os-image-measurement") => { + let image_dir = args.next().context(USAGE)?; + let document = dstack_mr::tdx::tdx_os_image_measurement_document_for_image_dir( + Path::new(&image_dir), + ) + .context("failed to compute tdx os image measurement material")?; + println!( + "{}", + serde_json::to_string(&document) + .context("failed to serialize tdx measurement material")? + ); + Ok(()) + } + Some("tdx-os-image-hash") => { + let image_dir = args.next().context(USAGE)?; + let hash = dstack_mr::tdx::tdx_os_image_hash_for_image_dir(Path::new(&image_dir)) + .context("failed to compute tdx os_image_hash")?; + println!("{}", hex::encode(hash)); + Ok(()) + } Some("-h") | Some("--help") => { println!("{USAGE}"); Ok(()) @@ -30,3 +84,41 @@ fn main() -> Result<()> { None => bail!("{USAGE}"), } } + +fn inspect_measurement(path: &Path) -> Result { + let document_text = fs_err::read_to_string(path) + .with_context(|| format!("failed to read {}", path.display()))?; + let document: OsImageMeasurementDocument = serde_json::from_str(&document_text) + .with_context(|| format!("failed to parse {}", path.display()))?; + let mut out: Value = serde_json::from_str(&document_text) + .with_context(|| format!("failed to parse {}", path.display()))?; + + if let (Some(tdx), Some(tdx_value)) = (&document.tdx, out.get_mut("tdx")) { + replace_measurement_field( + tdx_value, + tdx.decode_measurement_value() + .map_err(anyhow::Error::msg) + .context("failed to decode tdx measurement CBOR")?, + ); + } + if let (Some(snp), Some(snp_value)) = (&document.snp, out.get_mut("snp")) { + replace_measurement_field( + snp_value, + snp.decode_measurement_value() + .map_err(anyhow::Error::msg) + .context("failed to decode snp measurement CBOR")?, + ); + } + Ok(out) +} + +fn replace_measurement_field(section: &mut Value, decoded_measurement: Value) { + let Some(section) = section.as_object_mut() else { + return; + }; + if section.contains_key("measurement") { + section.insert("measurement".to_string(), decoded_measurement); + } else if section.contains_key("m") { + section.insert("m".to_string(), decoded_measurement); + } +} diff --git a/dstack-mr/src/measurement.rs b/dstack-mr/src/measurement.rs new file mode 100644 index 000000000..602afee60 --- /dev/null +++ b/dstack-mr/src/measurement.rs @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: © 2026 Phala Network +// +// SPDX-License-Identifier: Apache-2.0 + +//! Unified build-time OS-image measurement document. + +use anyhow::{Context, Result}; +use dstack_types::{ + OsImageMeasurementDocument, SevOsImageMeasurementDocument, TdxOsImageMeasurementDocument, +}; +use fs_err as fs; +use serde::Deserialize; +use std::path::Path; + +#[derive(Debug, Deserialize)] +struct ImageMetadata { + #[serde(default, rename = "bios-sev")] + bios_sev: Option, +} + +/// Generate `measurement.json` for an image directory. +/// +/// TDX material is mandatory for the normal dstack image. SNP material is +/// included when metadata declares a dedicated `bios-sev` firmware. +pub fn os_image_measurement_document_for_image_dir( + image_dir: &Path, +) -> Result { + let meta_path = image_dir.join("metadata.json"); + let meta_str = fs::read_to_string(&meta_path) + .with_context(|| format!("cannot read {}", meta_path.display()))?; + let meta: ImageMetadata = + serde_json::from_str(&meta_str).context("failed to parse image metadata.json")?; + + let tdx = TdxOsImageMeasurementDocument::new( + crate::tdx::tdx_os_image_measurement_for_image_dir(image_dir) + .context("failed to build TDX measurement document")?, + ); + + let snp = if meta.bios_sev.is_some() { + Some(SevOsImageMeasurementDocument::new( + crate::sev::sev_os_image_measurement_for_image_dir(image_dir) + .context("failed to build SNP measurement document")?, + )) + } else { + None + }; + + Ok(OsImageMeasurementDocument::new(Some(tdx), snp)) +} diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index 1d97d2c2f..dedab9453 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -321,6 +321,27 @@ fn build_sev_hashes_page( Ok(page) } +fn measured_kernel_cmdline(input: Option<&str>) -> String { + match input { + Some(base) if !base.trim().is_empty() => base.trim().to_string(), + _ => "console=ttyS0 loglevel=7".to_string(), + } +} + +fn kernel_cmdline_sha256(input: Option<&str>) -> Vec { + let cmdline = measured_kernel_cmdline(input); + let mut cmdline_bytes = cmdline.as_bytes().to_vec(); + cmdline_bytes.push(0); + Sha256::digest(&cmdline_bytes).to_vec() +} + +fn effective_initrd_hash_from_hex(value: &str) -> Result> { + if value.is_empty() { + return Ok(Sha256::digest(b"").to_vec()); + } + decode_required_hex("initrd_hash", value, 32) +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SectionType { SnpSecMemory = 1, @@ -664,10 +685,7 @@ pub fn compute_expected_measurement(input: &MeasurementInput) -> Result<[u8; 48] .as_deref() .ok_or_else(|| anyhow::anyhow!("vcpu_type is required"))?; - let cmdline = match input.base_cmdline.as_deref() { - Some(base) if !base.trim().is_empty() => base.trim().to_string(), - _ => "console=ttyS0 loglevel=7".to_string(), - }; + let cmdline = measured_kernel_cmdline(input.base_cmdline.as_deref()); let resolved_sections = input .ovmf_sections .iter() @@ -737,12 +755,15 @@ pub fn compute_expected_measurement(input: &MeasurementInput) -> Result<[u8; 48] fn sev_os_image_measurement( input: &MeasurementInput, ) -> Result { + // Validate that the measured command line commits the rootfs identity. The + // compact image projection does not carry a separate rootfs_hash because it + // is already committed by `kernel_cmdline_sha256`. + rootfs_hash_from_cmdline(input.base_cmdline.as_deref())?; Ok(dstack_types::SevOsImageMeasurement { - rootfs_hash: rootfs_hash_from_cmdline(input.base_cmdline.as_deref())?, - base_cmdline: input.base_cmdline.clone(), - ovmf_hash: input.ovmf_hash.clone(), - kernel_hash: input.kernel_hash.clone(), - initrd_hash: input.initrd_hash.clone(), + kernel_cmdline_sha256: kernel_cmdline_sha256(input.base_cmdline.as_deref()), + ovmf_hash: decode_required_hex("ovmf_hash", &input.ovmf_hash, 48)?, + kernel_hash: decode_required_hex("kernel_hash", &input.kernel_hash, 32)?, + initrd_hash: effective_initrd_hash_from_hex(&input.initrd_hash)?, sev_hashes_table_gpa: input.sev_hashes_table_gpa, sev_es_reset_eip: input.sev_es_reset_eip, ovmf_sections: input @@ -821,9 +842,9 @@ struct ImageMetadata { bios_sev: Option, } -fn file_sha256_hex(path: &Path) -> Result { +fn file_sha256(path: &Path) -> Result> { let data = fs::read(path).with_context(|| format!("cannot read {}", path.display()))?; - Ok(hex::encode(Sha256::digest(data))) + Ok(Sha256::digest(data).to_vec()) } pub fn rootfs_hash_from_cmdline(cmdline: Option<&str>) -> Result { @@ -840,14 +861,12 @@ pub fn rootfs_hash_from_cmdline(cmdline: Option<&str>) -> Result { )?)) } -/// Compute the AMD SEV-SNP `os_image_hash` from an OS image directory containing -/// `metadata.json` plus the SEV firmware, kernel and initrd. -/// -/// This is the canonical producer of `digest.sev.txt`. The value equals the -/// `os_image_hash` the KMS and verifier derive from a hardware-verified launch -/// measurement, because both go through [`snp_measurement_os_image_hash`] / -/// `dstack_types::SevOsImageMeasurement`. -pub fn sev_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { +/// Compute the AMD SEV-SNP image-invariant measurement projection from an OS +/// image directory containing `metadata.json` plus the SEV firmware, kernel and +/// initrd. +pub fn sev_os_image_measurement_for_image_dir( + image_dir: &Path, +) -> Result { let meta_path = image_dir.join("metadata.json"); let meta_str = fs::read_to_string(&meta_path) .with_context(|| format!("cannot read {}", meta_path.display()))?; @@ -862,13 +881,16 @@ pub fn sev_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { .or(meta.bios.as_deref()) .context("bios-sev/bios is required for amd sev-snp os_image_hash")?; let ovmf = ovmf_measurement_info(&image_dir.join(bios))?; + // Validate that the measured command line commits the rootfs identity. The + // compact image projection does not carry a separate rootfs_hash because it + // is already committed by `kernel_cmdline_sha256`. + rootfs_hash_from_cmdline(meta.cmdline.as_deref())?; - let measurement = dstack_types::SevOsImageMeasurement { - rootfs_hash: rootfs_hash_from_cmdline(meta.cmdline.as_deref())?, - base_cmdline: meta.cmdline.as_deref().map(|c| c.trim().to_string()), - ovmf_hash: ovmf.ovmf_hash, - kernel_hash: file_sha256_hex(&image_dir.join(&meta.kernel))?, - initrd_hash: file_sha256_hex(&image_dir.join(&meta.initrd))?, + Ok(dstack_types::SevOsImageMeasurement { + kernel_cmdline_sha256: kernel_cmdline_sha256(meta.cmdline.as_deref()), + ovmf_hash: decode_required_hex("ovmf_hash", &ovmf.ovmf_hash, 48)?, + kernel_hash: file_sha256(&image_dir.join(&meta.kernel))?, + initrd_hash: file_sha256(&image_dir.join(&meta.initrd))?, sev_hashes_table_gpa: ovmf.sev_hashes_table_gpa, sev_es_reset_eip: ovmf.sev_es_reset_eip, ovmf_sections: ovmf @@ -880,8 +902,27 @@ pub fn sev_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { section_type: s.section_type, }) .collect(), - }; - Ok(measurement.os_image_hash()) + }) +} + +/// Compute the AMD SEV-SNP `os_image_hash` from an OS image directory. +/// +/// This is the canonical legacy producer of `digest.sev.txt`. New images carry +/// the same value in `measurement.json.snp.os_image_hash`. The value equals the +/// `os_image_hash` the KMS and verifier derive from a hardware-verified launch +/// measurement, because both go through [`snp_measurement_os_image_hash`] / +/// `dstack_types::SevOsImageMeasurement`. +pub fn sev_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { + Ok(sev_os_image_measurement_for_image_dir(image_dir)?.os_image_hash()) +} + +/// Build the SNP section of `measurement.json`. +pub fn sev_os_image_measurement_document_for_image_dir( + image_dir: &Path, +) -> Result { + Ok(dstack_types::SevOsImageMeasurementDocument::new( + sev_os_image_measurement_for_image_dir(image_dir)?, + )) } /// `sha256(MEASUREMENT || HOST_DATA)` — the SNP aggregated identity digest. @@ -1313,13 +1354,13 @@ mod tests { "7f51e17f72a04d5422cb2c00998166536019a217376f3aa45a630e59c805a599847ff250dbffcd07e1ba639771d6f05d", ); - // os_image_hash derived from the same document must match the value the - // CVM advertised in its vm_config (and digest.sev.txt). + // os_image_hash derived from the same document must match the current + // measurement.json projection for these launch inputs. let os_image_hash = snp_measurement_os_image_hash(REAL_MEASUREMENT_DOC).expect("derive os_image_hash"); assert_eq!( hex::encode(os_image_hash), - "32b4767373ad7fa0f9c418925006194d5c3f5619529f309fe81156789fecd8bc", + "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda", ); } diff --git a/dstack-mr/src/tdvf.rs b/dstack-mr/src/tdvf.rs index f3791e8fc..90847a504 100644 --- a/dstack-mr/src/tdvf.rs +++ b/dstack-mr/src/tdvf.rs @@ -49,6 +49,136 @@ pub enum PageAddOrder { SinglePass, } +#[derive(Debug, Clone)] +pub(crate) struct AcpiTableHashes { + pub loader: Vec, + pub rsdp: Vec, + pub tables: Vec, +} + +pub(crate) fn rtmr0_log_from_td_hob_hash_with_acpi_hashes( + td_hob_hash: Vec, + ovmf_variant: OvmfVariant, + acpi_hashes: &AcpiTableHashes, +) -> Result { + let cfv_image_hash = hex!("344BC51C980BA621AAA00DA3ED7436F7D6E549197DFE699515DFA2C6583D95E6412AF21C097D473155875FFD561D6790"); + + let secureboot_hash = + measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "SecureBoot")?; + let pk_hash = measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "PK")?; + let kek_hash = measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "KEK")?; + let db_hash = measure_tdx_efi_variable("D719B2CB-3D3A-4596-A3BC-DAD00E67656F", "db")?; + let dbx_hash = measure_tdx_efi_variable("D719B2CB-3D3A-4596-A3BC-DAD00E67656F", "dbx")?; + let separator_hash = measure_sha384(&[0x00, 0x00, 0x00, 0x00]); + + let log = match ovmf_variant { + OvmfVariant::Pre202505 => { + // Boot0000 = OVMF UiApp (fixed digest for pre-202505 firmware). + let boot000_hash = hex!("23ADA07F5261F12F34A0BD8E46760962D6B4D576A416F1FEA1C64BC656B1D28EACF7047AE6E967C58FD2A98BFA74C298"); + vec![ + td_hob_hash, + cfv_image_hash.to_vec(), + secureboot_hash, + pk_hash, + kek_hash, + db_hash, + dbx_hash, + separator_hash, + acpi_hashes.loader.clone(), + acpi_hashes.rsdp.clone(), + acpi_hashes.tables.clone(), + measure_sha384(&[0x00, 0x00]), // BootOrder (raw 2 bytes in legacy OVMF) + boot000_hash.to_vec(), + ] + } + OvmfVariant::Stable202505 => { + // edk2-stable202505 emits 17 RTMR[0] events instead of 13. + // Everything except the three QEMU-generated ACPI blob digests is + // derivable from dstack's launch policy and the shipped OVMF build. + + // fw_cfg `BootMenu` is a u16; dstack doesn't pass `-boot + // menu=on`, so it defaults to 0x0000. + let bootmenu_fwcfg_hash = measure_sha384(&[0x00, 0x00]); + + // fw_cfg `bootorder` is the NUL-separated list of QEMU device + // paths whose backing devices have `bootindex` set. For + // `-kernel` boot, QEMU (hw/i386/x86.c::x86_load_linux) injects + // a single option ROM with `bootindex = 0`: + // * `linuxboot_dma.bin` if fw_cfg DMA is enabled (q35 default) + // * `linuxboot.bin` otherwise + // dstack-vmm always uses q35 → DMA is on → the bootorder file + // contains just the single path below (31 bytes, trailing NUL). + // No other dstack device gets an implicit bootindex. + // + // Verified end-to-end: gdb-attached the live QEMU and called + // get_boot_devices_list() — returned exactly these 31 bytes. + let bootorder_fwcfg_hash = measure_sha384(b"/rom@genroms/linuxboot_dma.bin\0"); + + // EV_EFI_VARIABLE_AUTHORITY: OVMF emits this once during BDS even + // when Secure Boot is disabled. The 32-byte event blob in the log is + // a sentinel; the actual measured payload is OVMF-internal. + // Captured digest is a constant for the edk2-stable202505 build + // dstack ships. + let variable_authority_hash = + hex!("FB66919801F1DFC9C4C273B6A739380790CB0FD3CB706A42F6AC050510EBC8618E7FBA53A1564522F5C6F0DC9E1F41A6"); + + // BootOrder UEFI variable holds [0x0000, 0x0001] — the two boot + // options OVMF's BDS publishes (UiApp and FrontPage). The TCG digest + // for `EV_EFI_VARIABLE_BOOT2` is over the raw variable data, NOT a + // UEFI_VARIABLE_DATA wrapper. + let boot_order_var_hash = measure_sha384(&boot_order_bytes(&[0x0000, 0x0001])); + + // Boot0000 = OVMF's BootManagerMenuApp; Boot0001 = "EFI Firmware + // Setup" (FrontPage). Both live in the OVMF FV and are baked into + // the firmware at build time. The attribute bits and descriptions + // come from MdeModulePkg's BdsBootManagerLib in edk2-stable202505. + // 0x101 = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_APP + // 0x109 = + LOAD_OPTION_HIDDEN + let boot0000_hash = measure_sha384(&boot_option_bytes( + 0x0000_0109, + "BootManagerMenuApp", + &[ + fv_node(&OVMF_FV_GUID_LE), + fv_file_node(&OVMF_UIAPP_FILE_GUID_LE), + END_OF_DEVICE_PATH, + ], + &[], + )); + let boot0001_hash = measure_sha384(&boot_option_bytes( + 0x0000_0101, + "EFI Firmware Setup", + &[ + fv_node(&OVMF_FV_GUID_LE), + fv_file_node(&OVMF_FRONTPAGE_FILE_GUID_LE), + END_OF_DEVICE_PATH, + ], + &[], + )); + vec![ + td_hob_hash, + cfv_image_hash.to_vec(), + bootmenu_fwcfg_hash, + bootorder_fwcfg_hash.to_vec(), + secureboot_hash, + pk_hash, + kek_hash, + db_hash, + dbx_hash, + separator_hash, + acpi_hashes.loader.clone(), + acpi_hashes.rsdp.clone(), + acpi_hashes.tables.clone(), + variable_authority_hash.to_vec(), + boot_order_var_hash, + boot0000_hash, + boot0001_hash, + ] + } + }; + + Ok(log) +} + /// Helper to decode little-endian integers from byte slice using scale codec fn decode_le(data: &[u8], context: &str) -> Result { T::decode(&mut &data[..]) @@ -279,6 +409,14 @@ impl<'a> Tdvf<'a> { Ok(h.finalize().to_vec()) } + pub(crate) fn mrtd_single_pass(&self) -> Result> { + self.compute_mrtd(PageAddOrder::SinglePass) + } + + pub(crate) fn mrtd_two_pass(&self) -> Result> { + self.compute_mrtd(PageAddOrder::TwoPass) + } + pub fn mrtd(&self, machine: &Machine) -> Result> { let opts = machine .versioned_options() @@ -290,6 +428,89 @@ impl<'a> Tdvf<'a> { }) } + /// Build the compact TdHobWitnessV1 byte string for this TDVF. + /// + /// The witness contains only the accepted TD HOB/TEMP_MEM ranges needed to + /// reconstruct the TD HOB for any VM memory size. All addresses/sizes are + /// represented in 4 KiB pages using unsigned LEB128 varints: + /// + /// varuint base_page + /// varuint td_hob_page_delta + /// varuint range_count + /// repeated range_count: + /// varuint start_page_delta + /// varuint page_count + /// + /// `base_page` is the minimum accepted range start page. Deltas are relative + /// to it. Ranges are sorted by start page and intentionally not merged; the + /// TD HOB measurement code emits adjacent accepted ranges as separate HOB + /// resources when TDVF metadata describes them separately. + pub(crate) fn td_hob_witness_v1(&self) -> Result> { + fn put_varuint(mut value: u64, out: &mut Vec) { + loop { + let mut byte = (value & 0x7f) as u8; + value >>= 7; + if value != 0 { + byte |= 0x80; + } + out.push(byte); + if value == 0 { + break; + } + } + } + + let mut ranges = Vec::<(u64, u64)>::new(); + let mut td_hob_page = None; + + for s in &self.sections { + if matches!(s.sec_type, TDVF_SECTION_TD_HOB | TDVF_SECTION_TEMP_MEM) { + let start_page = s.memory_address / PAGE_SIZE; + let page_count = s.memory_data_size / PAGE_SIZE; + if page_count == 0 { + bail!("TD HOB witness range must not be empty"); + } + ranges.push((start_page, page_count)); + } + if s.sec_type == TDVF_SECTION_TD_HOB { + if td_hob_page.replace(s.memory_address / PAGE_SIZE).is_some() { + bail!("TDVF metadata contains more than one TD_HOB section"); + } + } + } + + if ranges.is_empty() { + bail!("TDVF metadata has no TD_HOB/TEMP_MEM sections"); + } + let td_hob_page = td_hob_page.context("TDVF metadata is missing TD_HOB section")?; + + ranges.sort_by_key(|&(start_page, _)| start_page); + let mut prev_end = None; + for &(start_page, page_count) in &ranges { + if let Some(end) = prev_end { + if start_page < end { + bail!("TD HOB witness ranges must not overlap"); + } + } + prev_end = Some(start_page + page_count); + } + + let base_page = ranges[0].0; + if td_hob_page < base_page { + bail!("TD_HOB page is below TD HOB witness base page"); + } + + let mut out = Vec::with_capacity(4 + ranges.len() * 2); + put_varuint(base_page, &mut out); + put_varuint(td_hob_page - base_page, &mut out); + put_varuint(ranges.len() as u64, &mut out); + for (start_page, page_count) in ranges { + put_varuint(start_page - base_page, &mut out); + put_varuint(page_count, &mut out); + } + Ok(out) + } + #[allow(dead_code)] pub fn rtmr0(&self, machine: &Machine) -> Result> { let (rtmr0_log, _) = self.rtmr0_log(machine)?; @@ -297,135 +518,30 @@ impl<'a> Tdvf<'a> { } pub fn rtmr0_log(&self, machine: &Machine) -> Result<(RtmrLog, Tables)> { - let td_hob_hash = self.measure_td_hob(machine.memory_size)?; - let cfv_image_hash = hex!("344BC51C980BA621AAA00DA3ED7436F7D6E549197DFE699515DFA2C6583D95E6412AF21C097D473155875FFD561D6790"); - let tables = machine.build_tables()?; - let acpi_tables_hash = measure_sha384(&tables.tables); - let acpi_rsdp_hash = measure_sha384(&tables.rsdp); - let acpi_loader_hash = measure_sha384(&tables.loader); - - let secureboot_hash = - measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "SecureBoot")?; - let pk_hash = measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "PK")?; - let kek_hash = measure_tdx_efi_variable("8BE4DF61-93CA-11D2-AA0D-00E098032B8C", "KEK")?; - let db_hash = measure_tdx_efi_variable("D719B2CB-3D3A-4596-A3BC-DAD00E67656F", "db")?; - let dbx_hash = measure_tdx_efi_variable("D719B2CB-3D3A-4596-A3BC-DAD00E67656F", "dbx")?; - let separator_hash = measure_sha384(&[0x00, 0x00, 0x00, 0x00]); - - let log = match machine.ovmf_variant { - OvmfVariant::Pre202505 => { - // Boot0000 = OVMF UiApp (fixed digest for pre-202505 firmware). - let boot000_hash = hex!("23ADA07F5261F12F34A0BD8E46760962D6B4D576A416F1FEA1C64BC656B1D28EACF7047AE6E967C58FD2A98BFA74C298"); - vec![ - td_hob_hash, - cfv_image_hash.to_vec(), - secureboot_hash, - pk_hash, - kek_hash, - db_hash, - dbx_hash, - separator_hash, - acpi_loader_hash, - acpi_rsdp_hash, - acpi_tables_hash, - measure_sha384(&[0x00, 0x00]), // BootOrder (raw 2 bytes in legacy OVMF) - boot000_hash.to_vec(), - ] - } - OvmfVariant::Stable202505 => { - // edk2-stable202505 emits 17 RTMR[0] events instead of 13. The - // boot-option set is fully derivable from OVMF-internal - // constants (FV and file GUIDs, descriptions, attributes); the - // remaining two — the bootorder fw_cfg measurement and - // EV_EFI_VARIABLE_AUTHORITY — stay as captured digests because - // their content depends on QEMU's emitted device list and on - // OVMF-internal logic that's not worth shadowing here. - - // fw_cfg `BootMenu` is a u16; dstack doesn't pass `-boot - // menu=on`, so it defaults to 0x0000. - let bootmenu_fwcfg_hash = measure_sha384(&[0x00, 0x00]); - - // fw_cfg `bootorder` is the NUL-separated list of QEMU device - // paths whose backing devices have `bootindex` set. For - // `-kernel` boot, QEMU (hw/i386/x86.c::x86_load_linux) injects - // a single option ROM with `bootindex = 0`: - // * `linuxboot_dma.bin` if fw_cfg DMA is enabled (q35 default) - // * `linuxboot.bin` otherwise - // dstack-vmm always uses q35 → DMA is on → the bootorder file - // contains just the single path below (31 bytes, trailing - // NUL). No other dstack device gets an implicit bootindex. - // - // Verified end-to-end: gdb-attached the live QEMU and called - // get_boot_devices_list() — returned exactly these 31 bytes. - let bootorder_fwcfg_hash = measure_sha384(b"/rom@genroms/linuxboot_dma.bin\0"); - - // EV_EFI_VARIABLE_AUTHORITY: OVMF emits this once during BDS - // even when Secure Boot is disabled. The 32-byte event blob in - // the log is a sentinel; the actual measured payload is - // OVMF-internal. Captured digest is a constant for the - // edk2-stable202505 build dstack ships. - let variable_authority_hash = - hex!("FB66919801F1DFC9C4C273B6A739380790CB0FD3CB706A42F6AC050510EBC8618E7FBA53A1564522F5C6F0DC9E1F41A6"); - - // BootOrder UEFI variable holds [0x0000, 0x0001] — the two - // boot options OVMF's BDS publishes (UiApp and FrontPage). - // The TCG digest for `EV_EFI_VARIABLE_BOOT2` is over the raw - // variable data, NOT a UEFI_VARIABLE_DATA wrapper. - let boot_order_var_hash = measure_sha384(&boot_order_bytes(&[0x0000, 0x0001])); - - // Boot0000 = OVMF's BootManagerMenuApp; Boot0001 = "EFI - // Firmware Setup" (FrontPage). Both live in the OVMF FV and - // are baked into the firmware at build time. The attribute - // bits and descriptions come from MdeModulePkg's - // BdsBootManagerLib in edk2-stable202505. - // 0x101 = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_APP - // 0x109 = + LOAD_OPTION_HIDDEN - let boot0000_hash = measure_sha384(&boot_option_bytes( - 0x0000_0109, - "BootManagerMenuApp", - &[ - fv_node(&OVMF_FV_GUID_LE), - fv_file_node(&OVMF_UIAPP_FILE_GUID_LE), - END_OF_DEVICE_PATH, - ], - &[], - )); - let boot0001_hash = measure_sha384(&boot_option_bytes( - 0x0000_0101, - "EFI Firmware Setup", - &[ - fv_node(&OVMF_FV_GUID_LE), - fv_file_node(&OVMF_FRONTPAGE_FILE_GUID_LE), - END_OF_DEVICE_PATH, - ], - &[], - )); - vec![ - td_hob_hash, - cfv_image_hash.to_vec(), - bootmenu_fwcfg_hash, - bootorder_fwcfg_hash.to_vec(), - secureboot_hash, - pk_hash, - kek_hash, - db_hash, - dbx_hash, - separator_hash, - acpi_loader_hash, - acpi_rsdp_hash, - acpi_tables_hash, - variable_authority_hash.to_vec(), - boot_order_var_hash, - boot0000_hash, - boot0001_hash, - ] - } + let acpi_hashes = AcpiTableHashes { + tables: measure_sha384(&tables.tables), + rsdp: measure_sha384(&tables.rsdp), + loader: measure_sha384(&tables.loader), }; - + let log = self.rtmr0_log_with_acpi_hashes( + machine.memory_size, + machine.ovmf_variant, + &acpi_hashes, + )?; Ok((log, tables)) } + pub(crate) fn rtmr0_log_with_acpi_hashes( + &self, + memory_size: u64, + ovmf_variant: OvmfVariant, + acpi_hashes: &AcpiTableHashes, + ) -> Result { + let td_hob_hash = self.measure_td_hob(memory_size)?; + rtmr0_log_from_td_hob_hash_with_acpi_hashes(td_hob_hash, ovmf_variant, acpi_hashes) + } + fn measure_td_hob(&self, memory_size: u64) -> Result> { let mut memory_acceptor = MemoryAcceptor::new(0, memory_size); let mut td_hob = Vec::new(); @@ -533,3 +649,55 @@ impl MemoryAcceptor { self.ranges = new_ranges; } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn td_hob_witness_v1_encodes_current_dstack_ranges_compactly() -> Result<()> { + let tdvf = Tdvf { + fw: &[], + sections: vec![ + TdvfSection { + data_offset: 0, + raw_data_size: 0, + memory_address: 0x810000, + memory_data_size: 0x10000, + sec_type: TDVF_SECTION_TEMP_MEM, + attributes: 0, + }, + TdvfSection { + data_offset: 0, + raw_data_size: 0, + memory_address: 0x80b000, + memory_data_size: 0x2000, + sec_type: TDVF_SECTION_TEMP_MEM, + attributes: 0, + }, + TdvfSection { + data_offset: 0, + raw_data_size: 0, + memory_address: 0x809000, + memory_data_size: 0x2000, + sec_type: TDVF_SECTION_TD_HOB, + attributes: 0, + }, + TdvfSection { + data_offset: 0, + raw_data_size: 0, + memory_address: 0x800000, + memory_data_size: 0x6000, + sec_type: TDVF_SECTION_TEMP_MEM, + attributes: 0, + }, + ], + }; + + assert_eq!( + hex::encode(tdvf.td_hob_witness_v1()?), + "80100904000609020b021010" + ); + Ok(()) + } +} diff --git a/dstack-mr/src/tdx.rs b/dstack-mr/src/tdx.rs new file mode 100644 index 000000000..c7406309a --- /dev/null +++ b/dstack-mr/src/tdx.rs @@ -0,0 +1,625 @@ +// SPDX-FileCopyrightText: © 2026 Phala Network +// +// SPDX-License-Identifier: Apache-2.0 + +//! Build-time TDX OS-image static measurement material. +//! +//! The current verifier path recomputes TDX MRs from a downloaded image. This +//! module emits the image-static material needed by the no-image-download path: +//! MRTD candidates, compact TD HOB witness, command line, kernel/initrd digests +//! and sizes. VM-specific inputs (RAM size, vCPU count, QEMU topology knobs) are +//! intentionally excluded and must come from `VmConfig`. + +use crate::kernel::{ + patched_kernel_authenticode_sha384, tdx_kernel_hash_uses_precomputed_high_mem, + TDX_KERNEL_HASH_COMPAT_2G_MEMORY, TDX_KERNEL_HASH_STABLE_MIN_MEMORY, +}; +use crate::tdvf::{rtmr0_log_from_td_hob_hash_with_acpi_hashes, AcpiTableHashes, Tdvf}; +use crate::util::{measure_log, measure_sha384}; +use anyhow::{bail, Context, Result}; +use dstack_types::{ + OvmfVariant, TdxImageMeasurement, TdxMrtdCandidates, TdxOsImageMeasurement, + TdxOsImageMeasurementDocument, TdxTdvfMeasurement, VmConfig, +}; +use fs_err as fs; +use serde::Deserialize; +use std::path::Path; + +#[derive(Debug, Deserialize)] +struct ImageMetadata { + #[serde(default)] + cmdline: Option, + kernel: String, + initrd: String, + bios: String, + #[serde(default)] + version: String, + #[serde(default)] + ovmf_variant: Option, +} + +#[derive(Debug, Clone)] +pub struct TdxRtmr0AcpiHashes { + pub loader: Vec, + pub rsdp: Vec, + pub tables: Vec, +} + +#[derive(Debug, Clone)] +pub struct TdxMeasurementsWithoutRtmr0 { + pub mrtd: Vec, + pub rtmr1: Vec, + pub rtmr2: Vec, +} + +fn validate_bytes_field(value: &[u8], field: &str, expected_len: usize) -> Result> { + if value.len() != expected_len { + bail!( + "{field} has invalid length {}, expected {expected_len}", + value.len() + ); + } + Ok(value.to_vec()) +} + +fn select_mrtd(measurement: &TdxOsImageMeasurement, vm_config: &VmConfig) -> Result> { + let machine = crate::Machine::builder() + .cpu_count(vm_config.cpu_count) + .memory_size(vm_config.memory_size) + .firmware("") + .kernel("") + .initrd("") + .kernel_cmdline("") + .root_verity(true) + .hotplug_off(vm_config.hotplug_off) + .maybe_two_pass_add_pages(vm_config.qemu_single_pass_add_pages) + .maybe_pic(vm_config.pic) + .maybe_qemu_version(vm_config.qemu_version.clone()) + .maybe_pci_hole64_size(if vm_config.pci_hole64_size > 0 { + Some(vm_config.pci_hole64_size) + } else { + None + }) + .hugepages(vm_config.hugepages) + .num_gpus(vm_config.num_gpus) + .num_nvswitches(vm_config.num_nvswitches) + .host_share_mode(vm_config.host_share_mode.clone()) + .ovmf_variant(measurement.tdvf.ovmf_variant) + .build(); + let opts = machine + .versioned_options() + .context("failed to resolve QEMU measurement options")?; + let mrtd = if opts.two_pass_add_pages { + &measurement.tdvf.mrtd.two_pass + } else { + &measurement.tdvf.mrtd.single_pass + }; + validate_bytes_field(mrtd, "tdx.measurement.tdvf.mrtd", 48) +} + +fn read_varuint(input: &mut &[u8]) -> Result { + let mut value = 0u64; + let mut shift = 0u32; + loop { + let (&byte, rest) = input + .split_first() + .context("truncated TD HOB witness varuint")?; + *input = rest; + value |= ((byte & 0x7f) as u64) << shift; + if byte & 0x80 == 0 { + return Ok(value); + } + shift += 7; + if shift >= 64 { + bail!("TD HOB witness varuint is too large"); + } + } +} + +fn measure_td_hob_from_witness_data(data: &[u8], memory_size: u64) -> Result> { + let mut input = data; + let base_page = read_varuint(&mut input)?; + let td_hob_page_delta = read_varuint(&mut input)?; + let range_count = read_varuint(&mut input)?; + let td_hob_base_addr = (base_page + td_hob_page_delta) + .checked_mul(0x1000) + .context("TD HOB base address overflow")?; + + let mut memory_acceptor = MemoryAcceptor::new(0, memory_size); + for _ in 0..range_count { + let start_page_delta = read_varuint(&mut input)?; + let page_count = read_varuint(&mut input)?; + let start = (base_page + start_page_delta) + .checked_mul(0x1000) + .context("TD HOB range start overflow")?; + let len = page_count + .checked_mul(0x1000) + .context("TD HOB range length overflow")?; + memory_acceptor.accept(start, start + len); + } + if !input.is_empty() { + bail!("TD HOB witness has trailing bytes"); + } + + let mut td_hob = Vec::new(); + td_hob.extend_from_slice(&[0x01, 0x00]); // HobType + td_hob.extend_from_slice(&56u16.to_le_bytes()); // HobLength + td_hob.extend_from_slice(&[0u8; 4]); // Reserved + td_hob.extend_from_slice(&9u32.to_le_bytes()); // Version + td_hob.extend_from_slice(&[0u8; 4]); // BootMode + td_hob.extend_from_slice(&[0u8; 8]); // EfiMemoryTop + td_hob.extend_from_slice(&[0u8; 8]); // EfiMemoryBottom + td_hob.extend_from_slice(&[0u8; 8]); // EfiFreeMemoryTop + td_hob.extend_from_slice(&[0u8; 8]); // EfiFreeMemoryBottom + td_hob.extend_from_slice(&[0u8; 8]); // EfiEndOfHobList (placeholder) + + let mut add_memory_resource_hob = |resource_type: u8, start: u64, length: u64| { + td_hob.extend_from_slice(&[0x03, 0x00]); // HobType + td_hob.extend_from_slice(&48u16.to_le_bytes()); // HobLength + td_hob.extend_from_slice(&[0u8; 4]); // Reserved + td_hob.extend_from_slice(&[0u8; 16]); // Owner + td_hob.extend_from_slice(&resource_type.to_le_bytes()); + td_hob.extend_from_slice(&[0u8; 3]); // Padding for resource type + td_hob.extend_from_slice(&7u32.to_le_bytes()); // ResourceAttribute + td_hob.extend_from_slice(&start.to_le_bytes()); + td_hob.extend_from_slice(&length.to_le_bytes()); + }; + + let (_, last_start, last_end) = memory_acceptor.ranges.pop().context("No ranges")?; + + for (accepted, start, end) in memory_acceptor.ranges { + if end < start { + bail!("Invalid memory range: end < start"); + } + let size = end - start; + if accepted { + add_memory_resource_hob(0x00, start, size); + } else { + add_memory_resource_hob(0x07, start, size); + } + } + + if last_end < last_start { + bail!("Invalid last memory range: end < start"); + } + if memory_size >= TDX_KERNEL_HASH_STABLE_MIN_MEMORY { + if last_start < 0x80000000u64 { + add_memory_resource_hob(0x07, last_start, 0x80000000u64 - last_start); + } + if last_end > 0x80000000u64 { + add_memory_resource_hob(0x07, 0x100000000, last_end - 0x80000000u64); + } + } else { + add_memory_resource_hob(0x07, last_start, last_end - last_start); + } + + let end_of_hob_list = td_hob_base_addr + td_hob.len() as u64 + 8; + td_hob[48..56].copy_from_slice(&end_of_hob_list.to_le_bytes()); + + Ok(measure_sha384(&td_hob)) +} + +struct MemoryAcceptor { + ranges: Vec<(bool, u64, u64)>, +} + +impl MemoryAcceptor { + fn new(start: u64, size: u64) -> Self { + Self { + ranges: vec![(false, start, start + size)], + } + } + + fn accept(&mut self, start: u64, end: u64) { + if start >= end { + return; + } + + let mut new_ranges = Vec::new(); + + for &(is_accepted, range_start, range_end) in &self.ranges { + if is_accepted || range_end <= start || range_start >= end { + new_ranges.push((is_accepted, range_start, range_end)); + } else { + if range_start < start { + new_ranges.push((false, range_start, start)); + } + if range_end > end { + new_ranges.push((false, end, range_end)); + } + } + } + new_ranges.push((true, start, end)); + new_ranges.sort_by_key(|&(_, start, _)| start); + self.ranges = new_ranges; + } +} + +fn rtmr1_log_from_kernel_hash(kernel_hash: Vec) -> Vec> { + vec![ + kernel_hash, + measure_sha384(b"Calling EFI Application from Boot Option"), + measure_sha384(&[0x00, 0x00, 0x00, 0x00]), // Separator + measure_sha384(b"Exit Boot Services Invocation"), + measure_sha384(b"Exit Boot Services Returned with Success"), + ] +} + +/// Return the measured TDX kernel command line for a metadata cmdline. +/// +/// This mirrors the existing dstack TDX measurement replay path, which measures +/// the image-provided cmdline plus OVMF/QEMU's `initrd=initrd` suffix. +pub fn measured_kernel_cmdline(base_cmdline: &str) -> String { + format!("{base_cmdline} initrd=initrd") +} + +/// Generate the image-static TDX measurement material from an image directory. +pub fn tdx_os_image_measurement_for_image_dir(image_dir: &Path) -> Result { + let meta_path = image_dir.join("metadata.json"); + let meta_str = fs::read_to_string(&meta_path) + .with_context(|| format!("cannot read {}", meta_path.display()))?; + let meta: ImageMetadata = + serde_json::from_str(&meta_str).context("failed to parse image metadata.json")?; + + let base_cmdline = meta + .cmdline + .filter(|s| !s.trim().is_empty()) + .context("metadata.json cmdline is required for TDX os_image_hash")? + .to_string(); + + // Validate that the image identity carried by the measured cmdline is + // well-formed. The normalized rootfs hash is not stored separately to keep + // the TDX projection compact; it is already committed by the measured + // kernel command line digest. + crate::sev::rootfs_hash_from_cmdline(Some(&base_cmdline)) + .context("failed to parse dstack.rootfs_hash from TDX cmdline")?; + + let ovmf_variant = meta + .ovmf_variant + .or_else(|| { + if meta.version.is_empty() { + None + } else { + crate::ovmf_variant_for_version(&meta.version).ok() + } + }) + .unwrap_or_default(); + + let fw_data = fs::read(image_dir.join(&meta.bios)) + .with_context(|| format!("cannot read {}", image_dir.join(&meta.bios).display()))?; + let tdvf = Tdvf::parse(&fw_data).context("failed to parse TDX TDVF metadata")?; + + let initrd_path = image_dir.join(&meta.initrd); + let initrd = + fs::read(&initrd_path).with_context(|| format!("cannot read {}", initrd_path.display()))?; + let kernel_path = image_dir.join(&meta.kernel); + let kernel = + fs::read(&kernel_path).with_context(|| format!("cannot read {}", kernel_path.display()))?; + let kernel_authenticode = patched_kernel_authenticode_sha384( + &kernel, + initrd.len() as u32, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY, + 0x28000, + ) + .context("failed to compute high-memory QEMU-patched kernel hash")?; + + Ok(TdxOsImageMeasurement { + image: TdxImageMeasurement { + kernel_cmdline_sha384: crate::kernel::measure_cmdline(&measured_kernel_cmdline( + &base_cmdline, + )), + kernel_authenticode, + initrd_sha384: measure_sha384(&initrd), + }, + tdvf: TdxTdvfMeasurement { + ovmf_variant, + mrtd: TdxMrtdCandidates { + single_pass: tdvf.mrtd_single_pass()?, + two_pass: tdvf.mrtd_two_pass()?, + }, + td_hob_witness: tdvf.td_hob_witness_v1()?, + }, + }) +} + +/// Generate the self-contained TDX measurement document for an image directory. +/// +/// The document contains both the hash projection and the resulting +/// `os_image_hash`, avoiding a separate `digest.tdx.txt` artifact. +pub fn tdx_os_image_measurement_document_for_image_dir( + image_dir: &Path, +) -> Result { + Ok(TdxOsImageMeasurementDocument::new( + tdx_os_image_measurement_for_image_dir(image_dir)?, + )) +} + +/// Compute the TDX static-material OS image hash for an image directory. +pub fn tdx_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { + Ok(tdx_os_image_measurement_for_image_dir(image_dir)?.os_image_hash()) +} + +/// Compute expected TDX measurements from the self-contained `measurement.json` +/// TDX document and the three ACPI table digests captured in RTMR[0]. +/// +/// This path intentionally does not download or read the OS image. Because +/// QEMU's patched kernel Authenticode hash depends on exact guest RAM below +/// `TDX_KERNEL_HASH_STABLE_MIN_MEMORY`, the no-image-download path supports +/// CVMs at or above that threshold plus the exact 2 GiB placement, which QEMU +/// patches to the same kernel bytes as the high-memory case. +pub fn tdx_measurements_from_measurement_document( + document: &TdxOsImageMeasurementDocument, + vm_config: &VmConfig, + acpi_hashes: &TdxRtmr0AcpiHashes, +) -> Result { + if document.version != TdxOsImageMeasurementDocument::VERSION { + bail!( + "unsupported TDX measurement document version {}", + document.version + ); + } + if !tdx_kernel_hash_uses_precomputed_high_mem(vm_config.memory_size) { + bail!( + "TDX measurement attestation without image download requires memory_size == {} bytes ({} MiB) or >= {} bytes ({} MiB); got {} bytes", + TDX_KERNEL_HASH_COMPAT_2G_MEMORY, + TDX_KERNEL_HASH_COMPAT_2G_MEMORY / 1024 / 1024, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY, + TDX_KERNEL_HASH_STABLE_MIN_MEMORY / 1024 / 1024, + vm_config.memory_size + ); + } + + let measurement = document + .decode_measurement() + .map_err(anyhow::Error::msg) + .context("failed to decode TDX measurement CBOR")?; + let mrtd = select_mrtd(&measurement, vm_config)?; + + let td_hob_hash = + measure_td_hob_from_witness_data(&measurement.tdvf.td_hob_witness, vm_config.memory_size) + .context("failed to measure TD HOB from witness")?; + let rtmr0_log = rtmr0_log_from_td_hob_hash_with_acpi_hashes( + td_hob_hash, + measurement.tdvf.ovmf_variant, + &AcpiTableHashes { + loader: acpi_hashes.loader.clone(), + rsdp: acpi_hashes.rsdp.clone(), + tables: acpi_hashes.tables.clone(), + }, + ) + .context("failed to compute RTMR0 from measurement document")?; + let rtmr0 = measure_log(&rtmr0_log); + + let kernel_hash = validate_bytes_field( + &measurement.image.kernel_authenticode, + "tdx.measurement.image.kernel_authenticode", + 48, + )?; + let rtmr1 = measure_log(&rtmr1_log_from_kernel_hash(kernel_hash)); + + let initrd_hash = validate_bytes_field( + &measurement.image.initrd_sha384, + "tdx.measurement.image.initrd_sha384", + 48, + )?; + let kernel_cmdline_hash = validate_bytes_field( + &measurement.image.kernel_cmdline_sha384, + "tdx.measurement.image.kernel_cmdline_sha384", + 48, + )?; + let rtmr2 = measure_log(&[kernel_cmdline_hash, initrd_hash]); + + Ok(crate::TdxMeasurements { + mrtd, + rtmr0, + rtmr1, + rtmr2, + }) +} + +/// Compute image-critical TDX measurements without RTMR[0]. +/// +/// RTMR[0] contains QEMU-generated ACPI blobs and other launch-environment +/// material. This helper verifies the OS-image binding pieces that do not need +/// QEMU: MRTD (TDVF firmware), RTMR[1] (QEMU-patched kernel image), and RTMR[2] +/// (kernel command line + initrd). +pub fn tdx_measurements_for_image_dir_without_rtmr0( + image_dir: &Path, + vm_config: &VmConfig, +) -> Result { + let meta_path = image_dir.join("metadata.json"); + let meta_str = fs::read_to_string(&meta_path) + .with_context(|| format!("cannot read {}", meta_path.display()))?; + let meta: ImageMetadata = + serde_json::from_str(&meta_str).context("failed to parse image metadata.json")?; + + let base_cmdline = meta + .cmdline + .filter(|s| !s.trim().is_empty()) + .context("metadata.json cmdline is required for TDX measurement")? + .to_string(); + let kernel_cmdline = measured_kernel_cmdline(&base_cmdline); + + let firmware_path = image_dir.join(&meta.bios); + let kernel_path = image_dir.join(&meta.kernel); + let initrd_path = image_dir.join(&meta.initrd); + + let fw_data = fs::read(&firmware_path) + .with_context(|| format!("cannot read {}", firmware_path.display()))?; + let kernel_data = + fs::read(&kernel_path).with_context(|| format!("cannot read {}", kernel_path.display()))?; + let initrd_data = + fs::read(&initrd_path).with_context(|| format!("cannot read {}", initrd_path.display()))?; + + let ovmf_variant = vm_config + .ovmf_variant + .or(meta.ovmf_variant) + .or_else(|| { + if meta.version.is_empty() { + None + } else { + crate::ovmf_variant_for_version(&meta.version).ok() + } + }) + .unwrap_or_else(|| crate::ovmf_variant_for_image(vm_config.image.as_deref())); + + let firmware = firmware_path.display().to_string(); + let kernel = kernel_path.display().to_string(); + let initrd = initrd_path.display().to_string(); + let machine = crate::Machine::builder() + .cpu_count(vm_config.cpu_count) + .memory_size(vm_config.memory_size) + .firmware(&firmware) + .kernel(&kernel) + .initrd(&initrd) + .kernel_cmdline(&kernel_cmdline) + .root_verity(true) + .hotplug_off(vm_config.hotplug_off) + .maybe_two_pass_add_pages(vm_config.qemu_single_pass_add_pages) + .maybe_pic(vm_config.pic) + .maybe_qemu_version(vm_config.qemu_version.clone()) + .maybe_pci_hole64_size(if vm_config.pci_hole64_size > 0 { + Some(vm_config.pci_hole64_size) + } else { + None + }) + .hugepages(vm_config.hugepages) + .num_gpus(vm_config.num_gpus) + .num_nvswitches(vm_config.num_nvswitches) + .host_share_mode(vm_config.host_share_mode.clone()) + .ovmf_variant(ovmf_variant) + .build(); + + let tdvf = Tdvf::parse(&fw_data).context("failed to parse TDX TDVF metadata")?; + let mrtd = tdvf.mrtd(&machine).context("failed to compute MRTD")?; + + let rtmr1_log = crate::kernel::rtmr1_log( + &kernel_data, + initrd_data.len() as u32, + vm_config.memory_size, + 0x28000, + ) + .context("failed to compute RTMR1")?; + let rtmr1 = measure_log(&rtmr1_log); + + let rtmr2_log = vec![ + crate::kernel::measure_cmdline(&kernel_cmdline), + measure_sha384(&initrd_data), + ]; + let rtmr2 = measure_log(&rtmr2_log); + + Ok(TdxMeasurementsWithoutRtmr0 { mrtd, rtmr1, rtmr2 }) +} + +/// Compute TDX measurements without invoking QEMU-derived helper binaries. +/// +/// RTMR[0] includes ACPI blobs generated by QEMU at launch time. The caller +/// supplies the already-measured ACPI event digests from the hardware-bound +/// event log; this function recomputes the rest of the TDX image measurement +/// from image files and VM configuration. +pub fn tdx_measurements_for_image_dir_with_acpi_hashes( + image_dir: &Path, + vm_config: &VmConfig, + acpi_hashes: &TdxRtmr0AcpiHashes, +) -> Result { + let meta_path = image_dir.join("metadata.json"); + let meta_str = fs::read_to_string(&meta_path) + .with_context(|| format!("cannot read {}", meta_path.display()))?; + let meta: ImageMetadata = + serde_json::from_str(&meta_str).context("failed to parse image metadata.json")?; + + let base_cmdline = meta + .cmdline + .filter(|s| !s.trim().is_empty()) + .context("metadata.json cmdline is required for TDX measurement")? + .to_string(); + let kernel_cmdline = measured_kernel_cmdline(&base_cmdline); + + let firmware_path = image_dir.join(&meta.bios); + let kernel_path = image_dir.join(&meta.kernel); + let initrd_path = image_dir.join(&meta.initrd); + + let fw_data = fs::read(&firmware_path) + .with_context(|| format!("cannot read {}", firmware_path.display()))?; + let kernel_data = + fs::read(&kernel_path).with_context(|| format!("cannot read {}", kernel_path.display()))?; + let initrd_data = + fs::read(&initrd_path).with_context(|| format!("cannot read {}", initrd_path.display()))?; + + let ovmf_variant = vm_config + .ovmf_variant + .or(meta.ovmf_variant) + .or_else(|| { + if meta.version.is_empty() { + None + } else { + crate::ovmf_variant_for_version(&meta.version).ok() + } + }) + .unwrap_or_else(|| crate::ovmf_variant_for_image(vm_config.image.as_deref())); + + let firmware = firmware_path.display().to_string(); + let kernel = kernel_path.display().to_string(); + let initrd = initrd_path.display().to_string(); + let machine = crate::Machine::builder() + .cpu_count(vm_config.cpu_count) + .memory_size(vm_config.memory_size) + .firmware(&firmware) + .kernel(&kernel) + .initrd(&initrd) + .kernel_cmdline(&kernel_cmdline) + .root_verity(true) + .hotplug_off(vm_config.hotplug_off) + .maybe_two_pass_add_pages(vm_config.qemu_single_pass_add_pages) + .maybe_pic(vm_config.pic) + .maybe_qemu_version(vm_config.qemu_version.clone()) + .maybe_pci_hole64_size(if vm_config.pci_hole64_size > 0 { + Some(vm_config.pci_hole64_size) + } else { + None + }) + .hugepages(vm_config.hugepages) + .num_gpus(vm_config.num_gpus) + .num_nvswitches(vm_config.num_nvswitches) + .host_share_mode(vm_config.host_share_mode.clone()) + .ovmf_variant(ovmf_variant) + .build(); + + let tdvf = Tdvf::parse(&fw_data).context("failed to parse TDX TDVF metadata")?; + let mrtd = tdvf.mrtd(&machine).context("failed to compute MRTD")?; + + let rtmr0_log = tdvf + .rtmr0_log_with_acpi_hashes( + vm_config.memory_size, + ovmf_variant, + &AcpiTableHashes { + loader: acpi_hashes.loader.clone(), + rsdp: acpi_hashes.rsdp.clone(), + tables: acpi_hashes.tables.clone(), + }, + ) + .context("failed to compute RTMR0 without ACPI table generation")?; + let rtmr0 = measure_log(&rtmr0_log); + + let rtmr1_log = crate::kernel::rtmr1_log( + &kernel_data, + initrd_data.len() as u32, + vm_config.memory_size, + 0x28000, + ) + .context("failed to compute RTMR1")?; + let rtmr1 = measure_log(&rtmr1_log); + + let rtmr2_log = vec![ + crate::kernel::measure_cmdline(&kernel_cmdline), + measure_sha384(&initrd_data), + ]; + let rtmr2 = measure_log(&rtmr2_log); + + Ok(crate::TdxMeasurements { + mrtd, + rtmr0, + rtmr1, + rtmr2, + }) +} diff --git a/dstack-types/Cargo.toml b/dstack-types/Cargo.toml index 1bea45ec5..526d5192b 100644 --- a/dstack-types/Cargo.toml +++ b/dstack-types/Cargo.toml @@ -10,6 +10,8 @@ edition.workspace = true license.workspace = true [dependencies] +ciborium.workspace = true +hex = { workspace = true, features = ["std"] } or-panic.workspace = true scale = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } diff --git a/dstack-types/src/lib.rs b/dstack-types/src/lib.rs index d891eee93..cac0313c1 100644 --- a/dstack-types/src/lib.rs +++ b/dstack-types/src/lib.rs @@ -2,9 +2,8 @@ // // SPDX-License-Identifier: Apache-2.0 -use std::path::Path; +use std::{io::Cursor, path::Path}; -use or_panic::ResultOrPanic; use scale::{Decode, Encode}; use serde::{Deserialize, Serialize}; use serde_human_bytes as hex_bytes; @@ -34,6 +33,52 @@ pub enum OvmfVariant { Stable202505, } +impl OvmfVariant { + pub fn to_u8(self) -> u8 { + match self { + Self::Pre202505 => 0, + Self::Stable202505 => 1, + } + } + + pub fn from_u8(value: u8) -> Option { + match value { + 0 => Some(Self::Pre202505), + 1 => Some(Self::Stable202505), + _ => None, + } + } +} + +/// Selects how a TDX attestation should bind the OS image. +/// +/// `Legacy` preserves the existing verifier behavior: `vm_config.os_image_hash` +/// is the content digest (`digest.txt`) and the verifier recomputes the full +/// TDX launch measurement using the legacy image/QEMU-derived path. +/// +/// `Measurement` opts into the no-QEMU verifier path: `vm_config.os_image_hash` +/// is `measurement.json.tdx.os_image_hash`, `vm_config.tdx_measurement` carries +/// the self-contained measurement material, and KMS/verifier select the new +/// logic from this vm_config flag while the attestation quote remains the +/// existing `DstackTdx`. +#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, Default)] +#[serde(rename_all = "snake_case")] +pub enum TdxAttestationVariant { + #[default] + Legacy, + Measurement, +} + +impl TdxAttestationVariant { + pub fn is_legacy(&self) -> bool { + matches!(self, Self::Legacy) + } + + pub fn is_measurement(&self) -> bool { + matches!(self, Self::Measurement) + } +} + #[derive(Deserialize, Serialize, Debug, Clone)] pub struct AppCompose { pub manifest_version: u32, @@ -259,6 +304,14 @@ pub struct VmConfig { /// (e.g. parsing the OS version out of `image`). #[serde(default, skip_serializing_if = "Option::is_none")] pub ovmf_variant: Option, + /// TDX-only attestation/hash scheme selector. Defaults to `legacy` and is + /// omitted from legacy configs to keep old behavior and wire shape stable. + #[serde(default, skip_serializing_if = "TdxAttestationVariant::is_legacy")] + pub tdx_attestation_variant: TdxAttestationVariant, + /// TDX-only no-image-download measurement material. Present only when + /// `tdx_attestation_variant = "measurement"` and omitted for legacy TDX. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tdx_measurement: Option, } /// One OVMF SEV metadata section (gpa/size/type) that affects the SEV-SNP @@ -270,34 +323,422 @@ pub struct OvmfSection { pub section_type: u32, } -/// Image-invariant projection that determines the AMD SEV-SNP OS image identity. -/// -/// `os_image_hash` is the SHA-256 of this projection, canonically serialized -/// (JCS). It is shared by the VMM/KMS (which derive it from a verified launch -/// measurement) and the image build (which precomputes `digest.sev.txt`), so -/// both sides agree. It deliberately EXCLUDES per-deployment values (vcpus, -/// vcpu_type, guest_features, app_id, compose_hash): the same OS image must hash +fn cbor_to_vec(value: &T, context: &str) -> Vec { + let mut out = Vec::new(); + ciborium::ser::into_writer(value, &mut out) + .unwrap_or_else(|e| panic!("{context}: failed to encode CBOR: {e}")); + out +} + +fn cbor_from_slice( + bytes: &[u8], + context: &str, +) -> Result { + ciborium::de::from_reader(Cursor::new(bytes)) + .map_err(|e| format!("{context}: failed to decode CBOR: {e}")) +} + +fn sha256(bytes: &[u8]) -> [u8; 32] { + use sha2::{Digest, Sha256}; + Sha256::digest(bytes).into() +} + +fn sha256_hex(bytes: &[u8]) -> String { + hex::encode(sha256(bytes)) +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborOvmfSection { + gpa: u64, + size: u64, + #[serde(rename = "type")] + section_type: u32, +} + +impl From<&OvmfSection> for CborOvmfSection { + fn from(section: &OvmfSection) -> Self { + Self { + gpa: section.gpa, + size: section.size, + section_type: section.section_type, + } + } +} + +impl From for OvmfSection { + fn from(section: CborOvmfSection) -> Self { + Self { + gpa: section.gpa, + size: section.size, + section_type: section.section_type, + } + } +} + +/// Image-invariant projection that determines the AMD SEV-SNP OS image +/// identity. It deliberately excludes per-deployment values (vcpus, vcpu_type, +/// guest_features, app_id, compose_hash): the same OS image must hash /// identically regardless of how it is launched. +/// +/// `os_image_hash` is SHA-256 over the CBOR representation of this projection, +/// not over the outer measurement.json field names. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SevOsImageMeasurement { - pub rootfs_hash: String, - pub base_cmdline: Option, - pub ovmf_hash: String, - pub kernel_hash: String, - pub initrd_hash: String, + /// SHA-256 of the kernel command line bytes as measured in the SEV-SNP hash + /// table (trimmed command line plus trailing NUL byte). This avoids carrying + /// the full plaintext command line in image metadata while preserving the + /// exact measured value used by OVMF/QEMU. + #[serde(with = "hex_bytes")] + pub kernel_cmdline_sha256: Vec, + #[serde(with = "hex_bytes")] + pub ovmf_hash: Vec, + #[serde(with = "hex_bytes")] + pub kernel_hash: Vec, + #[serde(with = "hex_bytes")] + pub initrd_hash: Vec, pub sev_hashes_table_gpa: u64, pub sev_es_reset_eip: u32, pub ovmf_sections: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborSevOsImageMeasurement { + /// Measured kernel cmdline SHA-256. + #[serde(rename = "cmdline_sha256", with = "hex_bytes")] + kernel_cmdline_sha256: Vec, + /// OVMF launch digest. + #[serde(with = "hex_bytes")] + ovmf_hash: Vec, + /// Kernel SHA-256. + #[serde(with = "hex_bytes")] + kernel_hash: Vec, + /// Initrd SHA-256. + #[serde(with = "hex_bytes")] + initrd_hash: Vec, + /// SEV hash table GPA. + hashes_table_gpa: u64, + /// SEV-ES AP reset EIP. + reset_eip: u32, + /// OVMF metadata sections. + ovmf_sections: Vec, +} + +impl From<&SevOsImageMeasurement> for CborSevOsImageMeasurement { + fn from(measurement: &SevOsImageMeasurement) -> Self { + Self { + kernel_cmdline_sha256: measurement.kernel_cmdline_sha256.clone(), + ovmf_hash: measurement.ovmf_hash.clone(), + kernel_hash: measurement.kernel_hash.clone(), + initrd_hash: measurement.initrd_hash.clone(), + hashes_table_gpa: measurement.sev_hashes_table_gpa, + reset_eip: measurement.sev_es_reset_eip, + ovmf_sections: measurement.ovmf_sections.iter().map(Into::into).collect(), + } + } +} + +impl From for SevOsImageMeasurement { + fn from(measurement: CborSevOsImageMeasurement) -> Self { + Self { + kernel_cmdline_sha256: measurement.kernel_cmdline_sha256, + ovmf_hash: measurement.ovmf_hash, + kernel_hash: measurement.kernel_hash, + initrd_hash: measurement.initrd_hash, + sev_hashes_table_gpa: measurement.hashes_table_gpa, + sev_es_reset_eip: measurement.reset_eip, + ovmf_sections: measurement + .ovmf_sections + .into_iter() + .map(Into::into) + .collect(), + } + } +} + impl SevOsImageMeasurement { - /// SHA-256 over the canonical (JCS) serialization of this projection. + /// CBOR representation used as the `os_image_hash` input. + pub fn to_cbor_vec(&self) -> Vec { + cbor_to_vec( + &CborSevOsImageMeasurement::from(self), + "SevOsImageMeasurement", + ) + } + + pub fn from_cbor_slice(bytes: &[u8]) -> Result { + cbor_from_slice::(bytes, "SevOsImageMeasurement").map(Into::into) + } + + pub fn cbor_json_value_from_slice(bytes: &[u8]) -> Result { + let cbor = cbor_from_slice::(bytes, "SevOsImageMeasurement")?; + serde_json::to_value(cbor) + .map_err(|e| format!("SevOsImageMeasurement: failed to convert CBOR to JSON: {e}")) + } + + /// SHA-256 over the CBOR representation of this projection. + pub fn os_image_hash(&self) -> [u8; 32] { + sha256(&self.to_cbor_vec()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SevOsImageMeasurementDocument { + /// Document schema version. + #[serde(alias = "v")] + pub version: u32, + /// SHA-256 over the CBOR `measurement` bytes. This field is not included in + /// its own hash input. + #[serde(alias = "h")] + pub os_image_hash: String, + /// CBOR bytes for `SevOsImageMeasurement`. + #[serde(alias = "m", with = "hex_bytes")] + pub measurement: Vec, +} + +impl SevOsImageMeasurementDocument { + pub const VERSION: u32 = 2; + + pub fn new(measurement: SevOsImageMeasurement) -> Self { + let measurement = measurement.to_cbor_vec(); + let os_image_hash = sha256_hex(&measurement); + Self { + version: Self::VERSION, + os_image_hash, + measurement, + } + } + + pub fn decode_measurement(&self) -> Result { + SevOsImageMeasurement::from_cbor_slice(&self.measurement) + } + + pub fn decode_measurement_value(&self) -> Result { + SevOsImageMeasurement::cbor_json_value_from_slice(&self.measurement) + } + + pub fn measurement_os_image_hash(&self) -> [u8; 32] { + sha256(&self.measurement) + } +} + +/// Image-invariant projection that determines the TDX OS image identity. +/// +/// This is the build-time, image-static material for the verifier-side +/// no-image-download TDX path. Dynamic VM parameters (vCPU count, RAM size, +/// QEMU PCI topology, GPU count, etc.) are deliberately excluded and must be +/// supplied by `VmConfig` when replaying RTMRs. +/// +/// `os_image_hash` is SHA-256 over the CBOR representation of this projection, +/// not over the outer measurement.json field names. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TdxOsImageMeasurement { + pub image: TdxImageMeasurement, + pub tdvf: TdxTdvfMeasurement, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TdxImageMeasurement { + /// SHA-384 of the exact kernel command line event measured into RTMR[2]. + /// + /// The measured value is the image-provided command line plus OVMF/QEMU's + /// `initrd=initrd` suffix, encoded as UTF-16LE with a trailing NUL. + #[serde(with = "hex_bytes")] + pub kernel_cmdline_sha384: Vec, + /// Authenticode SHA-384 digest of the QEMU-patched kernel image when the + /// guest memory is at or above QEMU's high-memory TDX initrd placement + /// threshold. Below that threshold the patched kernel header depends on the + /// exact guest memory size, so the no-image-download verifier rejects it. + #[serde(with = "hex_bytes")] + pub kernel_authenticode: Vec, + /// SHA-384 of the initrd file bytes. This is the second RTMR[2] event. + #[serde(with = "hex_bytes")] + pub initrd_sha384: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TdxTdvfMeasurement { + /// OVMF RTMR[0] event layout. + pub ovmf_variant: OvmfVariant, + pub mrtd: TdxMrtdCandidates, + /// Compact TdHobWitnessV1 byte string. + #[serde(with = "hex_bytes")] + pub td_hob_witness: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TdxMrtdCandidates { + /// Candidate MRTD for QEMU's single-pass MEM.PAGE.ADD/MR.EXTEND order. + #[serde(with = "hex_bytes")] + pub single_pass: Vec, + /// Candidate MRTD for QEMU's two-pass MEM.PAGE.ADD then MR.EXTEND order. + #[serde(with = "hex_bytes")] + pub two_pass: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborTdxImageMeasurement { + /// Measured kernel cmdline SHA-384. + #[serde(rename = "cmdline_sha384", with = "hex_bytes")] + kernel_cmdline_sha384: Vec, + /// QEMU-patched kernel Authenticode SHA-384. + #[serde(with = "hex_bytes")] + kernel_authenticode: Vec, + /// Initrd SHA-384. + #[serde(with = "hex_bytes")] + initrd_sha384: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborTdxMrtdCandidates { + #[serde(with = "hex_bytes")] + single_pass: Vec, + #[serde(with = "hex_bytes")] + two_pass: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborTdxTdvfMeasurement { + #[serde(rename = "ovmf")] + ovmf_variant: OvmfVariant, + mrtd: CborTdxMrtdCandidates, + #[serde(rename = "td_hob", with = "hex_bytes")] + td_hob_witness: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +struct CborTdxOsImageMeasurement { + image: CborTdxImageMeasurement, + tdvf: CborTdxTdvfMeasurement, +} + +impl From<&TdxOsImageMeasurement> for CborTdxOsImageMeasurement { + fn from(measurement: &TdxOsImageMeasurement) -> Self { + Self { + image: CborTdxImageMeasurement { + kernel_cmdline_sha384: measurement.image.kernel_cmdline_sha384.clone(), + kernel_authenticode: measurement.image.kernel_authenticode.clone(), + initrd_sha384: measurement.image.initrd_sha384.clone(), + }, + tdvf: CborTdxTdvfMeasurement { + ovmf_variant: measurement.tdvf.ovmf_variant, + mrtd: CborTdxMrtdCandidates { + single_pass: measurement.tdvf.mrtd.single_pass.clone(), + two_pass: measurement.tdvf.mrtd.two_pass.clone(), + }, + td_hob_witness: measurement.tdvf.td_hob_witness.clone(), + }, + } + } +} + +impl From for TdxOsImageMeasurement { + fn from(measurement: CborTdxOsImageMeasurement) -> Self { + Self { + image: TdxImageMeasurement { + kernel_cmdline_sha384: measurement.image.kernel_cmdline_sha384, + kernel_authenticode: measurement.image.kernel_authenticode, + initrd_sha384: measurement.image.initrd_sha384, + }, + tdvf: TdxTdvfMeasurement { + ovmf_variant: measurement.tdvf.ovmf_variant, + mrtd: TdxMrtdCandidates { + single_pass: measurement.tdvf.mrtd.single_pass, + two_pass: measurement.tdvf.mrtd.two_pass, + }, + td_hob_witness: measurement.tdvf.td_hob_witness, + }, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TdxOsImageMeasurementDocument { + /// Document schema version. + #[serde(alias = "v")] + pub version: u32, + /// SHA-256 over the CBOR `measurement` bytes. This field is not included in + /// its own hash input. + #[serde(alias = "h")] + pub os_image_hash: String, + /// CBOR bytes for `TdxOsImageMeasurement`. + #[serde(alias = "m", with = "hex_bytes")] + pub measurement: Vec, +} + +impl TdxOsImageMeasurement { + /// CBOR representation used as the `os_image_hash` input. + pub fn to_cbor_vec(&self) -> Vec { + cbor_to_vec( + &CborTdxOsImageMeasurement::from(self), + "TdxOsImageMeasurement", + ) + } + + pub fn from_cbor_slice(bytes: &[u8]) -> Result { + let cbor = cbor_from_slice::(bytes, "TdxOsImageMeasurement")?; + Ok(cbor.into()) + } + + pub fn cbor_json_value_from_slice(bytes: &[u8]) -> Result { + let cbor = cbor_from_slice::(bytes, "TdxOsImageMeasurement")?; + serde_json::to_value(cbor) + .map_err(|e| format!("TdxOsImageMeasurement: failed to convert CBOR to JSON: {e}")) + } + + /// SHA-256 over the CBOR representation of this projection. pub fn os_image_hash(&self) -> [u8; 32] { - use sha2::{Digest, Sha256}; - // JCS serialization of this plain owned struct (strings/ints/array) - // cannot fail; panic loudly if that invariant is ever broken. - let canonical = serde_jcs::to_vec(self).or_panic("SevOsImageMeasurement JCS serialization"); - Sha256::digest(canonical).into() + sha256(&self.to_cbor_vec()) + } +} + +impl TdxOsImageMeasurementDocument { + pub const VERSION: u32 = 2; + + pub fn new(measurement: TdxOsImageMeasurement) -> Self { + let measurement = measurement.to_cbor_vec(); + let os_image_hash = sha256_hex(&measurement); + Self { + version: Self::VERSION, + os_image_hash, + measurement, + } + } + + pub fn decode_measurement(&self) -> Result { + TdxOsImageMeasurement::from_cbor_slice(&self.measurement) + } + + pub fn decode_measurement_value(&self) -> Result { + TdxOsImageMeasurement::cbor_json_value_from_slice(&self.measurement) + } + + pub fn measurement_os_image_hash(&self) -> [u8; 32] { + sha256(&self.measurement) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct OsImageMeasurementDocument { + /// Document schema version. + #[serde(alias = "v")] + pub version: u32, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tdx: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub snp: Option, +} + +impl OsImageMeasurementDocument { + pub const VERSION: u32 = 2; + + pub fn new( + tdx: Option, + snp: Option, + ) -> Self { + Self { + version: Self::VERSION, + tdx, + snp, + } } } diff --git a/gateway/src/config.rs b/gateway/src/config.rs index 68db41c84..e43bf54bd 100644 --- a/gateway/src/config.rs +++ b/gateway/src/config.rs @@ -9,6 +9,7 @@ use load_config::load_config; use rocket::figment::Figment; use serde::{Deserialize, Serialize}; use std::net::Ipv4Addr; +use std::path::PathBuf; use std::time::Duration; use tracing::info; @@ -113,6 +114,12 @@ pub struct ProxyConfig { pub connect_top_n: usize, pub localhost_enabled: bool, pub workers: usize, + #[serde(default)] + pub base_domain: Option, + #[serde(default)] + pub cert_chain: Option, + #[serde(default)] + pub cert_key: Option, pub app_address_ns_prefix: String, pub app_address_ns_compat: bool, /// Maximum concurrent connections per app. 0 means unlimited. diff --git a/gateway/src/main_service.rs b/gateway/src/main_service.rs index 74b640a2d..14b0f93dd 100644 --- a/gateway/src/main_service.rs +++ b/gateway/src/main_service.rs @@ -39,8 +39,8 @@ use crate::{ cert_store::{CertResolver, CertStoreBuilder}, config::{Config, TlsConfig}, kv::{ - fetch_peers_from_bootnode, AppIdValidator, HttpsClientConfig, InstanceData, KvStore, - NodeData, NodeStatus, PortPolicy, WaveKvSyncService, + fetch_peers_from_bootnode, AppIdValidator, CertData, HttpsClientConfig, InstanceData, + KvStore, NodeData, NodeStatus, PortPolicy, WaveKvSyncService, }, models::{InstanceInfo, PortPolicyView, WgConf}, proxy::{create_acceptor_with_cert_resolver, AddressGroup, AddressInfo}, @@ -267,6 +267,32 @@ impl ProxyInner { all_cert_data.len() ); } + if let (Some(base_domain), Some(cert_chain), Some(cert_key)) = ( + &config.proxy.base_domain, + &config.proxy.cert_chain, + &config.proxy.cert_key, + ) { + let cert_pem = std::fs::read_to_string(cert_chain).with_context(|| { + format!("failed to read proxy cert_chain {}", cert_chain.display()) + })?; + let key_pem = std::fs::read_to_string(cert_key) + .with_context(|| format!("failed to read proxy cert_key {}", cert_key.display()))?; + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let cert_data = CertData { + cert_pem, + key_pem, + not_after: now + 14 * 24 * 60 * 60, + issued_by: config.sync.node_id, + issued_at: now, + }; + cert_resolver + .update_cert(base_domain, &cert_data) + .with_context(|| format!("failed to load static proxy cert for {base_domain}"))?; + info!("CertStore: loaded static proxy certificate for *.{base_domain}"); + } // Create multi-domain certbot (uses KvStore configs for DNS credentials and domains) let certbot = Arc::new(DistributedCertBot::new( diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index 49326d30c..d49f1add7 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -10,7 +10,9 @@ use std::{ use anyhow::{anyhow, bail, Context, Result}; use cc_eventlog::TdxEvent; -use dstack_mr::{RtmrLog, TdxMeasurementDetails, TdxMeasurements}; +use dstack_mr::{ + tdx::TdxRtmr0AcpiHashes, RtmrLog, RtmrLogs, TdxMeasurementDetails, TdxMeasurements, +}; use dstack_types::VmConfig; use hex_literal::hex; use ra_tls::attestation::{ @@ -149,6 +151,7 @@ struct CachedMeasurement { } struct ImagePaths { + image_dir: PathBuf, fw_path: PathBuf, kernel_path: PathBuf, initrd_path: PathBuf, @@ -359,6 +362,91 @@ impl CvmVerifier { Ok(measurements) } + fn image_content_digest(image_dir: &Path) -> Result>> { + let sha256sum_path = image_dir.join("sha256sum.txt"); + if !sha256sum_path.exists() { + return Ok(None); + } + let files_doc = + fs_err::read_to_string(&sha256sum_path).context("Failed to read sha256sum.txt")?; + Ok(Some( + Sha256::new_with_prefix(files_doc.as_bytes()) + .finalize() + .to_vec(), + )) + } + + fn image_hash_matches_legacy_digest(image_dir: &Path, expected: &[u8]) -> Result { + Ok(Self::image_content_digest(image_dir)? + .as_deref() + .is_some_and(|digest| digest == expected)) + } + + fn tdx_acpi_digest_candidates_from_event_log(event_log: &[TdxEvent]) -> Result>> { + const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; + const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; + + let rtmr0_events = event_log + .iter() + .filter(|event| event.imr == 0) + .collect::>(); + let mut candidates = rtmr0_events + .iter() + .filter(|event| { + event.event_type == TDX_ACPI_DATA_EVENT_TYPE + && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD + }) + .map(|event| event.digest()) + .collect::>(); + + // Certificate-embedded attestations strip boot payloads. In the + // measurement path we keep only the three RTMR0 ACPI data digests, so + // fall back to all RTMR0 events when payload-based matching is no longer + // possible. + if candidates.is_empty() && rtmr0_events.len() == 3 { + candidates = rtmr0_events.iter().map(|event| event.digest()).collect(); + } + if candidates.len() != 3 { + bail!( + "TDX measurement attestation requires exactly 3 RTMR0 ACPI DATA digests; found {} candidates and {} RTMR0 events", + candidates.len(), + rtmr0_events.len() + ); + } + for (idx, digest) in candidates.iter().enumerate() { + if digest.len() != 48 { + bail!( + "TDX RTMR0 ACPI DATA digest {idx} has invalid length {}, expected 48", + digest.len() + ); + } + } + Ok(candidates) + } + + fn tdx_acpi_hash_permutations(digests: &[Vec]) -> Vec { + debug_assert_eq!(digests.len(), 3); + let mut permutations = Vec::with_capacity(6); + for loader_idx in 0..3 { + for rsdp_idx in 0..3 { + if rsdp_idx == loader_idx { + continue; + } + for tables_idx in 0..3 { + if tables_idx == loader_idx || tables_idx == rsdp_idx { + continue; + } + permutations.push(TdxRtmr0AcpiHashes { + loader: digests[loader_idx].clone(), + rsdp: digests[rsdp_idx].clone(), + tables: digests[tables_idx].clone(), + }); + } + } + } + permutations + } + /// Helper method to ensure image is downloaded and return image paths async fn ensure_image_downloaded(&self, vm_config: &VmConfig) -> Result { let hex_os_image_hash = hex::encode(&vm_config.os_image_hash); @@ -391,6 +479,7 @@ impl CvmVerifier { let kernel_cmdline = image_info.cmdline + " initrd=initrd"; Ok(ImagePaths { + image_dir, fw_path, kernel_path, initrd_path, @@ -526,8 +615,23 @@ impl CvmVerifier { .await?; } AttestationQuote::DstackTdx(_) => { - self.verify_os_image_hash_for_dstack_tdx(&vm_config, attestation, debug, details) + if vm_config.tdx_attestation_variant.is_measurement() { + self.verify_os_image_hash_for_dstack_tdx_measurement( + &vm_config, + attestation, + debug, + details, + ) .await?; + } else { + self.verify_os_image_hash_for_dstack_tdx( + &vm_config, + attestation, + debug, + details, + ) + .await?; + } } AttestationQuote::DstackNitroEnclave(_) => { let DstackVerifiedReport::DstackNitroEnclave(report) = &attestation.report else { @@ -596,13 +700,11 @@ impl CvmVerifier { bail!("No TDX quote"); }; let event_log = &tdx_quote.event_log; - // Get boot info from attestation let report = report .report .as_td10() .context("Failed to decode TD report")?; - // Extract the verified MRs from the report let verified_mrs = Mrs { mrtd: report.mr_td.to_vec(), rtmr0: report.rt_mr0.to_vec(), @@ -610,16 +712,21 @@ impl CvmVerifier { rtmr2: report.rt_mr2.to_vec(), }; - // one download serves both measurement computation and the dev/version flags + // Legacy TDX attestation keeps the original KMS verifier semantics: + // os_image_hash must be the image content digest, and expected MRs are + // recomputed through the existing full-image path. let image_paths = self.ensure_image_downloaded(vm_config).await?; + if !Self::image_hash_matches_legacy_digest(&image_paths.image_dir, &vm_config.os_image_hash) + .context("Failed to check legacy image digest")? + { + bail!("legacy TDX attestation requires the digest.txt os_image_hash"); + } details.os_image_is_dev = Some(image_paths.is_dev); if !image_paths.version.is_empty() { details.os_image_version = Some(image_paths.version.clone()); } - // Compute expected measurements let (mrs, expected_logs) = if debug { - // For debug mode, we need detailed logs and ACPI tables let TdxMeasurementDetails { measurements, rtmr_logs, @@ -642,7 +749,6 @@ impl CvmVerifier { (measurements, Some(rtmr_logs)) } else { - // For non-debug mode, use the cached-measurement path. ( self.load_or_compute_measurements( vm_config, @@ -656,13 +762,140 @@ impl CvmVerifier { ) }; - let expected_mrs = Mrs { - mrtd: mrs.mrtd.clone(), - rtmr0: mrs.rtmr0.clone(), - rtmr1: mrs.rtmr1.clone(), - rtmr2: mrs.rtmr2.clone(), + self.compare_tdx_mrs( + Mrs { + mrtd: mrs.mrtd, + rtmr0: mrs.rtmr0, + rtmr1: mrs.rtmr1, + rtmr2: mrs.rtmr2, + }, + verified_mrs, + expected_logs.as_ref(), + event_log, + debug, + details, + ) + } + + async fn verify_os_image_hash_for_dstack_tdx_measurement( + &self, + vm_config: &VmConfig, + attestation: &VerifiedAttestation, + debug: bool, + _details: &mut VerificationDetails, + ) -> Result<()> { + let Some(report) = &attestation.report.tdx_report() else { + bail!("No TDX report"); }; + let Some(tdx_quote) = attestation.tdx_quote() else { + bail!("No TDX quote"); + }; + let event_log = &tdx_quote.event_log; + // Get boot info from attestation + let report = report + .report + .as_td10() + .context("Failed to decode TD report")?; + // Extract the verified MRs from the report + let verified_mrs = Mrs { + mrtd: report.mr_td.to_vec(), + rtmr0: report.rt_mr0.to_vec(), + rtmr1: report.rt_mr1.to_vec(), + rtmr2: report.rt_mr2.to_vec(), + }; + + let document = vm_config + .tdx_measurement + .as_ref() + .context("tdx measurement attestation requires vm_config.tdx_measurement")?; + let document_hash = hex::decode(&document.os_image_hash) + .context("vm_config.tdx_measurement.os_image_hash is not valid hex")?; + if document_hash != vm_config.os_image_hash { + bail!( + "tdx measurement os_image_hash mismatch: vm_config={}, document={}", + hex::encode(&vm_config.os_image_hash), + document.os_image_hash + ); + } + let computed_hash = document.measurement_os_image_hash(); + if computed_hash.as_slice() != vm_config.os_image_hash { + bail!( + "tdx measurement document hash mismatch: vm_config={}, computed={}", + hex::encode(&vm_config.os_image_hash), + hex::encode(computed_hash) + ); + } + let measurement = document + .decode_measurement() + .map_err(anyhow::Error::msg) + .context("failed to decode vm_config.tdx_measurement CBOR")?; + if let Some(config_ovmf_variant) = vm_config.ovmf_variant { + if config_ovmf_variant != measurement.tdvf.ovmf_variant { + bail!( + "tdx measurement ovmf_variant mismatch: vm_config={:?}, document={:?}", + config_ovmf_variant, + measurement.tdvf.ovmf_variant + ); + } + } + + // Compute expected measurements. New TDX images advertise the + // measurement.json-derived TDX os_image_hash; verify those without + // downloading the image or running QEMU-derived ACPI table generators. + // The event log supplies only the three hardware-bound RTMR0 ACPI DATA + // digests. Their payloads do not distinguish loader/RSDP/tables, so try + // all assignments and accept the one that replays to the quote RTMRs. + // This avoids hard-coding OVMF-version-specific RTMR0 indexes. + let acpi_digests = Self::tdx_acpi_digest_candidates_from_event_log(event_log) + .context("TDX measurement attestation is missing RTMR0 ACPI DATA digests")?; + let mut last_error = None; + for acpi_hashes in Self::tdx_acpi_hash_permutations(&acpi_digests) { + let mrs = match dstack_mr::tdx::tdx_measurements_from_measurement_document( + document, + vm_config, + &acpi_hashes, + ) + .context("Failed to compute TDX expected measurements without image download") + { + Ok(mrs) => mrs, + Err(e) => { + last_error = Some(e); + continue; + } + }; + + let expected_mrs = Mrs { + mrtd: mrs.mrtd.clone(), + rtmr0: mrs.rtmr0.clone(), + rtmr1: mrs.rtmr1.clone(), + rtmr2: mrs.rtmr2.clone(), + }; + match expected_mrs.assert_eq(&verified_mrs) { + Ok(()) => return Ok(()), + Err(e) => last_error = Some(e.into()), + } + } + + let result = Err(last_error.unwrap_or_else(|| { + anyhow!("MRs do not match for any RTMR0 ACPI DATA digest assignment") + })) + .context("MRs do not match"); + if !debug { + return result; + } + result + } + + fn compare_tdx_mrs( + &self, + expected_mrs: Mrs, + verified_mrs: Mrs, + expected_logs: Option<&RtmrLogs>, + event_log: &[TdxEvent], + debug: bool, + details: &mut VerificationDetails, + ) -> Result<()> { match expected_mrs.assert_eq(&verified_mrs) { Ok(()) => Ok(()), Err(e) => { @@ -670,7 +903,7 @@ impl CvmVerifier { if !debug { return result; } - let Some(expected_logs) = expected_logs.as_ref() else { + let Some(expected_logs) = expected_logs else { return result; }; let mut rtmr_debug = Vec::new(); @@ -894,10 +1127,24 @@ impl CvmVerifier { } } - // os_image_hash should eq to sha256sum of the sha256sum.txt - let os_image_hash = Sha256::new_with_prefix(files_doc.as_bytes()).finalize(); - if hex::encode(os_image_hash) != hex_os_image_hash { - bail!("os_image_hash does not match sha256sum of the sha256sum.txt"); + // Legacy images use sha256(sha256sum.txt) as os_image_hash. Newer + // TDX/SNP images may instead be addressed by measurement.json-derived + // hashes, so accept those too after recomputing them from extracted + // image files. + let legacy_os_image_hash = Sha256::new_with_prefix(files_doc.as_bytes()).finalize(); + let mut image_hash_matches = hex::encode(legacy_os_image_hash) == hex_os_image_hash; + if !image_hash_matches { + image_hash_matches = dstack_mr::tdx::tdx_os_image_hash_for_image_dir(&extracted_dir) + .map(|hash| hex::encode(hash) == hex_os_image_hash) + .unwrap_or(false) + || dstack_mr::sev::sev_os_image_hash_for_image_dir(&extracted_dir) + .map(|hash| hex::encode(hash) == hex_os_image_hash) + .unwrap_or(false); + } + if !image_hash_matches { + bail!( + "os_image_hash matches neither sha256sum.txt nor measurement.json-derived hashes" + ); } // Move the extracted files to the destination directory diff --git a/vmm/src/app.rs b/vmm/src/app.rs index fa21297a0..1510851f0 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1344,17 +1344,30 @@ fn make_vm_config( ) -> Result { let is_amd_sev_snp = cfg.cvm.resolved_platform() == crate::config::TeePlatform::AmdSevSnp && !manifest.no_tee; + let is_tdx = cfg.cvm.resolved_platform() == crate::config::TeePlatform::Tdx && !manifest.no_tee; + let tdx_attestation_variant = if is_tdx { + cfg.cvm.tdx_attestation_variant + } else { + dstack_types::TdxAttestationVariant::Legacy + }; // AMD SEV-SNP binds the OS image through the launch-measurement-derived - // os_image_hash, computed at image build time by `dstack-mr sev-os-image-hash` - // and shipped as `digest.sev.txt` (the same value KMS/verifier derive from a - // verified launch measurement). The VMM reads it from the image rather than - // recomputing it; TDX still uses the generic content digest. + // os_image_hash, computed at image build time and shipped in + // `measurement.json.snp.os_image_hash` (legacy images used `digest.sev.txt`). TDX keeps + // using the generic content digest unless the + // operator explicitly opts into the measurement attestation variant. let os_image_hash = if is_amd_sev_snp { let digest = image.sev_digest.as_deref().context( - "amd sev-snp image is missing digest.sev.txt; \ - rebuild the image so `dstack-mr sev-os-image-hash` emits it", + "amd sev-snp image is missing measurement.json SNP hash; \ + rebuild the image so `dstack-mr os-image-measurement` emits it", )?; - hex::decode(digest).context("digest.sev.txt is not valid hex")? + hex::decode(digest).context("SNP os_image_hash is not valid hex")? + } else if tdx_attestation_variant.is_measurement() { + let digest = image.tdx_digest.as_deref().context( + "tdx measurement attestation requested but image is missing \ + measurement.json TDX hash; rebuild the image so \ + `dstack-mr os-image-measurement` emits it", + )?; + hex::decode(digest).context("TDX os_image_hash is not valid hex")? } else { image .digest @@ -1362,6 +1375,14 @@ fn make_vm_config( .and_then(|d| hex::decode(d).ok()) .unwrap_or_default() }; + let tdx_measurement = if tdx_attestation_variant.is_measurement() { + Some(image.tdx_measurement.clone().context( + "tdx measurement attestation requested but image is missing \ + measurement.json TDX measurement material", + )?) + } else { + None + }; let gpus = if cfg.cvm.gpu.enabled { manifest.gpus.clone().unwrap_or_default() } else { @@ -1383,6 +1404,8 @@ fn make_vm_config( hotplug_off: cfg.cvm.qemu_hotplug_off, image: Some(manifest.image.clone()), ovmf_variant: image.info.ovmf_variant, + tdx_attestation_variant, + tdx_measurement, })?; // For backward compatibility config["spec_version"] = serde_json::Value::from(1); @@ -1580,11 +1603,19 @@ mod tests { ) .to_canonical_json(); - // digest.sev.txt is produced at build time by the `dstack-mr - // sev-os-image-hash` command; the VMM reads it instead of recomputing. + // measurement.json is produced at build time by the `dstack-mr + // os-image-measurement` command; the VMM reads it instead of recomputing. // Emit it here so the deploy path (make_vm_config) can read it back. - let build_hash = dstack_mr::sev::sev_os_image_hash_for_image_dir(&image_dir)?; - fs::write(image_dir.join("digest.sev.txt"), hex::encode(build_hash))?; + let snp_document = + dstack_mr::sev::sev_os_image_measurement_document_for_image_dir(&image_dir)?; + let build_hash = + hex::decode(&snp_document.os_image_hash).context("snp os_image_hash must be hex")?; + let measurement_document = + dstack_types::OsImageMeasurementDocument::new(None, Some(snp_document)); + fs::write( + image_dir.join("measurement.json"), + serde_json::to_string(&measurement_document)?, + )?; let sys_config_document = make_sys_config(&config, &manifest, &compose_hash, Some(mr_config))?; @@ -1607,13 +1638,13 @@ mod tests { assert_eq!(parsed_mr_config.compose_hash, vec![0x22; 32]); assert_eq!(vm_config["mr_config"], sys_config["mr_config"]); // The deploy path must surface the os_image_hash straight from - // digest.sev.txt (not recompute it). + // measurement.json (not recompute it). assert_eq!( vm_config["os_image_hash"] .as_str() .context("os_image_hash must be a string")?, - hex::encode(build_hash), - "vm_config os_image_hash must come from digest.sev.txt" + hex::encode(&build_hash), + "vm_config os_image_hash must come from measurement.json" ); assert!(measurement.get("app_id").is_none()); assert!(measurement.get("compose_hash").is_none()); @@ -1650,18 +1681,24 @@ mod tests { 4 ); - // The build-time os_image_hash (dstack-mr sev-os-image-hash -> - // digest.sev.txt) must equal the os_image_hash a verifier derives from + // The build-time os_image_hash (measurement.json.snp.os_image_hash) must + // equal the os_image_hash a verifier derives from // the launch measurement document, i.e. the image-invariant projection. - let as_str = |v: &serde_json::Value| v.as_str().unwrap().to_string(); - let rootfs_hash = - dstack_mr::sev::rootfs_hash_from_cmdline(measurement["base_cmdline"].as_str())?; + let as_bytes = |v: &serde_json::Value| hex::decode(v.as_str().unwrap()).unwrap(); + dstack_mr::sev::rootfs_hash_from_cmdline(measurement["base_cmdline"].as_str())?; let projected = dstack_types::SevOsImageMeasurement { - rootfs_hash, - base_cmdline: measurement["base_cmdline"].as_str().map(str::to_string), - ovmf_hash: as_str(&measurement["ovmf_hash"]), - kernel_hash: as_str(&measurement["kernel_hash"]), - initrd_hash: as_str(&measurement["initrd_hash"]), + kernel_cmdline_sha256: { + let mut cmdline = measurement["base_cmdline"] + .as_str() + .unwrap() + .as_bytes() + .to_vec(); + cmdline.push(0); + Sha256::digest(&cmdline).to_vec() + }, + ovmf_hash: as_bytes(&measurement["ovmf_hash"]), + kernel_hash: as_bytes(&measurement["kernel_hash"]), + initrd_hash: as_bytes(&measurement["initrd_hash"]), sev_hashes_table_gpa: measurement["sev_hashes_table_gpa"].as_u64().unwrap(), sev_es_reset_eip: measurement["sev_es_reset_eip"].as_u64().unwrap() as u32, ovmf_sections: measurement["ovmf_sections"] @@ -1677,8 +1714,8 @@ mod tests { }; assert_eq!( build_hash, - projected.os_image_hash(), - "digest.sev.txt must match the os_image_hash derived from the launch measurement" + projected.os_image_hash().to_vec(), + "measurement.json SNP hash must match the os_image_hash derived from the launch measurement" ); Ok(()) } diff --git a/vmm/src/app/image.rs b/vmm/src/app/image.rs index c8e7d255d..f7bdb2e7f 100644 --- a/vmm/src/app/image.rs +++ b/vmm/src/app/image.rs @@ -7,6 +7,7 @@ use path_absolutize::Absolutize; use std::path::{Path, PathBuf}; use anyhow::{bail, Context, Result}; +use dstack_types::{OsImageMeasurementDocument, TdxOsImageMeasurementDocument}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] @@ -71,9 +72,12 @@ pub struct Image { pub bios: Option, pub bios_sev: Option, pub digest: Option, - /// AMD SEV-SNP os_image_hash, read from `digest.sev.txt` (produced at image - /// build time by `dstack-mr sev-os-image-hash`). The VMM does not recompute - /// it; the deploy path reads this value directly. + /// TDX os_image_hash, read from `measurement.json.tdx.os_image_hash`. + pub tdx_digest: Option, + /// TDX no-image-download measurement material, read from `measurement.json.tdx`. + pub tdx_measurement: Option, + /// AMD SEV-SNP os_image_hash, read from `measurement.json.snp.os_image_hash` + /// for new images, falling back to legacy `digest.sev.txt`. pub sev_digest: Option, } @@ -103,10 +107,31 @@ impl Image { let digest = fs::read_to_string(base_path.join("digest.txt")) .ok() .map(|s| s.trim().to_string()); - let sev_digest = fs::read_to_string(base_path.join("digest.sev.txt")) + let measurement_path = base_path.join("measurement.json"); + let measurement = if measurement_path.exists() { + let file = fs::File::open(&measurement_path) + .with_context(|| format!("failed to open {}", measurement_path.display()))?; + Some( + serde_json::from_reader::<_, OsImageMeasurementDocument>(file) + .with_context(|| format!("failed to parse {}", measurement_path.display()))?, + ) + } else { + None + }; + let legacy_sev_digest = fs::read_to_string(base_path.join("digest.sev.txt")) .ok() .map(|s| s.trim().to_string()) .filter(|s| !s.is_empty()); + let sev_digest = measurement + .as_ref() + .and_then(|m| m.snp.as_ref()) + .map(|snp| snp.os_image_hash.clone()) + .or(legacy_sev_digest); + let tdx_digest = measurement + .as_ref() + .and_then(|m| m.tdx.as_ref()) + .map(|tdx| tdx.os_image_hash.clone()); + let tdx_measurement = measurement.as_ref().and_then(|m| m.tdx.clone()); if info.version.is_empty() { // Older images does not have version field. Fallback to the version of the image folder name info.version = guess_version(&base_path).unwrap_or_default(); @@ -120,6 +145,8 @@ impl Image { bios, bios_sev, digest, + tdx_digest, + tdx_measurement, sev_digest, } .ensure_exists() diff --git a/vmm/src/config.rs b/vmm/src/config.rs index b0b234a29..523b56edf 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -10,6 +10,7 @@ use path_absolutize::Absolutize; use rocket::figment::Figment; use serde::{Deserialize, Serialize}; +use dstack_types::TdxAttestationVariant; use lspci::{lspci_filtered, Device}; use tracing::{info, warn}; @@ -260,6 +261,12 @@ pub struct CvmConfig { /// QEMU hotplug_off pub qemu_hotplug_off: bool, + /// TDX attestation/hash scheme. `legacy` keeps the existing digest.txt + + /// dstack-acpi-tables verifier path; `measurement` opts into the + /// measurement.json + no-QEMU verifier path. + #[serde(default)] + pub tdx_attestation_variant: TdxAttestationVariant, + /// Networking configuration pub networking: Networking, diff --git a/vmm/vmm.toml b/vmm/vmm.toml index 73d8c124a..6487502d1 100644 --- a/vmm/vmm.toml +++ b/vmm/vmm.toml @@ -45,6 +45,9 @@ use_mrconfigid = true #qemu_version = "" qemu_pci_hole64_size = 0 qemu_hotplug_off = false +# TDX attestation/hash scheme: "legacy" (digest.txt + legacy verifier) or +# "measurement" (measurement.json.tdx.os_image_hash + no-QEMU verifier). +tdx_attestation_variant = "legacy" host_share_mode = "9p" From 687c4668b0b3119c406538005cd9dc4ea61e3bb8 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Sun, 28 Jun 2026 20:50:39 -0700 Subject: [PATCH 02/18] test: add TDX measurement attestation fixture --- .../fixtures/tdx-measurement-attestation.json | 1 + .../fixtures/tdx-measurement-getquote.json | 1 + verifier/fixtures/tdx-measurement.README.md | 55 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 verifier/fixtures/tdx-measurement-attestation.json create mode 100644 verifier/fixtures/tdx-measurement-getquote.json create mode 100644 verifier/fixtures/tdx-measurement.README.md diff --git a/verifier/fixtures/tdx-measurement-attestation.json b/verifier/fixtures/tdx-measurement-attestation.json new file mode 100644 index 000000000..e95dc4641 --- /dev/null +++ b/verifier/fixtures/tdx-measurement-attestation.json @@ -0,0 +1 @@ +{"attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}","debug":true} diff --git a/verifier/fixtures/tdx-measurement-getquote.json b/verifier/fixtures/tdx-measurement-getquote.json new file mode 100644 index 000000000..623613b3f --- /dev/null +++ b/verifier/fixtures/tdx-measurement-getquote.json @@ -0,0 +1 @@ +{"quote":"040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","event_log":"[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"98a9eb355addf798c4c067396c4ae4a973e77589\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]","report_data":"646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}","attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f07090088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c01dd141c7865527ae0205000be341c49069a66ef07b097d30e816afc7c53b4afc9ea407f9fa1b14d9e1ad6917039477cf2c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e775890300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0decc09e278b6cee21838239c1d24f0720a3f75b7e4d6d4558657567d76051f9d30c94e6c705901603a25f60fcc545ca2346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc00300000001000008c03ea3fcad28298c824fb2eb5e7c2ee414fa5ad6e56daa08ac5c09769b6f84ab23d77fa17985df8f4986fc1bc3b0f669f4306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d"} diff --git a/verifier/fixtures/tdx-measurement.README.md b/verifier/fixtures/tdx-measurement.README.md new file mode 100644 index 000000000..881a019e4 --- /dev/null +++ b/verifier/fixtures/tdx-measurement.README.md @@ -0,0 +1,55 @@ +# TDX measurement-mode attestation fixture + +This fixture was captured from the local meta-dstack e2e stack using TDX +`tdx_attestation_variant = "measurement"`. It covers the KMS/verifier path that +verifies the OS image from `vm_config.tdx_measurement`, without downloading the +image and without running the QEMU ACPI table helper. + +Files: + +- `tdx-measurement-attestation.json`: verifier input that mimics the KMS + `GetAppKey` flow. It contains a stripped `attestation` plus the explicit + `vm_config` carrying `tdx_measurement`. +- `tdx-measurement-getquote.json`: raw guest-agent `GetQuoteResponse` captured + via `GetAttestationForAppKey`, including quote, event log, vm_config, and the + full versioned attestation. + +Captured with: + +```bash +E2E_APP_TIMEOUT=900 ./e2e/run.sh up \ + --image dstack-0.6.0 \ + --apps 1 \ + --force \ + --kms-image-verify \ + --kms-no-qemu +``` + +Important fixture properties: + +- `vm_config.tdx_attestation_variant = "measurement"` +- `vm_config.memory_size = 2147483648` (2 GiB) +- `vm_config.os_image_hash = 457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0` +- The stripped attestation keeps the three RTMR0 `ACPI DATA` digests needed by + the measurement verifier plus RTMR3 runtime events. + +To verify without image download, use a config whose download URL is unreachable; +the measurement-mode verifier should still pass: + +```toml +address = "127.0.0.1" +port = 0 +image_cache_dir = "/tmp/dstack-verifier-tdx-measurement-fixture-cache" +image_download_url = "http://127.0.0.1:9/should-not-download/{OS_IMAGE_HASH}.tar.gz" +image_download_timeout_secs = 1 +``` + +Then run: + +```bash +dstack-verifier --config verifier-no-download.toml \ + --verify verifier/fixtures/tdx-measurement-attestation.json +``` + +Expected result: `Valid: true`, with quote, event log, and OS image hash all +verified. From 94aa8efa828e81086ce2c33719e1d2ec020febc9 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Sun, 28 Jun 2026 21:20:38 -0700 Subject: [PATCH 03/18] test: remove debug flag from TDX measurement fixture --- verifier/fixtures/tdx-measurement-attestation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier/fixtures/tdx-measurement-attestation.json b/verifier/fixtures/tdx-measurement-attestation.json index e95dc4641..9aa07ea19 100644 --- a/verifier/fixtures/tdx-measurement-attestation.json +++ b/verifier/fixtures/tdx-measurement-attestation.json @@ -1 +1 @@ -{"attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}","debug":true} +{"attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}"} From 891b4f9385b5db0213c4ba279499014503277c94 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 00:59:53 -0700 Subject: [PATCH 04/18] refactor: rename TDX measurement variant to lite --- dstack-attest/src/v1.rs | 14 +++++++------- dstack-mr/src/tdx.rs | 2 +- dstack-types/src/lib.rs | 10 +++++----- verifier/fixtures/tdx-lite-attestation.json | 4 ++++ verifier/fixtures/tdx-lite-getquote.json | 7 +++++++ ...easurement.README.md => tdx-lite.README.md} | 18 +++++++++--------- .../fixtures/tdx-measurement-attestation.json | 1 - .../fixtures/tdx-measurement-getquote.json | 1 - verifier/src/verification.rs | 14 +++++++------- vmm/src/app.rs | 10 +++++----- vmm/src/config.rs | 2 +- vmm/vmm.toml | 2 +- 12 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 verifier/fixtures/tdx-lite-attestation.json create mode 100644 verifier/fixtures/tdx-lite-getquote.json rename verifier/fixtures/{tdx-measurement.README.md => tdx-lite.README.md} (69%) delete mode 100644 verifier/fixtures/tdx-measurement-attestation.json delete mode 100644 verifier/fixtures/tdx-measurement-getquote.json diff --git a/dstack-attest/src/v1.rs b/dstack-attest/src/v1.rs index 7c36618d9..597af4421 100644 --- a/dstack-attest/src/v1.rs +++ b/dstack-attest/src/v1.rs @@ -27,7 +27,7 @@ pub(crate) fn strip_tdx_runtime_event_log(event_log: Vec) -> Vec) -> Vec { +pub(crate) fn strip_tdx_lite_event_log(event_log: Vec) -> Vec { event_log .into_iter() .filter_map(|event| { @@ -40,9 +40,9 @@ pub(crate) fn strip_tdx_measurement_event_log(event_log: Vec) -> Vec bool { +pub(crate) fn is_tdx_lite_config(config: &str) -> bool { serde_json::from_str::(config) - .map(|config| config.tdx_attestation_variant.is_measurement()) + .map(|config| config.tdx_attestation_variant.is_lite()) .unwrap_or(false) } @@ -50,8 +50,8 @@ pub(crate) fn strip_tdx_event_log_for_config( event_log: Vec, config: &str, ) -> Vec { - if is_tdx_measurement_config(config) { - strip_tdx_measurement_event_log(event_log) + if is_tdx_lite_config(config) { + strip_tdx_lite_event_log(event_log) } else { strip_tdx_runtime_event_log(event_log) } @@ -487,14 +487,14 @@ mod tests { } #[test] - fn measurement_stripping_keeps_only_acpi_data_digests_and_runtime_payloads() { + fn lite_stripping_keeps_only_acpi_data_digests_and_runtime_payloads() { let mut event_log = (0..20).map(boot_event).collect::>(); event_log[3] = acpi_data_event(3); event_log[8] = acpi_data_event(8); event_log[15] = acpi_data_event(15); event_log.push(runtime_event()); - let stripped = strip_tdx_measurement_event_log(event_log); + let stripped = strip_tdx_lite_event_log(event_log); assert_eq!(stripped.len(), 4); assert_eq!( diff --git a/dstack-mr/src/tdx.rs b/dstack-mr/src/tdx.rs index c7406309a..f604bb0b5 100644 --- a/dstack-mr/src/tdx.rs +++ b/dstack-mr/src/tdx.rs @@ -360,7 +360,7 @@ pub fn tdx_measurements_from_measurement_document( } if !tdx_kernel_hash_uses_precomputed_high_mem(vm_config.memory_size) { bail!( - "TDX measurement attestation without image download requires memory_size == {} bytes ({} MiB) or >= {} bytes ({} MiB); got {} bytes", + "TDX lite attestation without image download requires memory_size == {} bytes ({} MiB) or >= {} bytes ({} MiB); got {} bytes", TDX_KERNEL_HASH_COMPAT_2G_MEMORY, TDX_KERNEL_HASH_COMPAT_2G_MEMORY / 1024 / 1024, TDX_KERNEL_HASH_STABLE_MIN_MEMORY, diff --git a/dstack-types/src/lib.rs b/dstack-types/src/lib.rs index cac0313c1..69d5000e5 100644 --- a/dstack-types/src/lib.rs +++ b/dstack-types/src/lib.rs @@ -56,7 +56,7 @@ impl OvmfVariant { /// is the content digest (`digest.txt`) and the verifier recomputes the full /// TDX launch measurement using the legacy image/QEMU-derived path. /// -/// `Measurement` opts into the no-QEMU verifier path: `vm_config.os_image_hash` +/// `Lite` opts into the no-QEMU verifier path: `vm_config.os_image_hash` /// is `measurement.json.tdx.os_image_hash`, `vm_config.tdx_measurement` carries /// the self-contained measurement material, and KMS/verifier select the new /// logic from this vm_config flag while the attestation quote remains the @@ -66,7 +66,7 @@ impl OvmfVariant { pub enum TdxAttestationVariant { #[default] Legacy, - Measurement, + Lite, } impl TdxAttestationVariant { @@ -74,8 +74,8 @@ impl TdxAttestationVariant { matches!(self, Self::Legacy) } - pub fn is_measurement(&self) -> bool { - matches!(self, Self::Measurement) + pub fn is_lite(&self) -> bool { + matches!(self, Self::Lite) } } @@ -309,7 +309,7 @@ pub struct VmConfig { #[serde(default, skip_serializing_if = "TdxAttestationVariant::is_legacy")] pub tdx_attestation_variant: TdxAttestationVariant, /// TDX-only no-image-download measurement material. Present only when - /// `tdx_attestation_variant = "measurement"` and omitted for legacy TDX. + /// `tdx_attestation_variant = "lite"` and omitted for legacy TDX. #[serde(default, skip_serializing_if = "Option::is_none")] pub tdx_measurement: Option, } diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json new file mode 100644 index 000000000..3d33e2812 --- /dev/null +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -0,0 +1,4 @@ +{ + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "vm_config": "{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" +} diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json new file mode 100644 index 000000000..39d9d6333 --- /dev/null +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -0,0 +1,7 @@ +{ + "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"98a9eb355addf798c4c067396c4ae4a973e77589\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", + "report_data": "646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961", + "vm_config": "{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f07090088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c01dd141c7865527ae0205000be341c49069a66ef07b097d30e816afc7c53b4afc9ea407f9fa1b14d9e1ad6917039477cf2c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e775890300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0decc09e278b6cee21838239c1d24f0720a3f75b7e4d6d4558657567d76051f9d30c94e6c705901603a25f60fcc545ca2346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc00300000001000008c03ea3fcad28298c824fb2eb5e7c2ee414fa5ad6e56daa08ac5c09769b6f84ab23d77fa17985df8f4986fc1bc3b0f669f4306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" +} diff --git a/verifier/fixtures/tdx-measurement.README.md b/verifier/fixtures/tdx-lite.README.md similarity index 69% rename from verifier/fixtures/tdx-measurement.README.md rename to verifier/fixtures/tdx-lite.README.md index 881a019e4..383ad5748 100644 --- a/verifier/fixtures/tdx-measurement.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -1,16 +1,16 @@ -# TDX measurement-mode attestation fixture +# TDX lite attestation fixture This fixture was captured from the local meta-dstack e2e stack using TDX -`tdx_attestation_variant = "measurement"`. It covers the KMS/verifier path that +`tdx_attestation_variant = "lite"`. It covers the KMS/verifier path that verifies the OS image from `vm_config.tdx_measurement`, without downloading the image and without running the QEMU ACPI table helper. Files: -- `tdx-measurement-attestation.json`: verifier input that mimics the KMS +- `tdx-lite-attestation.json`: verifier input that mimics the KMS `GetAppKey` flow. It contains a stripped `attestation` plus the explicit `vm_config` carrying `tdx_measurement`. -- `tdx-measurement-getquote.json`: raw guest-agent `GetQuoteResponse` captured +- `tdx-lite-getquote.json`: raw guest-agent `GetQuoteResponse` captured via `GetAttestationForAppKey`, including quote, event log, vm_config, and the full versioned attestation. @@ -27,19 +27,19 @@ E2E_APP_TIMEOUT=900 ./e2e/run.sh up \ Important fixture properties: -- `vm_config.tdx_attestation_variant = "measurement"` +- `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) - `vm_config.os_image_hash = 457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0` - The stripped attestation keeps the three RTMR0 `ACPI DATA` digests needed by - the measurement verifier plus RTMR3 runtime events. + the lite verifier plus RTMR3 runtime events. To verify without image download, use a config whose download URL is unreachable; -the measurement-mode verifier should still pass: +the lite verifier should still pass: ```toml address = "127.0.0.1" port = 0 -image_cache_dir = "/tmp/dstack-verifier-tdx-measurement-fixture-cache" +image_cache_dir = "/tmp/dstack-verifier-tdx-lite-fixture-cache" image_download_url = "http://127.0.0.1:9/should-not-download/{OS_IMAGE_HASH}.tar.gz" image_download_timeout_secs = 1 ``` @@ -48,7 +48,7 @@ Then run: ```bash dstack-verifier --config verifier-no-download.toml \ - --verify verifier/fixtures/tdx-measurement-attestation.json + --verify verifier/fixtures/tdx-lite-attestation.json ``` Expected result: `Valid: true`, with quote, event log, and OS image hash all diff --git a/verifier/fixtures/tdx-measurement-attestation.json b/verifier/fixtures/tdx-measurement-attestation.json deleted file mode 100644 index 9aa07ea19..000000000 --- a/verifier/fixtures/tdx-measurement-attestation.json +++ /dev/null @@ -1 +0,0 @@ -{"attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}"} diff --git a/verifier/fixtures/tdx-measurement-getquote.json b/verifier/fixtures/tdx-measurement-getquote.json deleted file mode 100644 index 623613b3f..000000000 --- a/verifier/fixtures/tdx-measurement-getquote.json +++ /dev/null @@ -1 +0,0 @@ -{"quote":"040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","event_log":"[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"98a9eb355addf798c4c067396c4ae4a973e77589\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]","report_data":"646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961","vm_config":"{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"measurement\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}","attestation":"0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f07090088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c01dd141c7865527ae0205000be341c49069a66ef07b097d30e816afc7c53b4afc9ea407f9fa1b14d9e1ad6917039477cf2c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e775890300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0decc09e278b6cee21838239c1d24f0720a3f75b7e4d6d4558657567d76051f9d30c94e6c705901603a25f60fcc545ca2346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc00300000001000008c03ea3fcad28298c824fb2eb5e7c2ee414fa5ad6e56daa08ac5c09769b6f84ab23d77fa17985df8f4986fc1bc3b0f669f4306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596181137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226d6561737572656d656e74222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d"} diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index d49f1add7..357fb8b6b 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -400,7 +400,7 @@ impl CvmVerifier { .collect::>(); // Certificate-embedded attestations strip boot payloads. In the - // measurement path we keep only the three RTMR0 ACPI data digests, so + // lite path we keep only the three RTMR0 ACPI data digests, so // fall back to all RTMR0 events when payload-based matching is no longer // possible. if candidates.is_empty() && rtmr0_events.len() == 3 { @@ -408,7 +408,7 @@ impl CvmVerifier { } if candidates.len() != 3 { bail!( - "TDX measurement attestation requires exactly 3 RTMR0 ACPI DATA digests; found {} candidates and {} RTMR0 events", + "TDX lite attestation requires exactly 3 RTMR0 ACPI DATA digests; found {} candidates and {} RTMR0 events", candidates.len(), rtmr0_events.len() ); @@ -615,8 +615,8 @@ impl CvmVerifier { .await?; } AttestationQuote::DstackTdx(_) => { - if vm_config.tdx_attestation_variant.is_measurement() { - self.verify_os_image_hash_for_dstack_tdx_measurement( + if vm_config.tdx_attestation_variant.is_lite() { + self.verify_os_image_hash_for_dstack_tdx_lite( &vm_config, attestation, debug, @@ -777,7 +777,7 @@ impl CvmVerifier { ) } - async fn verify_os_image_hash_for_dstack_tdx_measurement( + async fn verify_os_image_hash_for_dstack_tdx_lite( &self, vm_config: &VmConfig, attestation: &VerifiedAttestation, @@ -808,7 +808,7 @@ impl CvmVerifier { let document = vm_config .tdx_measurement .as_ref() - .context("tdx measurement attestation requires vm_config.tdx_measurement")?; + .context("tdx lite attestation requires vm_config.tdx_measurement")?; let document_hash = hex::decode(&document.os_image_hash) .context("vm_config.tdx_measurement.os_image_hash is not valid hex")?; if document_hash != vm_config.os_image_hash { @@ -848,7 +848,7 @@ impl CvmVerifier { // all assignments and accept the one that replays to the quote RTMRs. // This avoids hard-coding OVMF-version-specific RTMR0 indexes. let acpi_digests = Self::tdx_acpi_digest_candidates_from_event_log(event_log) - .context("TDX measurement attestation is missing RTMR0 ACPI DATA digests")?; + .context("TDX lite attestation is missing RTMR0 ACPI DATA digests")?; let mut last_error = None; for acpi_hashes in Self::tdx_acpi_hash_permutations(&acpi_digests) { let mrs = match dstack_mr::tdx::tdx_measurements_from_measurement_document( diff --git a/vmm/src/app.rs b/vmm/src/app.rs index 1510851f0..288453d19 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1354,16 +1354,16 @@ fn make_vm_config( // os_image_hash, computed at image build time and shipped in // `measurement.json.snp.os_image_hash` (legacy images used `digest.sev.txt`). TDX keeps // using the generic content digest unless the - // operator explicitly opts into the measurement attestation variant. + // operator explicitly opts into the lite attestation variant. let os_image_hash = if is_amd_sev_snp { let digest = image.sev_digest.as_deref().context( "amd sev-snp image is missing measurement.json SNP hash; \ rebuild the image so `dstack-mr os-image-measurement` emits it", )?; hex::decode(digest).context("SNP os_image_hash is not valid hex")? - } else if tdx_attestation_variant.is_measurement() { + } else if tdx_attestation_variant.is_lite() { let digest = image.tdx_digest.as_deref().context( - "tdx measurement attestation requested but image is missing \ + "tdx lite attestation requested but image is missing \ measurement.json TDX hash; rebuild the image so \ `dstack-mr os-image-measurement` emits it", )?; @@ -1375,9 +1375,9 @@ fn make_vm_config( .and_then(|d| hex::decode(d).ok()) .unwrap_or_default() }; - let tdx_measurement = if tdx_attestation_variant.is_measurement() { + let tdx_measurement = if tdx_attestation_variant.is_lite() { Some(image.tdx_measurement.clone().context( - "tdx measurement attestation requested but image is missing \ + "tdx lite attestation requested but image is missing \ measurement.json TDX measurement material", )?) } else { diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 523b56edf..788865d49 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -262,7 +262,7 @@ pub struct CvmConfig { pub qemu_hotplug_off: bool, /// TDX attestation/hash scheme. `legacy` keeps the existing digest.txt + - /// dstack-acpi-tables verifier path; `measurement` opts into the + /// dstack-acpi-tables verifier path; `lite` opts into the /// measurement.json + no-QEMU verifier path. #[serde(default)] pub tdx_attestation_variant: TdxAttestationVariant, diff --git a/vmm/vmm.toml b/vmm/vmm.toml index 6487502d1..cde99b7a7 100644 --- a/vmm/vmm.toml +++ b/vmm/vmm.toml @@ -46,7 +46,7 @@ use_mrconfigid = true qemu_pci_hole64_size = 0 qemu_hotplug_off = false # TDX attestation/hash scheme: "legacy" (digest.txt + legacy verifier) or -# "measurement" (measurement.json.tdx.os_image_hash + no-QEMU verifier). +# "lite" (measurement.json.tdx.os_image_hash + no-QEMU verifier). tdx_attestation_variant = "legacy" host_share_mode = "9p" From 2b07c74d6060e892edc4f69aa002b8513a9f666f Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 01:07:50 -0700 Subject: [PATCH 05/18] chore: fix clippy warnings --- dstack-mr/src/tdvf.rs | 8 ++++---- verifier/src/verification.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dstack-mr/src/tdvf.rs b/dstack-mr/src/tdvf.rs index 90847a504..74388dde8 100644 --- a/dstack-mr/src/tdvf.rs +++ b/dstack-mr/src/tdvf.rs @@ -472,10 +472,10 @@ impl<'a> Tdvf<'a> { } ranges.push((start_page, page_count)); } - if s.sec_type == TDVF_SECTION_TD_HOB { - if td_hob_page.replace(s.memory_address / PAGE_SIZE).is_some() { - bail!("TDVF metadata contains more than one TD_HOB section"); - } + if s.sec_type == TDVF_SECTION_TD_HOB + && td_hob_page.replace(s.memory_address / PAGE_SIZE).is_some() + { + bail!("TDVF metadata contains more than one TD_HOB section"); } } diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index 357fb8b6b..5ac56949a 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -873,7 +873,7 @@ impl CvmVerifier { }; match expected_mrs.assert_eq(&verified_mrs) { Ok(()) => return Ok(()), - Err(e) => last_error = Some(e.into()), + Err(e) => last_error = Some(e), } } From ff3af61fec2428a2f4591636b8e50eaeb3790fd3 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 01:45:17 -0700 Subject: [PATCH 06/18] fix: preserve ACPI DATA payload in TDX lite attestations --- dstack-attest/src/v1.rs | 12 ++++++++++-- verifier/fixtures/tdx-lite-attestation.json | 2 +- verifier/fixtures/tdx-lite.README.md | 5 +++-- verifier/src/verification.rs | 10 +--------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/dstack-attest/src/v1.rs b/dstack-attest/src/v1.rs index 597af4421..eb71e8970 100644 --- a/dstack-attest/src/v1.rs +++ b/dstack-attest/src/v1.rs @@ -27,11 +27,19 @@ pub(crate) fn strip_tdx_runtime_event_log(event_log: Vec) -> Vec TdxEvent { + let mut event = event.stripped(); + event.event_payload = TDX_ACPI_DATA_EVENT_PAYLOAD.to_vec(); + event +} + pub(crate) fn strip_tdx_lite_event_log(event_log: Vec) -> Vec { event_log .into_iter() .filter_map(|event| { - if is_tdx_acpi_data_event(&event) || event.imr == 3 { + if is_tdx_acpi_data_event(&event) { + Some(strip_tdx_lite_acpi_data_event(event)) + } else if event.imr == 3 { Some(event.stripped()) } else { None @@ -506,7 +514,7 @@ mod tests { ); assert!(stripped[0..3] .iter() - .all(|event| event.imr == 0 && event.event_payload.is_empty())); + .all(|event| event.imr == 0 && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD)); assert_eq!(stripped[3].imr, 3); assert_eq!(stripped[3].event, "app-id"); assert_eq!(stripped[3].event_payload, vec![0x42]); diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index 3d33e2812..b6bf4060a 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370000000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0000000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600000300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", "vm_config": "{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 383ad5748..813e7648a 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -30,8 +30,9 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) - `vm_config.os_image_hash = 457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0` -- The stripped attestation keeps the three RTMR0 `ACPI DATA` digests needed by - the lite verifier plus RTMR3 runtime events. +- The stripped attestation keeps the three RTMR0 `ACPI DATA` digests and + their `ACPI DATA` marker payloads needed by the lite verifier, plus RTMR3 + runtime events. To verify without image download, use a config whose download URL is unreachable; the lite verifier should still pass: diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index 5ac56949a..56c0744c7 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -390,7 +390,7 @@ impl CvmVerifier { .iter() .filter(|event| event.imr == 0) .collect::>(); - let mut candidates = rtmr0_events + let candidates = rtmr0_events .iter() .filter(|event| { event.event_type == TDX_ACPI_DATA_EVENT_TYPE @@ -398,14 +398,6 @@ impl CvmVerifier { }) .map(|event| event.digest()) .collect::>(); - - // Certificate-embedded attestations strip boot payloads. In the - // lite path we keep only the three RTMR0 ACPI data digests, so - // fall back to all RTMR0 events when payload-based matching is no longer - // possible. - if candidates.is_empty() && rtmr0_events.len() == 3 { - candidates = rtmr0_events.iter().map(|event| event.digest()).collect(); - } if candidates.len() != 3 { bail!( "TDX lite attestation requires exactly 3 RTMR0 ACPI DATA digests; found {} candidates and {} RTMR0 events", From 6d26e73252cdac60cacd0d439903c05a3967b1b6 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 02:37:33 -0700 Subject: [PATCH 07/18] test: recapture TDX lite fixtures --- verifier/fixtures/tdx-lite-attestation.json | 4 ++-- verifier/fixtures/tdx-lite-getquote.json | 10 +++++----- verifier/fixtures/tdx-lite.README.md | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index b6bf4060a..a25e49ac3 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", - "vm_config": "{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c3365137b226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333065383431363362323538323063306635616465353432363534646336643962653035656635623930653463396135643736643834343036633661346230393065323761363961613764353331666535616133303264613461323131623332316437333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "vm_config": "{\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index 39d9d6333..465a46139 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -1,7 +1,7 @@ { - "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"98a9eb355addf798c4c067396c4ae4a973e77589\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", - "report_data": "646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961", - "vm_config": "{\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f0709736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee7b2796d4a86235438d257111c99fe7e785942a1b9db707742e62602c6b6c2f9c1faeda88208300b5f63a6c9544e0fa244ac72fb0b708785794339f85ea1d1fe9e0a5c37e6435d86918635f368f193c8a48bef35649fd87185312333069b8e1eb646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c4278423747785961cc1000002a21b550bbe03143ff6ea043411aee5a9ad2e42e0684c7ab76a4721c36f0f49e100d28585e23cacf8ca456c22a75509937f78c7d118797dbdc45c341e3bb82824fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0d6e4b5635869d58f2ad081f679fd9a1f79d1056a3daf57ea134c69fea65f02c52233fb0c3092421e344e3347670f07090088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c01dd141c7865527ae0205000be341c49069a66ef07b097d30e816afc7c53b4afc9ea407f9fa1b14d9e1ad6917039477cf2c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e775890300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0decc09e278b6cee21838239c1d24f0720a3f75b7e4d6d4558657567d76051f9d30c94e6c705901603a25f60fcc545ca2346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc00300000001000008c03ea3fcad28298c824fb2eb5e7c2ee414fa5ad6e56daa08ac5c09769b6f84ab23d77fa17985df8f4986fc1bc3b0f669f4306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d69645098a9eb355addf798c4c067396c4ae4a973e7758930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343032353361363735356436313162623462626430346365626230376136656137623636613331323637353135323761626434613836666237303266616439366365346430313133663366616431666364366636356436363434636532346466396661383335626465363836616165396430646661646665356661633663323730227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a4174656c4e4d6c6c7739344a72756a675555517672394e59466d4c48454f76703135464c427842374778596165137b226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2234353763333835353337636662633863636136313762363732656633393561653061616262383866306666663162633533636138383762343634373564636330222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333064366534623536333538363964353866326164303831663637396664396131663739643130353661336461663537656131333463363966656136356630326335323233336662306333303932343231653334346533333437363730663037303937333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" + "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"eba0d9bb58f119907cb6785db62c3c00d44e5129\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", + "report_data": "646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33", + "vm_config": "{\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d0088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c0df3e40734f05b41d62299ead8b2d0e65dba9331630006df304fdce95c88d51245e0d90ee059c1b2c8bb0a892e310fc102c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e51290300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0464d50eae2dfc4afea38a36decac0f5632f81512f2f878705d2d8cb286dee253db77a0fb4012bb91bdd2d5a029993727346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d000300000001000008c0511e1ceab69ea7e48f750891e5f9a790d0aecabe3f60b4b51a7048014260b3907cc5996b96af160146208c8bd70b31fd306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c3365137b226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333065383431363362323538323063306635616465353432363534646336643962653035656635623930653463396135643736643834343036633661346230393065323761363961613764353331666535616133303264613461323131623332316437333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 813e7648a..6ecbb8ff3 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -18,6 +18,7 @@ Captured with: ```bash E2E_APP_TIMEOUT=900 ./e2e/run.sh up \ + --image-dir images \ --image dstack-0.6.0 \ --apps 1 \ --force \ @@ -29,7 +30,7 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) -- `vm_config.os_image_hash = 457c385537cfbc8cca617b672ef395ae0aabb88f0fff1bc53ca887b46475dcc0` +- `vm_config.os_image_hash = dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00` - The stripped attestation keeps the three RTMR0 `ACPI DATA` digests and their `ACPI DATA` marker payloads needed by the lite verifier, plus RTMR3 runtime events. From dc11472fea007fd86ed1b32c0a02fde7c661d325 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 05:47:28 -0700 Subject: [PATCH 08/18] fix: keep lite ACPI payloads in getquote event log --- dstack-attest/src/attestation.rs | 69 ++++++++++++++++++++- dstack-attest/src/v1.rs | 2 +- guest-agent/src/backend.rs | 2 +- verifier/fixtures/tdx-lite-attestation.json | 4 +- verifier/fixtures/tdx-lite-getquote.json | 10 +-- verifier/fixtures/tdx-lite.README.md | 8 +-- 6 files changed, 80 insertions(+), 15 deletions(-) diff --git a/dstack-attest/src/attestation.rs b/dstack-attest/src/attestation.rs index c56652799..f98b856a8 100644 --- a/dstack-attest/src/attestation.rs +++ b/dstack-attest/src/attestation.rs @@ -32,7 +32,10 @@ use tpm_qvl::verify::VerifiedReport as TpmVerifiedReport; pub use tpm_types::TpmQuote; use crate::amd_sev_snp::VerifiedAmdSnpReport; -use crate::v1::{strip_tdx_event_log_for_config, strip_tdx_runtime_event_log}; +use crate::v1::{ + is_tdx_acpi_data_event, is_tdx_lite_config, strip_tdx_event_log_for_config, + strip_tdx_runtime_event_log, +}; pub use crate::v1::{Attestation as AttestationV1, PlatformEvidence, StackEvidence}; pub const SNP_REPORT_DATA_RANGE: std::ops::Range = 0x50..0x90; @@ -1129,8 +1132,29 @@ impl Attestation { /// Get TDX event log string with RTMR[0-2] payloads stripped to reduce size. /// Only digests are kept for boot-time events; runtime events (RTMR3) retain full payload. pub fn get_tdx_event_log_string(&self) -> Option { + self.get_tdx_event_log_string_for_config("") + } + + /// Get TDX event log string for a vm_config. + /// + /// In lite mode, keep the `ACPI DATA` marker payloads in RTMR0 so callers + /// that still consume the top-level `event_log` can semantically identify + /// the ACPI table digest events without consulting the versioned + /// attestation field. + pub fn get_tdx_event_log_string_for_config(&self, config: &str) -> Option { self.tdx_quote().map(|q| { - let stripped: Vec<_> = q.event_log.iter().map(|e| e.stripped()).collect(); + let keep_lite_acpi_payload = is_tdx_lite_config(config); + let stripped: Vec<_> = q + .event_log + .iter() + .map(|e| { + let mut stripped = e.stripped(); + if keep_lite_acpi_payload && is_tdx_acpi_data_event(e) { + stripped.event_payload = e.event_payload.clone(); + } + stripped + }) + .collect(); serde_json::to_string(&stripped).unwrap_or_default() }) } @@ -2015,6 +2039,47 @@ mod tests { } } + fn tdx_event(imr: u32, event_type: u32, event_payload: &[u8]) -> TdxEvent { + TdxEvent { + imr, + event_type, + digest: vec![event_type as u8; 48], + event: String::new(), + event_payload: event_payload.to_vec(), + } + } + + #[test] + fn tdx_event_log_string_for_lite_keeps_acpi_data_payloads() { + let mut attestation = dummy_tdx_attestation([0u8; 64]); + let AttestationQuote::DstackTdx(tdx_quote) = &mut attestation.quote else { + panic!("expected TDX attestation"); + }; + tdx_quote.event_log = vec![ + tdx_event(0, 10, b"ACPI DATA"), + tdx_event(0, 4, b"boot-payload"), + tdx_event(3, 8, b"runtime-payload"), + ]; + + let lite_events: Vec = serde_json::from_str( + &attestation + .get_tdx_event_log_string_for_config(r#"{"tdx_attestation_variant":"lite"}"#) + .expect("TDX event log"), + ) + .expect("decode lite event log"); + assert_eq!(lite_events[0].event_payload, b"ACPI DATA"); + assert!(lite_events[1].event_payload.is_empty()); + assert!(lite_events[2].event_payload.is_empty()); + + let legacy_events: Vec = serde_json::from_str( + &attestation + .get_tdx_event_log_string() + .expect("TDX event log"), + ) + .expect("decode legacy event log"); + assert!(legacy_events[0].event_payload.is_empty()); + } + #[test] fn test_to_report_data_with_hash() { let content_type = QuoteContentType::AppData; diff --git a/dstack-attest/src/v1.rs b/dstack-attest/src/v1.rs index eb71e8970..a5fa5b750 100644 --- a/dstack-attest/src/v1.rs +++ b/dstack-attest/src/v1.rs @@ -13,7 +13,7 @@ pub const ATTESTATION_VERSION: u64 = 1; const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; -fn is_tdx_acpi_data_event(event: &TdxEvent) -> bool { +pub(crate) fn is_tdx_acpi_data_event(event: &TdxEvent) -> bool { event.imr == 0 && event.event_type == TDX_ACPI_DATA_EVENT_TYPE && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD diff --git a/guest-agent/src/backend.rs b/guest-agent/src/backend.rs index a8e06cd8e..55af0947b 100644 --- a/guest-agent/src/backend.rs +++ b/guest-agent/src/backend.rs @@ -36,7 +36,7 @@ impl PlatformBackend for RealPlatform { fn quote_response(&self, report_data: [u8; 64], vm_config: &str) -> Result { let attestation = Attestation::quote(&report_data).context("Failed to get quote")?; let tdx_quote = attestation.get_tdx_quote_bytes(); - let tdx_event_log = attestation.get_tdx_event_log_string(); + let tdx_event_log = attestation.get_tdx_event_log_string_for_config(vm_config); // Always carry the platform-adaptive versioned attestation so callers on // non-TDX platforms (AMD SEV-SNP) still get a verifier-ready payload. let versioned = attestation diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index a25e49ac3..3d355a527 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512903000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c3365137b226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333065383431363362323538323063306635616465353432363534646336643962653035656635623930653463396135643736643834343036633661346230393065323761363961613764353331666535616133303264613461323131623332316437333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", - "vm_config": "{\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c3165137b226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333034376132613365626261306133366234376335363332613135626535313261656432383462363538376462313737353334373033356333633436356239343533323536613838623338323431396237313530343730373636336535353731613337333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "vm_config": "{\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"measurement\":\"a265696d616765a36e636d646c696e655f736861333834583047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index 465a46139..d4975289d 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -1,7 +1,7 @@ { - "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"eba0d9bb58f119907cb6785db62c3c00d44e5129\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", - "report_data": "646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33", - "vm_config": "{\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aeea81cd9e60c9ee42ff99f00308b7de6782755002a3596b158392900a69ca804f2c6cd39c37715f2babae0404a27a53131a6f9c992fc305a43ead5d87b30d6bbc349213efb6dc0a313427acb7c5f399cd503940a47de3105acfbdce43469b78399646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c33cc1000001481fb3225e49ec933e79aba4077e13cb5de35af0a4228e2b308022312abd515263c245e9e65201ab2fc75a78218206924a0781a9ef58a89fad7ebd7595964134fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000008e58dd088127305e4ed927ca5a3376f29ec8cef1a8bc33d3d1928879402a652b6ea27825d58b14e14299413a5f47771be9239a0b31cdfe0caa68207dc16d16a32000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c0e84163b25820c0f5ade542654dc6d9be05ef5b90e4c9a5d76d84406c6a4b090e27a69aa7d531fe5aa302da4a211b321d0088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c0df3e40734f05b41d62299ead8b2d0e65dba9331630006df304fdce95c88d51245e0d90ee059c1b2c8bb0a892e310fc102c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e51290300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c0464d50eae2dfc4afea38a36decac0f5632f81512f2f878705d2d8cb286dee253db77a0fb4012bb91bdd2d5a029993727346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d000300000001000008c0511e1ceab69ea7e48f750891e5f9a790d0aecabe3f60b4b51a7048014260b3907cc5996b96af160146208c8bd70b31fd306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450eba0d9bb58f119907cb6785db62c3c00d44e512930626f6f742d6d722d646f6e6500346f732d696d6167652d6861736880dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343839343938313166636631376438636463313538376362363361653639653831656530353362386332396666663330393061323838636432313637343730323964376166343264393338626531643138623430376237383065626239666538623232613436653438373963363230343166353834363466316431323466376334227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a416d755f52717056666c69723762783774796b627250445874735636572d382d325770773361436171424c3365137b226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2264666464663231333430376639626566346365333031613561373131323431613832316131623533613262663864666564623437346332656263316436643030222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333065383431363362323538323063306635616465353432363534646336643962653035656635623930653463396135643736643834343036633661346230393065323761363961613764353331666535616133303264613461323131623332316437333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" + "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"47a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", + "report_data": "646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31", + "vm_config": "{\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"measurement\":\"a265696d616765a36e636d646c696e655f736861333834583047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a30088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c00bedd694f3c9f1f5eb2125b1020bbf6c03caf4063380bc0c1f667d143167b5347cba2ce26d3cb042dcd30a0b48bce4392c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae0300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c06b6a05657daa9c0348ef6d97f3f3e28abef0665d241580b3416d12a721c8b11e94bdee05e56362d5592abd3af1cb2e06346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c0300000001000008c0bf0600a25fd3ce1be4e8b89cea8b6c64a8bb7efbcfaeb27164a6258a294af57e72ba3afc1b2f8686714b52bc5878e922306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c3165137b226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333034376132613365626261306133366234376335363332613135626535313261656432383462363538376462313737353334373033356333633436356239343533323536613838623338323431396237313530343730373636336535353731613337333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 6ecbb8ff3..fcc668e6b 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -30,10 +30,10 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) -- `vm_config.os_image_hash = dfddf213407f9bef4ce301a5a711241a821a1b53a2bf8dfedb474c2ebc1d6d00` -- The stripped attestation keeps the three RTMR0 `ACPI DATA` digests and - their `ACPI DATA` marker payloads needed by the lite verifier, plus RTMR3 - runtime events. +- `vm_config.os_image_hash = 66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c` +- The top-level `event_log` and stripped attestation keep the three RTMR0 + `ACPI DATA` digests and marker payloads needed by the lite verifier, plus + RTMR3 runtime events. To verify without image download, use a config whose download URL is unreachable; the lite verifier should still pass: From 02bb24761a15a3047f30be3da8aa6f1c64e3ef46 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 06:34:28 -0700 Subject: [PATCH 09/18] fix: omit TDX getquote attestation payload --- guest-agent/rpc/build.rs | 4 ++++ guest-agent/rpc/proto/agent_rpc.proto | 5 ++--- guest-agent/src/backend.rs | 16 ++++++++++------ guest-agent/src/rpc_service.rs | 8 +++----- verifier/fixtures/tdx-lite-attestation.json | 4 ++-- verifier/fixtures/tdx-lite-getquote.json | 9 ++++----- verifier/fixtures/tdx-lite.README.md | 7 ++++--- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/guest-agent/rpc/build.rs b/guest-agent/rpc/build.rs index fe19530a5..bc584fdbe 100644 --- a/guest-agent/rpc/build.rs +++ b/guest-agent/rpc/build.rs @@ -11,6 +11,10 @@ fn main() { .build_scale_ext(false) .disable_package_emission() .enable_serde_extension() + .field_attribute( + ".dstack_guest.GetQuoteResponse.attestation", + "#[serde(skip_serializing_if = \"::prost::alloc::vec::Vec::is_empty\")]", + ) .disable_service_name_emission() .compile_dir("./proto") .expect("failed to compile proto files"); diff --git a/guest-agent/rpc/proto/agent_rpc.proto b/guest-agent/rpc/proto/agent_rpc.proto index 3226d2ef3..3b74289a7 100644 --- a/guest-agent/rpc/proto/agent_rpc.proto +++ b/guest-agent/rpc/proto/agent_rpc.proto @@ -200,9 +200,8 @@ message GetQuoteResponse { // Hw config string vm_config = 4; // Platform-adaptive versioned attestation (SCALE/msgpack encoded). Populated - // for every TEE platform (TDX, AMD SEV-SNP, ...) and is the verifier-ready - // payload to send to dstack-verifier's `/verify` `attestation` field. Use - // this instead of `quote`/`event_log` for platform-agnostic verification. + // on non-TDX TEE platforms (AMD SEV-SNP, ...). TDX uses `quote` + `event_log` + // above to keep this response compact. bytes attestation = 5; } diff --git a/guest-agent/src/backend.rs b/guest-agent/src/backend.rs index 55af0947b..2e5f32dc3 100644 --- a/guest-agent/src/backend.rs +++ b/guest-agent/src/backend.rs @@ -37,12 +37,16 @@ impl PlatformBackend for RealPlatform { let attestation = Attestation::quote(&report_data).context("Failed to get quote")?; let tdx_quote = attestation.get_tdx_quote_bytes(); let tdx_event_log = attestation.get_tdx_event_log_string_for_config(vm_config); - // Always carry the platform-adaptive versioned attestation so callers on - // non-TDX platforms (AMD SEV-SNP) still get a verifier-ready payload. - let versioned = attestation - .into_versioned() - .to_bytes() - .context("Failed to encode versioned attestation")?; + // TDX callers already have quote + event_log. Only non-TDX platforms + // need the platform-adaptive versioned attestation payload. + let versioned = if tdx_quote.is_some() { + Vec::new() + } else { + attestation + .into_versioned() + .to_bytes() + .context("Failed to encode versioned attestation")? + }; Ok(GetQuoteResponse { quote: tdx_quote.unwrap_or_default(), event_log: tdx_event_log.unwrap_or_default(), diff --git a/guest-agent/src/rpc_service.rs b/guest-agent/src/rpc_service.rs index 984da23b7..fd0324f6e 100644 --- a/guest-agent/src/rpc_service.rs +++ b/guest-agent/src/rpc_service.rs @@ -839,10 +839,6 @@ pNs85uhOZE8z2jr8Pg== let Some(quote) = attestation.platform.tdx_quote().map(ToOwned::to_owned) else { return Err(anyhow::anyhow!("Quote not found")); }; - let versioned = VersionedAttestation::V1 { - attestation: attestation.clone(), - } - .to_bytes()?; Ok(GetQuoteResponse { quote, event_log: serde_json::to_string( @@ -851,7 +847,7 @@ pNs85uhOZE8z2jr8Pg== .unwrap_or_default(), report_data: report_data.to_vec(), vm_config: vm_config.to_string(), - attestation: versioned, + attestation: Vec::new(), }) } @@ -1092,6 +1088,7 @@ pNs85uhOZE8z2jr8Pg== const EXPECTED_REPORT_DATA: &str = "dip1::ed25519-pk:5Pbre1Amf1hrp2V2bbfKlIfxpQb2pJAmrgmhxgVoG9s\0\0\0\0"; assert_eq!(EXPECTED_REPORT_DATA.as_bytes(), response.report_data); + assert!(response.attestation.is_empty()); } #[tokio::test] @@ -1107,6 +1104,7 @@ pNs85uhOZE8z2jr8Pg== const EXPECTED_REPORT_DATA: &str = "dip1::secp256k1c-pk:A6t_JdVkVdMAocH3f1f20WGT6JzdntxcXimUtEax8zc9"; assert_eq!(EXPECTED_REPORT_DATA.as_bytes(), response.report_data); + assert!(response.attestation.is_empty()); } #[tokio::test] diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index 3d355a527..e5fefc398 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c3165137b226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333034376132613365626261306133366234376335363332613135626535313261656432383462363538376462313737353334373033356333633436356239343533323536613838623338323431396237313530343730373636336535353731613337333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", - "vm_config": "{\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"measurement\":\"a265696d616765a36e636d646c696e655f736861333834583047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b5165137b226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333037383632383038343262373336343238376133613730643936663765333039323532383537626562343566623166393133313461326561383633646230616463303463383433316563626632396139363634303536303436333161356161623837333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index d4975289d..bd92d9429 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -1,7 +1,6 @@ { - "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"47a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", - "report_data": "646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31", - "vm_config": "{\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c\",\"measurement\":\"a265696d616765a36e636d646c696e655f736861333834583047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a3736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}", - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee9101064d6bf54e1a660c464213dc9d0d130d77a7a1cd646227268035b9cde82d16e674a8a17e113ffda3a9db45c1e35640d7dcf650e7bd55c289fc12c6c565b272dd5b3133bf3d30472f6a2491b4596557d134d9fadf7f95ee85eab7f75ff7c5646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c31cc1000000562a872eafe77503485135cd428ceba12d494e4c75f95617ccf30a47d403ecf755a3767fca1de7d44819a665f2df1d014bf1ba6ef6c69afc137dfbd725631874fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c78360000000000000000000000000000000000000000000000000000000000000000df0ff715a2498e5a61fafdc5fa6aa5bbeea6cf311f2249ab808f71d8b270fbfb20abec7d760ad3e6509c9d9ad7d1c84c131bd89f0b4c8f26e61d583d3bcb03e92000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074000000000b000080c00b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a74900a8095464785461626c65000100000000000000af96bb93f2b9b84e9462e0ba745642360090800000000000000000000a000080c0344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d679000e82946762858585858585858582d585858582d585858582d585858582d58585858585858585858585829000000c0ff0000000000400800000000000000000001000080c09dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb00d061dfe48bca93d211aa0d00e098032b8c0a00000000000000000000000000000053006500630075007200650042006f006f0074000000000001000080c06f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b009061dfe48bca93d211aa0d00e098032b8c0200000000000000000000000000000050004b000000000001000080c0d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9009861dfe48bca93d211aa0d00e098032b8c030000000000000000000000000000004b0045004b000000000001000080c008a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e1270090cbb219d73a3d9645a3bcdad00e67656f02000000000000000000000000000000640062000000000001000080c018cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d0098cbb219d73a3d9645a3bcdad00e67656f030000000000000000000000000000006400620078000000000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0001000000000000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410100000003000080c0ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641770029011890aa7a0000000000f295000000000000000000000000002a000000000000000403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff04000000000002000080c01dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c00d061dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f00720064006500720000000000000002000080c023ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c29800b90161dfe48bca93d211aa0d00e098032b8c08000000000000003e0000000000000042006f006f0074003000300030003000090100002c0055006900410070007000000004071400c9bdb87cebf8344faaea3ee4af6516a10406140021aa2c4614760345836e8ab6f46623317fff04000100000007000080c077a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d7100a043616c6c696e6720454649204170706c69636174696f6e2066726f6d20426f6f74204f7074696f6e0100000004000000c0394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f00010000000000200000006000000c047a2a3ebba0a36b47c5632a15be512aed284b6587db1775347035c3c465b9453256a88b382419b71504707663e5571a30088ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e73000200000006000000c04fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815210054ec223b8f0d0000004c696e757820696e69747264000100000007000080c0214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e000744578697420426f6f7420536572766963657320496e766f636174696f6e0100000007000080c00a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b7400a04578697420426f6f742053657276696365732052657475726e6564207769746820537563636573730300000001000008c0f9974020ef507068183313d0ca808e0d1ca9b2d1ad0c61f5784e7157c362c06536f5ddacdad4451693f48fcc72fff6244073797374656d2d707265706172696e67000300000001000008c0e115f23f600ee1a9e085dac82e912c37258c9bf23a3ea0f790fe0896f3432f6e49b6d5420295e7de50293659a5b24685186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e0300000001000008c00bdd53f6ce1e789e3dd5c3ee89da1ab0c7b300226c2323f00e56856419787f13dac4465beeb6467a2c10dd74d89080d330636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008c00bedd694f3c9f1f5eb2125b1020bbf6c03caf4063380bc0c1f667d143167b5347cba2ce26d3cb042dcd30a0b48bce4392c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae0300000001000008c098bd7e6bd3952720b65027fd494834045d06b4a714bf737a06b874638b3ea00ff402f7f583e3e3b05e921c8570433ac630626f6f742d6d722d646f6e65000300000001000008c06b6a05657daa9c0348ef6d97f3f3e28abef0665d241580b3416d12a721c8b11e94bdee05e56362d5592abd3af1cb2e06346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c0300000001000008c0bf0600a25fd3ce1be4e8b89cea8b6c64a8bb7efbcfaeb27164a6258a294af57e72ba3afc1b2f8686714b52bc5878e922306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d0300000001000008c0ba51104636900268b0e059fa3d266419d079d1e94aea26fb9fcbb8d764bf4c89a67ac271b8a0d1a3989945132a111fc72873746f726167652d66730c7a66730300000001000008c01a76b2a80a0be71eae59f80945d876351a7a3fb8e9fd1ff1cede5734aa84ea11fd72b4edfbb6f04e5a85edd114c751bd3073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450549a7a489b35dc5cc73e0a17bc32e03c7c1c54ae30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688066dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346437376333396266633931666638653638653032613133376232323365393734336363323433663836323733373434633561633564393037633565663837326462663363316664363661386439386530366162353961376661373436323662373835613438393438383732353736313165613733323662383433306136656262227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a413148473559674f7271576466375259674b4f6b486848714447476f77735832394330734265656261614c3165137b226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2236366462663831343363646333623335303561306131633062376336616464353562646462643836656636356231633965623965636261623838306437333663222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333034376132613365626261306133366234376335363332613135626535313261656432383462363538376462313737353334373033356333633436356239343533323536613838623338323431396237313530343730373636336535353731613337333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d" + "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"050bf89570575fe8fab4cb8f0a62a9e64efe8ead\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", + "report_data": "646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51", + "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index fcc668e6b..95b25f731 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -11,8 +11,9 @@ Files: `GetAppKey` flow. It contains a stripped `attestation` plus the explicit `vm_config` carrying `tdx_measurement`. - `tdx-lite-getquote.json`: raw guest-agent `GetQuoteResponse` captured - via `GetAttestationForAppKey`, including quote, event log, vm_config, and the - full versioned attestation. + via `GetAttestationForAppKey`, including quote, event log, and vm_config. + TDX `GetQuoteResponse` intentionally omits the `attestation` field to keep + the response compact. Captured with: @@ -30,7 +31,7 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) -- `vm_config.os_image_hash = 66dbf8143cdc3b3505a0a1c0b7c6add55bddbd86ef65b1c9eb9ecbab880d736c` +- `vm_config.os_image_hash = 07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d` - The top-level `event_log` and stripped attestation keep the three RTMR0 `ACPI DATA` digests and marker payloads needed by the lite verifier, plus RTMR3 runtime events. From 648e49807c95dd4da8a6562578503100829c15c9 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 07:28:36 -0700 Subject: [PATCH 10/18] fix: require SNP measured kernel cmdline --- dstack-mr/src/sev.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index dedab9453..baee71e92 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -321,18 +321,18 @@ fn build_sev_hashes_page( Ok(page) } -fn measured_kernel_cmdline(input: Option<&str>) -> String { +fn measured_kernel_cmdline(input: Option<&str>) -> Result { match input { - Some(base) if !base.trim().is_empty() => base.trim().to_string(), - _ => "console=ttyS0 loglevel=7".to_string(), + Some(base) if !base.trim().is_empty() => Ok(base.trim().to_string()), + _ => bail!("base_cmdline is required in amd sev-snp measured cmdline"), } } -fn kernel_cmdline_sha256(input: Option<&str>) -> Vec { - let cmdline = measured_kernel_cmdline(input); +fn kernel_cmdline_sha256(input: Option<&str>) -> Result> { + let cmdline = measured_kernel_cmdline(input)?; let mut cmdline_bytes = cmdline.as_bytes().to_vec(); cmdline_bytes.push(0); - Sha256::digest(&cmdline_bytes).to_vec() + Ok(Sha256::digest(&cmdline_bytes).to_vec()) } fn effective_initrd_hash_from_hex(value: &str) -> Result> { @@ -685,7 +685,7 @@ pub fn compute_expected_measurement(input: &MeasurementInput) -> Result<[u8; 48] .as_deref() .ok_or_else(|| anyhow::anyhow!("vcpu_type is required"))?; - let cmdline = measured_kernel_cmdline(input.base_cmdline.as_deref()); + let cmdline = measured_kernel_cmdline(input.base_cmdline.as_deref())?; let resolved_sections = input .ovmf_sections .iter() @@ -760,7 +760,7 @@ fn sev_os_image_measurement( // is already committed by `kernel_cmdline_sha256`. rootfs_hash_from_cmdline(input.base_cmdline.as_deref())?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(input.base_cmdline.as_deref()), + kernel_cmdline_sha256: kernel_cmdline_sha256(input.base_cmdline.as_deref())?, ovmf_hash: decode_required_hex("ovmf_hash", &input.ovmf_hash, 48)?, kernel_hash: decode_required_hex("kernel_hash", &input.kernel_hash, 32)?, initrd_hash: effective_initrd_hash_from_hex(&input.initrd_hash)?, @@ -887,7 +887,7 @@ pub fn sev_os_image_measurement_for_image_dir( rootfs_hash_from_cmdline(meta.cmdline.as_deref())?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(meta.cmdline.as_deref()), + kernel_cmdline_sha256: kernel_cmdline_sha256(meta.cmdline.as_deref())?, ovmf_hash: decode_required_hex("ovmf_hash", &ovmf.ovmf_hash, 48)?, kernel_hash: file_sha256(&image_dir.join(&meta.kernel))?, initrd_hash: file_sha256(&image_dir.join(&meta.initrd))?, @@ -1199,6 +1199,20 @@ mod tests { serde_json::to_string(input).expect("measurement input should serialize") } + #[test] + fn compute_measurement_requires_base_cmdline() { + for base_cmdline in [None, Some(" ".to_string())] { + let mut input = valid_input(); + input.base_cmdline = base_cmdline; + let err = compute_expected_measurement(&input) + .expect_err("missing measured cmdline must reject"); + assert!( + err.to_string().contains("base_cmdline is required"), + "unexpected error: {err:?}" + ); + } + } + #[test] fn measurement_input_does_not_carry_standalone_rootfs_hash() { let value = serde_json::to_value(valid_input()).expect("serialize measurement input"); From 0bb90b23ceb9e686ca6699924b2905d1552fedd5 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 07:45:37 -0700 Subject: [PATCH 11/18] fix: make SNP base cmdline mandatory --- dstack-mr/src/sev.rs | 74 +++++++++++++++++------------- kms/src/main_service.rs | 2 +- kms/src/main_service/amd_attest.rs | 7 +-- kms/src/onboard_service.rs | 2 +- vmm/src/app.rs | 15 ++++-- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index baee71e92..d5fffb501 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -50,7 +50,7 @@ pub struct OvmfSectionParam { #[serde(deny_unknown_fields)] pub struct MeasurementInput { /// Original image kernel cmdline used for SNP measured launch. - pub base_cmdline: Option, + pub base_cmdline: String, /// 48-byte OVMF GCTX launch digest seed supplied by the VMM. pub ovmf_hash: String, /// 32-byte kernel SHA-256 hash. @@ -116,7 +116,7 @@ pub fn validate_measurement_input(input: &MeasurementInput) -> Result<()> { bail!("guest_features must be non-zero"); } - rootfs_hash_from_cmdline(input.base_cmdline.as_deref())?; + rootfs_hash_from_cmdline(Some(&input.base_cmdline))?; decode_required_hex("kernel_hash", &input.kernel_hash, 32)?; decode_optional_hex("initrd_hash", &input.initrd_hash, 32)?; if input.vcpus == 0 { @@ -321,14 +321,14 @@ fn build_sev_hashes_page( Ok(page) } -fn measured_kernel_cmdline(input: Option<&str>) -> Result { - match input { - Some(base) if !base.trim().is_empty() => Ok(base.trim().to_string()), +fn measured_kernel_cmdline(input: &str) -> Result { + match input.trim() { + base if !base.is_empty() => Ok(base.to_string()), _ => bail!("base_cmdline is required in amd sev-snp measured cmdline"), } } -fn kernel_cmdline_sha256(input: Option<&str>) -> Result> { +fn kernel_cmdline_sha256(input: &str) -> Result> { let cmdline = measured_kernel_cmdline(input)?; let mut cmdline_bytes = cmdline.as_bytes().to_vec(); cmdline_bytes.push(0); @@ -685,7 +685,7 @@ pub fn compute_expected_measurement(input: &MeasurementInput) -> Result<[u8; 48] .as_deref() .ok_or_else(|| anyhow::anyhow!("vcpu_type is required"))?; - let cmdline = measured_kernel_cmdline(input.base_cmdline.as_deref())?; + let cmdline = measured_kernel_cmdline(&input.base_cmdline)?; let resolved_sections = input .ovmf_sections .iter() @@ -758,9 +758,9 @@ fn sev_os_image_measurement( // Validate that the measured command line commits the rootfs identity. The // compact image projection does not carry a separate rootfs_hash because it // is already committed by `kernel_cmdline_sha256`. - rootfs_hash_from_cmdline(input.base_cmdline.as_deref())?; + rootfs_hash_from_cmdline(Some(&input.base_cmdline))?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(input.base_cmdline.as_deref())?, + kernel_cmdline_sha256: kernel_cmdline_sha256(&input.base_cmdline)?, ovmf_hash: decode_required_hex("ovmf_hash", &input.ovmf_hash, 48)?, kernel_hash: decode_required_hex("kernel_hash", &input.kernel_hash, 32)?, initrd_hash: effective_initrd_hash_from_hex(&input.initrd_hash)?, @@ -887,7 +887,11 @@ pub fn sev_os_image_measurement_for_image_dir( rootfs_hash_from_cmdline(meta.cmdline.as_deref())?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(meta.cmdline.as_deref())?, + kernel_cmdline_sha256: kernel_cmdline_sha256( + meta.cmdline + .as_deref() + .context("metadata.json cmdline is required for amd sev-snp os_image_hash")?, + )?, ovmf_hash: decode_required_hex("ovmf_hash", &ovmf.ovmf_hash, 48)?, kernel_hash: file_sha256(&image_dir.join(&meta.kernel))?, initrd_hash: file_sha256(&image_dir.join(&meta.initrd))?, @@ -1161,7 +1165,7 @@ mod tests { fn valid_input() -> MeasurementInput { let rootfs_hash = hex_of(0x33, 32); MeasurementInput { - base_cmdline: Some(format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}")), + base_cmdline: format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}"), ovmf_hash: hex_of(0x44, 48), kernel_hash: hex_of(0x55, 32), initrd_hash: hex_of(0x66, 32), @@ -1201,16 +1205,26 @@ mod tests { #[test] fn compute_measurement_requires_base_cmdline() { - for base_cmdline in [None, Some(" ".to_string())] { - let mut input = valid_input(); - input.base_cmdline = base_cmdline; - let err = compute_expected_measurement(&input) - .expect_err("missing measured cmdline must reject"); - assert!( - err.to_string().contains("base_cmdline is required"), - "unexpected error: {err:?}" - ); - } + let mut value = serde_json::to_value(valid_input()).expect("serialize measurement input"); + value + .as_object_mut() + .expect("measurement input is an object") + .remove("base_cmdline"); + let err = serde_json::from_value::(value) + .expect_err("missing base_cmdline must reject"); + assert!( + err.to_string().contains("missing field `base_cmdline`"), + "unexpected error: {err:?}" + ); + + let mut input = valid_input(); + input.base_cmdline = " ".to_string(); + let err = + compute_expected_measurement(&input).expect_err("empty measured cmdline must reject"); + assert!( + err.to_string().contains("base_cmdline is required"), + "unexpected error: {err:?}" + ); } #[test] @@ -1242,16 +1256,13 @@ mod tests { // Image-determined fields MUST change the os_image_hash. let image_cases: Vec<(&str, fn(&mut MeasurementInput))> = vec![ ("base_cmdline.rootfs_hash", |i| { - i.base_cmdline = Some(format!( - "console=ttyS0 dstack.rootfs_hash={}", - hex_of(0x34, 32) - )) + i.base_cmdline = format!("console=ttyS0 dstack.rootfs_hash={}", hex_of(0x34, 32)) }), ("base_cmdline", |i| { - i.base_cmdline = Some(format!( + i.base_cmdline = format!( "console=ttyS0 loglevel=8 dstack.rootfs_hash={}", hex_of(0x33, 32) - )) + ) }), ("ovmf_hash", |i| i.ovmf_hash = hex_of(0x45, 48)), ("kernel_hash", |i| i.kernel_hash = hex_of(0x56, 32)), @@ -1462,10 +1473,10 @@ mod tests { let (input, mr_config, measurement, host_data, _vm_config) = honest_case(); let cases: Vec<(&str, fn(&mut MeasurementInput))> = vec![ ("base_cmdline", |i| { - i.base_cmdline = Some(format!( + i.base_cmdline = format!( "console=ttyS0 evil=1 dstack.rootfs_hash={}", hex_of(0x33, 32) - )) + ) }), ("ovmf_hash", |i| i.ovmf_hash = hex_of(0x99, 48)), ("kernel_hash", |i| i.kernel_hash = hex_of(0x99, 32)), @@ -1508,10 +1519,7 @@ mod tests { .expect("honest launch verifies"); let mut tampered = input.clone(); - tampered.base_cmdline = Some(format!( - "console=ttyS0 dstack.rootfs_hash={}", - hex_of(0x99, 32) - )); + tampered.base_cmdline = format!("console=ttyS0 dstack.rootfs_hash={}", hex_of(0x99, 32)); let tampered_vm = synthetic_vm_config(&tampered, &mr_config); let err = verify_sev_launch(&measurement, &host_data, &tampered_vm) .expect_err("tampered rootfs hash in cmdline must not verify"); diff --git a/kms/src/main_service.rs b/kms/src/main_service.rs index 17b6f5948..ca40541d3 100644 --- a/kms/src/main_service.rs +++ b/kms/src/main_service.rs @@ -566,7 +566,7 @@ mod tests { fn valid_snp_measurement_input() -> MeasurementInput { let rootfs_hash = hex_of(0x33, 32); MeasurementInput { - base_cmdline: Some(format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}")), + base_cmdline: format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}"), ovmf_hash: hex_of(0x44, 48), kernel_hash: hex_of(0x55, 32), initrd_hash: hex_of(0x66, 32), diff --git a/kms/src/main_service/amd_attest.rs b/kms/src/main_service/amd_attest.rs index 48688c6a9..da6831170 100644 --- a/kms/src/main_service/amd_attest.rs +++ b/kms/src/main_service/amd_attest.rs @@ -212,7 +212,7 @@ mod tests { fn valid_input() -> MeasurementInput { let rootfs_hash = hex_of(0x33, 32); MeasurementInput { - base_cmdline: Some(format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}")), + base_cmdline: format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}"), ovmf_hash: hex_of(0x44, 48), kernel_hash: hex_of(0x55, 32), initrd_hash: hex_of(0x66, 32), @@ -681,10 +681,7 @@ mod tests { #[test] fn rejects_empty_or_malformed_binding_hashes() { let mut input = valid_input(); - input.base_cmdline = Some(format!( - "console=ttyS0 dstack.rootfs_hash={}", - hex_of(0x33, 31) - )); + input.base_cmdline = format!("console=ttyS0 dstack.rootfs_hash={}", hex_of(0x33, 31)); assert_rejects(input, "dstack.rootfs_hash must be 32 bytes"); let mut input = valid_input(); diff --git a/kms/src/onboard_service.rs b/kms/src/onboard_service.rs index 79a8d1085..272e5dc56 100644 --- a/kms/src/onboard_service.rs +++ b/kms/src/onboard_service.rs @@ -205,7 +205,7 @@ mod tests { fn valid_snp_measurement_input() -> MeasurementInput { let rootfs_hash = hex_of(0x33, 32); MeasurementInput { - base_cmdline: Some(format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}")), + base_cmdline: format!("console=ttyS0 dstack.rootfs_hash={rootfs_hash}"), ovmf_hash: hex_of(0x44, 48), kernel_hash: hex_of(0x55, 32), initrd_hash: hex_of(0x66, 32), diff --git a/vmm/src/app.rs b/vmm/src/app.rs index 288453d19..56893a674 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1324,8 +1324,11 @@ fn amd_sev_snp_ovmf_measurement_info(image: &Image) -> Result) -> Option { - base_cmdline.map(|cmdline| cmdline.trim().to_string()) +fn amd_sev_snp_measurement_base_cmdline(base_cmdline: Option<&str>) -> Result { + match base_cmdline.map(str::trim) { + Some(cmdline) if !cmdline.is_empty() => Ok(cmdline.to_string()), + _ => anyhow::bail!("metadata.json cmdline is required for amd sev-snp measurement"), + } } fn sha256_file(path: impl AsRef) -> Result<[u8; 32]> { @@ -1419,7 +1422,7 @@ fn make_vm_config( } let ovmf = amd_sev_snp_ovmf_measurement_info(image)?; let measurement = json!({ - "base_cmdline": amd_sev_snp_measurement_base_cmdline(image.info.cmdline.as_deref()), + "base_cmdline": amd_sev_snp_measurement_base_cmdline(image.info.cmdline.as_deref())?, "ovmf_hash": ovmf.ovmf_hash, "kernel_hash": file_sha256_hex(&image.kernel)?, "initrd_hash": file_sha256_hex(&image.initrd)?, @@ -1539,9 +1542,11 @@ mod tests { #[test] fn amd_sev_snp_measurement_base_cmdline_trims_image_cmdline() { assert_eq!( - amd_sev_snp_measurement_base_cmdline(Some(" console=ttyS0 loglevel=7 ")), - Some("console=ttyS0 loglevel=7".to_string()) + amd_sev_snp_measurement_base_cmdline(Some(" console=ttyS0 loglevel=7 ")).unwrap(), + "console=ttyS0 loglevel=7" ); + assert!(amd_sev_snp_measurement_base_cmdline(None).is_err()); + assert!(amd_sev_snp_measurement_base_cmdline(Some(" ")).is_err()); } #[test] From 75397c1d54b1b6aff8b1858d7661dead1ea2f87f Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 07:57:01 -0700 Subject: [PATCH 12/18] refactor: avoid special casing empty SNP cmdline --- dstack-mr/src/sev.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index d5fffb501..59e96a1de 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -321,18 +321,15 @@ fn build_sev_hashes_page( Ok(page) } -fn measured_kernel_cmdline(input: &str) -> Result { - match input.trim() { - base if !base.is_empty() => Ok(base.to_string()), - _ => bail!("base_cmdline is required in amd sev-snp measured cmdline"), - } +fn measured_kernel_cmdline(input: &str) -> String { + input.trim().to_string() } -fn kernel_cmdline_sha256(input: &str) -> Result> { - let cmdline = measured_kernel_cmdline(input)?; +fn kernel_cmdline_sha256(input: &str) -> Vec { + let cmdline = measured_kernel_cmdline(input); let mut cmdline_bytes = cmdline.as_bytes().to_vec(); cmdline_bytes.push(0); - Ok(Sha256::digest(&cmdline_bytes).to_vec()) + Sha256::digest(&cmdline_bytes).to_vec() } fn effective_initrd_hash_from_hex(value: &str) -> Result> { @@ -685,7 +682,7 @@ pub fn compute_expected_measurement(input: &MeasurementInput) -> Result<[u8; 48] .as_deref() .ok_or_else(|| anyhow::anyhow!("vcpu_type is required"))?; - let cmdline = measured_kernel_cmdline(&input.base_cmdline)?; + let cmdline = measured_kernel_cmdline(&input.base_cmdline); let resolved_sections = input .ovmf_sections .iter() @@ -760,7 +757,7 @@ fn sev_os_image_measurement( // is already committed by `kernel_cmdline_sha256`. rootfs_hash_from_cmdline(Some(&input.base_cmdline))?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(&input.base_cmdline)?, + kernel_cmdline_sha256: kernel_cmdline_sha256(&input.base_cmdline), ovmf_hash: decode_required_hex("ovmf_hash", &input.ovmf_hash, 48)?, kernel_hash: decode_required_hex("kernel_hash", &input.kernel_hash, 32)?, initrd_hash: effective_initrd_hash_from_hex(&input.initrd_hash)?, @@ -891,7 +888,7 @@ pub fn sev_os_image_measurement_for_image_dir( meta.cmdline .as_deref() .context("metadata.json cmdline is required for amd sev-snp os_image_hash")?, - )?, + ), ovmf_hash: decode_required_hex("ovmf_hash", &ovmf.ovmf_hash, 48)?, kernel_hash: file_sha256(&image_dir.join(&meta.kernel))?, initrd_hash: file_sha256(&image_dir.join(&meta.initrd))?, @@ -1204,7 +1201,7 @@ mod tests { } #[test] - fn compute_measurement_requires_base_cmdline() { + fn measurement_input_requires_base_cmdline() { let mut value = serde_json::to_value(valid_input()).expect("serialize measurement input"); value .as_object_mut() @@ -1220,9 +1217,9 @@ mod tests { let mut input = valid_input(); input.base_cmdline = " ".to_string(); let err = - compute_expected_measurement(&input).expect_err("empty measured cmdline must reject"); + validate_measurement_input(&input).expect_err("empty measured cmdline must reject"); assert!( - err.to_string().contains("base_cmdline is required"), + err.to_string().contains("dstack.rootfs_hash is required"), "unexpected error: {err:?}" ); } From 4cc8516fd2011d02b662a1c2d11d784ec4a463c1 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 08:08:30 -0700 Subject: [PATCH 13/18] refactor: remove stable ovmf variant support --- dstack-mr/cli/src/main.rs | 5 +- dstack-mr/src/lib.rs | 49 ++++--------- dstack-mr/src/machine.rs | 2 +- dstack-mr/src/tdvf.rs | 107 --------------------------- dstack-mr/src/uefi_var.rs | 135 ----------------------------------- dstack-types/src/lib.rs | 19 +---- verifier/src/verification.rs | 5 +- 7 files changed, 22 insertions(+), 300 deletions(-) delete mode 100644 dstack-mr/src/uefi_var.rs diff --git a/dstack-mr/cli/src/main.rs b/dstack-mr/cli/src/main.rs index 0898e7015..fb78808e2 100644 --- a/dstack-mr/cli/src/main.rs +++ b/dstack-mr/cli/src/main.rs @@ -78,9 +78,8 @@ struct MachineConfig { #[arg(long)] qemu_version: Option, - /// dstack OS version (MAJOR.MINOR.PATCH), used to pick the OVMF measurement layout. - /// 0.5.10 <= ver < 0.6.0 and ver >= 0.6.1 use the edk2-stable202505 layout; everything - /// else uses the legacy layout. If omitted, falls back to `image_info.version`. + /// dstack OS version (MAJOR.MINOR.PATCH), validated before using the supported OVMF + /// measurement layout. If omitted, falls back to `image_info.version`. #[arg(long)] dstack_os_version: Option, diff --git a/dstack-mr/src/lib.rs b/dstack-mr/src/lib.rs index 2513c2897..00385a05f 100644 --- a/dstack-mr/src/lib.rs +++ b/dstack-mr/src/lib.rs @@ -22,13 +22,12 @@ mod num; pub mod sev; mod tdvf; pub mod tdx; -mod uefi_var; mod util; -/// Pick the OVMF variant for a given dstack OS version string ("MAJOR.MINOR.PATCH"). +/// Return the supported OVMF variant for a dstack OS version string ("MAJOR.MINOR.PATCH"). /// -/// Treats `0.5.10 <= v < 0.6.0` and `v >= 0.6.1` as `Stable202505`, everything else as -/// `Pre202505`. Used as a fallback when `VmConfig::ovmf_variant` is absent. +/// The version is still parsed for compatibility with callers that validate the +/// OS version through this helper, but all valid versions use `Pre202505`. pub fn ovmf_variant_for_version(version: &str) -> Result { let parts: Vec = version .split('.') @@ -40,13 +39,7 @@ pub fn ovmf_variant_for_version(version: &str) -> Result { if parts.len() != 3 { bail!("expected MAJOR.MINOR.PATCH, got {version}"); } - let v = (parts[0], parts[1], parts[2]); - let stable = ((0, 5, 10)..(0, 6, 0)).contains(&v) || v >= (0, 6, 1); - Ok(if stable { - OvmfVariant::Stable202505 - } else { - OvmfVariant::Pre202505 - }) + Ok(OvmfVariant::Pre202505) } /// Extract the `MAJOR.MINOR.PATCH` version suffix from a dstack image name. @@ -57,7 +50,7 @@ pub fn ovmf_variant_for_version(version: &str) -> Result { /// /// The optional `.SUFFIX` is permitted to be non-numeric (pre-release tag, /// build label, etc.) and is dropped from the returned slice — only the -/// numeric `X.Y.Z` is needed to pick the OVMF variant. +/// numeric `X.Y.Z` is needed to validate the image version. /// /// Returns `None` when the segment after the last `-` is not at least a valid /// `X.Y.Z` triple of non-empty numeric components. @@ -79,7 +72,7 @@ pub fn extract_version_from_image_name(image: &str) -> Option<&str> { Some(&tail[..core_len]) } -/// Pick the OVMF variant from an image name like `dstack-0.5.10`. +/// Return the supported OVMF variant from an image name like `dstack-0.5.10`. /// /// Falls back to `OvmfVariant::default()` (= `Pre202505`) when the image name is /// missing or doesn't carry a parseable version suffix. Use this only as a @@ -96,8 +89,11 @@ mod ovmf_variant_tests { use super::*; #[test] - fn pre_202505_for_old_versions() { - for v in ["0.4.99", "0.5.7", "0.5.8", "0.5.9", "0.6.0"] { + fn pre_202505_for_all_versions() { + for v in [ + "0.4.99", "0.5.7", "0.5.8", "0.5.9", "0.5.10", "0.5.99", "0.6.0", "0.6.1", "0.6.2", + "0.7.0", "1.0.0", + ] { assert_eq!( ovmf_variant_for_version(v).unwrap(), OvmfVariant::Pre202505, @@ -106,17 +102,6 @@ mod ovmf_variant_tests { } } - #[test] - fn stable_202505_for_new_versions() { - for v in ["0.5.10", "0.5.99", "0.6.1", "0.6.2", "0.7.0", "1.0.0"] { - assert_eq!( - ovmf_variant_for_version(v).unwrap(), - OvmfVariant::Stable202505, - "{v}" - ); - } - } - #[test] fn rejects_malformed_version() { assert!(ovmf_variant_for_version("0.5").is_err()); @@ -179,11 +164,11 @@ mod ovmf_variant_tests { ); assert_eq!( ovmf_variant_for_image(Some("dstack-0.5.10")), - OvmfVariant::Stable202505 + OvmfVariant::Pre202505 ); assert_eq!( ovmf_variant_for_image(Some("dstack-nvidia-dev-0.6.1")), - OvmfVariant::Stable202505 + OvmfVariant::Pre202505 ); } @@ -194,12 +179,8 @@ mod ovmf_variant_tests { "\"pre202505\"" ); assert_eq!( - serde_json::to_string(&OvmfVariant::Stable202505).unwrap(), - "\"stable202505\"" - ); - assert_eq!( - serde_json::from_str::("\"stable202505\"").unwrap(), - OvmfVariant::Stable202505 + serde_json::from_str::("\"pre202505\"").unwrap(), + OvmfVariant::Pre202505 ); } } diff --git a/dstack-mr/src/machine.rs b/dstack-mr/src/machine.rs index 756a21ee4..823470d23 100644 --- a/dstack-mr/src/machine.rs +++ b/dstack-mr/src/machine.rs @@ -33,7 +33,7 @@ pub struct Machine<'a> { #[builder(default)] pub host_share_mode: String, /// Selects which OVMF measurement event layout to expect. - /// Defaults to the pre-edk2-stable202505 layout for backwards compatibility. + /// Defaults to the supported pre-202505 layout. #[builder(default)] pub ovmf_variant: OvmfVariant, } diff --git a/dstack-mr/src/tdvf.rs b/dstack-mr/src/tdvf.rs index 74388dde8..3b6b7d3af 100644 --- a/dstack-mr/src/tdvf.rs +++ b/dstack-mr/src/tdvf.rs @@ -9,35 +9,11 @@ use sha2::{Digest, Sha384}; use crate::acpi::Tables; use crate::num::read_le; -use crate::uefi_var::{ - boot_option_bytes, boot_order_bytes, fv_file_node, fv_node, END_OF_DEVICE_PATH, -}; use crate::{measure_log, measure_sha384, utf16_encode, Machine, OvmfVariant, RtmrLog}; const PAGE_SIZE: u64 = 0x1000; const MR_EXTEND_GRANULARITY: usize = 0x100; -// OVMF firmware-volume identifiers used by edk2-stable202505. These are baked -// into the OVMF binary at build time; if the firmware is regenerated against a -// different EDK2 source these constants may need refreshing. -// -// Each GUID is stored in the on-the-wire little-endian byte form OVMF puts in -// the EFI_DEVICE_PATH MEDIA_FV / MEDIA_FV_FILE nodes — the first three GUID -// fields are byte-swapped relative to the canonical string form. -// -// canonical: 7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1 -const OVMF_FV_GUID_LE: [u8; 16] = [ - 0xc9, 0xbd, 0xb8, 0x7c, 0xeb, 0xf8, 0x34, 0x4f, 0xaa, 0xea, 0x3e, 0xe4, 0xaf, 0x65, 0x16, 0xa1, -]; -// canonical: eec25bdc-67f2-4d95-b1d5-f81b2039d11d (MdeModulePkg UiApp) -const OVMF_UIAPP_FILE_GUID_LE: [u8; 16] = [ - 0xdc, 0x5b, 0xc2, 0xee, 0xf2, 0x67, 0x95, 0x4d, 0xb1, 0xd5, 0xf8, 0x1b, 0x20, 0x39, 0xd1, 0x1d, -]; -// canonical: 462caa21-7614-4503-836e-8ab6f4662331 (MdeModulePkg BootMaintenance / FrontPage) -const OVMF_FRONTPAGE_FILE_GUID_LE: [u8; 16] = [ - 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31, -]; - const ATTRIBUTE_MR_EXTEND: u32 = 0x00000001; const ATTRIBUTE_PAGE_AUG: u32 = 0x00000002; @@ -91,89 +67,6 @@ pub(crate) fn rtmr0_log_from_td_hob_hash_with_acpi_hashes( boot000_hash.to_vec(), ] } - OvmfVariant::Stable202505 => { - // edk2-stable202505 emits 17 RTMR[0] events instead of 13. - // Everything except the three QEMU-generated ACPI blob digests is - // derivable from dstack's launch policy and the shipped OVMF build. - - // fw_cfg `BootMenu` is a u16; dstack doesn't pass `-boot - // menu=on`, so it defaults to 0x0000. - let bootmenu_fwcfg_hash = measure_sha384(&[0x00, 0x00]); - - // fw_cfg `bootorder` is the NUL-separated list of QEMU device - // paths whose backing devices have `bootindex` set. For - // `-kernel` boot, QEMU (hw/i386/x86.c::x86_load_linux) injects - // a single option ROM with `bootindex = 0`: - // * `linuxboot_dma.bin` if fw_cfg DMA is enabled (q35 default) - // * `linuxboot.bin` otherwise - // dstack-vmm always uses q35 → DMA is on → the bootorder file - // contains just the single path below (31 bytes, trailing NUL). - // No other dstack device gets an implicit bootindex. - // - // Verified end-to-end: gdb-attached the live QEMU and called - // get_boot_devices_list() — returned exactly these 31 bytes. - let bootorder_fwcfg_hash = measure_sha384(b"/rom@genroms/linuxboot_dma.bin\0"); - - // EV_EFI_VARIABLE_AUTHORITY: OVMF emits this once during BDS even - // when Secure Boot is disabled. The 32-byte event blob in the log is - // a sentinel; the actual measured payload is OVMF-internal. - // Captured digest is a constant for the edk2-stable202505 build - // dstack ships. - let variable_authority_hash = - hex!("FB66919801F1DFC9C4C273B6A739380790CB0FD3CB706A42F6AC050510EBC8618E7FBA53A1564522F5C6F0DC9E1F41A6"); - - // BootOrder UEFI variable holds [0x0000, 0x0001] — the two boot - // options OVMF's BDS publishes (UiApp and FrontPage). The TCG digest - // for `EV_EFI_VARIABLE_BOOT2` is over the raw variable data, NOT a - // UEFI_VARIABLE_DATA wrapper. - let boot_order_var_hash = measure_sha384(&boot_order_bytes(&[0x0000, 0x0001])); - - // Boot0000 = OVMF's BootManagerMenuApp; Boot0001 = "EFI Firmware - // Setup" (FrontPage). Both live in the OVMF FV and are baked into - // the firmware at build time. The attribute bits and descriptions - // come from MdeModulePkg's BdsBootManagerLib in edk2-stable202505. - // 0x101 = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_APP - // 0x109 = + LOAD_OPTION_HIDDEN - let boot0000_hash = measure_sha384(&boot_option_bytes( - 0x0000_0109, - "BootManagerMenuApp", - &[ - fv_node(&OVMF_FV_GUID_LE), - fv_file_node(&OVMF_UIAPP_FILE_GUID_LE), - END_OF_DEVICE_PATH, - ], - &[], - )); - let boot0001_hash = measure_sha384(&boot_option_bytes( - 0x0000_0101, - "EFI Firmware Setup", - &[ - fv_node(&OVMF_FV_GUID_LE), - fv_file_node(&OVMF_FRONTPAGE_FILE_GUID_LE), - END_OF_DEVICE_PATH, - ], - &[], - )); - vec![ - td_hob_hash, - cfv_image_hash.to_vec(), - bootmenu_fwcfg_hash, - bootorder_fwcfg_hash.to_vec(), - secureboot_hash, - pk_hash, - kek_hash, - db_hash, - dbx_hash, - separator_hash, - acpi_hashes.loader.clone(), - acpi_hashes.rsdp.clone(), - acpi_hashes.tables.clone(), - variable_authority_hash.to_vec(), - boot_order_var_hash, - boot0000_hash, - boot0001_hash, - ] - } }; Ok(log) diff --git a/dstack-mr/src/uefi_var.rs b/dstack-mr/src/uefi_var.rs deleted file mode 100644 index b3d0c6040..000000000 --- a/dstack-mr/src/uefi_var.rs +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-FileCopyrightText: © 2025 Phala Network -// -// SPDX-License-Identifier: Apache-2.0 - -//! Helpers for synthesising the UEFI variable byte blobs that OVMF measures -//! into RTMR[0] as `EV_EFI_VARIABLE_BOOT2` events. -//! -//! For the BootOrder / Boot#### variables the TCG PFP spec digest is taken -//! over the *variable data* portion only (not the full `UEFI_VARIABLE_DATA` -//! struct), so we just build the on-the-wire variable contents here. - -use crate::utf16_encode; - -/// Build the raw bytes of a `BootOrder` UEFI variable from a sequence of boot -/// option numbers — each entry is a little-endian `u16` referring to a -/// `Boot####` variable. -pub fn boot_order_bytes(entries: &[u16]) -> Vec { - let mut out = Vec::with_capacity(entries.len() * 2); - for &entry in entries { - out.extend_from_slice(&entry.to_le_bytes()); - } - out -} - -/// An `EFI_DEVICE_PATH_PROTOCOL` node. -#[derive(Clone, Copy)] -pub struct DevicePathNode<'a> { - pub r#type: u8, - pub subtype: u8, - pub data: &'a [u8], -} - -impl DevicePathNode<'_> { - fn write_to(self, buf: &mut Vec) { - let len = 4 + self.data.len(); - buf.push(self.r#type); - buf.push(self.subtype); - buf.extend_from_slice(&(len as u16).to_le_bytes()); - buf.extend_from_slice(self.data); - } -} - -/// `END_ENTIRE_DEVICE_PATH` terminator. -pub const END_OF_DEVICE_PATH: DevicePathNode<'static> = DevicePathNode { - r#type: 0x7f, - subtype: 0xff, - data: &[], -}; - -/// `MEDIA_DEVICE_PATH / Firmware Volume` node (`type=4, subtype=7`). -pub fn fv_node(guid_le: &[u8; 16]) -> DevicePathNode<'_> { - DevicePathNode { - r#type: 0x04, - subtype: 0x07, - data: guid_le, - } -} - -/// `MEDIA_DEVICE_PATH / Firmware File` node (`type=4, subtype=6`). -pub fn fv_file_node(guid_le: &[u8; 16]) -> DevicePathNode<'_> { - DevicePathNode { - r#type: 0x04, - subtype: 0x06, - data: guid_le, - } -} - -/// Build the raw bytes of a `Boot####` UEFI variable — the on-the-wire form of -/// `EFI_LOAD_OPTION { Attributes, FilePathListLength, Description, FilePathList, -/// OptionalData }`. -/// -/// The description is automatically NUL-terminated in UTF-16LE. -pub fn boot_option_bytes( - attributes: u32, - description: &str, - file_path_nodes: &[DevicePathNode<'_>], - optional_data: &[u8], -) -> Vec { - // Serialise the device-path list first so we know its length. - let mut file_path = Vec::new(); - for node in file_path_nodes { - node.write_to(&mut file_path); - } - - let mut desc = utf16_encode(description); - desc.extend_from_slice(&[0x00, 0x00]); // NUL terminator - - let mut out = Vec::with_capacity(4 + 2 + desc.len() + file_path.len() + optional_data.len()); - out.extend_from_slice(&attributes.to_le_bytes()); - out.extend_from_slice(&(file_path.len() as u16).to_le_bytes()); - out.extend_from_slice(&desc); - out.extend_from_slice(&file_path); - out.extend_from_slice(optional_data); - out -} - -#[cfg(test)] -mod tests { - use super::*; - use sha2::{Digest, Sha384}; - - fn sha384(bytes: &[u8]) -> String { - hex::encode(Sha384::new_with_prefix(bytes).finalize()) - } - - #[test] - fn boot_option_round_trip_sample() { - // Trivial sanity check: a load option with one MEDIA_FV_FILE node and - // an empty description should serialise to a 4 (Attrs) + 2 (FpLen) + - // 2 (NUL) + (4 + 16) (FV_FILE) + 4 (END) = 32 byte blob, and - // round-tripping the descriptive string survives. - let blob = boot_option_bytes(1, "", &[fv_file_node(&[0; 16]), END_OF_DEVICE_PATH], &[]); - assert_eq!(blob.len(), 4 + 2 + 2 + 20 + 4); - assert_eq!(&blob[0..4], &[0x01, 0x00, 0x00, 0x00]); - assert_eq!(&blob[4..6], &[0x18, 0x00]); // FilePathListLength = 24 - // Description is just a NUL terminator (two bytes of 0). - assert_eq!(&blob[6..8], &[0x00, 0x00]); - } - - #[test] - fn boot_order_encodes_u16_le_entries() { - assert_eq!( - boot_order_bytes(&[0x0000, 0x0001]), - vec![0x00, 0x00, 0x01, 0x00] - ); - assert_eq!( - boot_order_bytes(&[0x1234, 0xabcd]), - vec![0x34, 0x12, 0xcd, 0xab] - ); - assert_eq!( - sha384(&boot_order_bytes(&[0x0000, 0x0001])), - "52b9a02de946b947364b57d8210c63113b9058996e2a3ba7cead54af11ae0873b085d1e52bc01e4febe57ca05ca1332b" - ); - } -} diff --git a/dstack-types/src/lib.rs b/dstack-types/src/lib.rs index 69d5000e5..ab0b5a229 100644 --- a/dstack-types/src/lib.rs +++ b/dstack-types/src/lib.rs @@ -11,40 +11,25 @@ use size_parser::human_size; /// Identifies which OVMF flavour the guest image was built with. /// -/// The firmware switch happened in meta-dstack commit f9f11f3 (upgrade from an -/// untagged 2024-09 snapshot to edk2-stable202505): 0.5.7 and earlier shipped -/// `Pre202505`, 0.5.9 onwards ships `Stable202505`. The newer firmware emits -/// more boot-time events into RTMR[0], so quote replay needs a different -/// expected event list for the two flavours. -/// -/// When the variant isn't carried explicitly in `VmConfig`, the runtime cutoff -/// rule in `dstack_mr::ovmf_variant_for_version` draws the line at OS version -/// `0.5.10` (and again at `0.6.1`) — a deliberate policy decision that doesn't -/// follow the firmware-flip date exactly. See that function's docs for the -/// authoritative selection rule. +/// Only the pre-202505 OVMF measurement layout is supported. #[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, Default)] #[serde(rename_all = "snake_case")] pub enum OvmfVariant { - /// Pre-edk2-stable202505 OVMF (13 RTMR[0] events). + /// Pre-202505 OVMF (13 RTMR[0] events). #[default] Pre202505, - /// edk2-stable202505+ OVMF (17 RTMR[0] events: new fw_cfg, VARIABLE_AUTHORITY - /// and BootXXXX entries). - Stable202505, } impl OvmfVariant { pub fn to_u8(self) -> u8 { match self { Self::Pre202505 => 0, - Self::Stable202505 => 1, } } pub fn from_u8(value: u8) -> Option { match value { 0 => Some(Self::Pre202505), - 1 => Some(Self::Stable202505), _ => None, } } diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index 56c0744c7..ecddf017e 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -140,9 +140,8 @@ fn collect_rtmr_mismatch( } // Bump whenever expected RTMR computation changes so stale entries get ignored. -// v2: edk2-stable202505 OVMF RTMR[0] layout (added 4 events, reshaped BootOrder -// and Boot0000); the legacy 13-event log no longer matches any in-field image. -const MEASUREMENT_CACHE_VERSION: u32 = 2; +// v3: all supported OVMF measurements use the Pre202505 RTMR[0] layout. +const MEASUREMENT_CACHE_VERSION: u32 = 3; #[derive(Clone, Serialize, Deserialize)] struct CachedMeasurement { From c40c99c52dd5a27ec03e86839932a559e9ab39af Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 18:10:32 -0700 Subject: [PATCH 14/18] docs: explain tdx lite acpi trust boundary --- docs/security/security-model.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/security/security-model.md b/docs/security/security-model.md index fc5ad8475..6a5c24ee1 100644 --- a/docs/security/security-model.md +++ b/docs/security/security-model.md @@ -124,6 +124,29 @@ This is also reflected at the source: the event log shipped alongside an attesta The reason boot-time event log entries (RTMR0-2) are dropped is that **nothing downstream consumes them**. Verification recomputes the OS-layer measurements directly from the signed `rt_mr0/1/2` values and compares them to independently reproduced expected measurements, so the corresponding boot event log would be redundant. Keeping it would only bloat the RA-TLS certificate and expose extra detail without adding any verification capability. RTMR3, by contrast, is runtime-extended (compose-hash, key-provider, instance-id, and application-emitted events), so its event log is the only one with a real consumer — the replay that proves what was extended into RTMR3. +### Why TDX lite mode does not validate ACPI table contents + +TDX lite mode verifies the OS image without downloading the image and without +running QEMU to regenerate ACPI tables. It still uses the three RTMR0 `ACPI +DATA` digests from the attestation event log as opaque measurement inputs and +checks that the recomputed RTMR values match the hardware-signed quote. What it +does not do is reconstruct and byte-compare the full ACPI table contents. + +This is safe for dstack's threat model because ACPI tables are treated as +untrusted host-provided platform description, not as trusted guest code. The +dangerous executable part of ACPI is AML (ACPI Machine Language): malicious AML +can try to use `SystemMemory` operation regions through the Linux ACPICA +interpreter to read or write guest physical memory. dstack kernels include the +BadAML sandbox patch (`0002-acpi-sandbox-block-aml-systemmemory-ram-access.patch`), +which hooks the ACPI `SystemMemory` region handler, walks the guest page tables, +and denies AML access to encrypted/private guest RAM. AML can only access +unencrypted/shared mappings. + +Therefore, an infrastructure operator can still provide bad ACPI data and cause +misconfiguration or denial of service, but unvalidated ACPI/AML cannot tamper +with confidential private memory or extract secrets. That residual availability +risk is already outside dstack's confidentiality/integrity guarantees. + ### TCB status is surfaced, not gated, during verification dstack's `validate_tcb` does not reject a quote based on its TCB status string (`UpToDate`, `OutOfDate`, `ConfigurationNeeded`, `SWHardeningNeeded`, ...). It only enforces hard invariants: debug mode must be off, and the SEAM/service-TD measurements must be well-formed. The verified report carries the `status` field through to the caller. From c384a6328f37edee236d9076432edc0094f42475 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 18:31:46 -0700 Subject: [PATCH 15/18] refactor: label tdx lite acpi events --- cc-eventlog/src/tdx.rs | 71 ++++++++ docs/security/security-model.md | 8 +- dstack-attest/src/v1.rs | 13 +- verifier/fixtures/tdx-lite-attestation.json | 2 +- verifier/fixtures/tdx-lite-getquote.json | 2 +- verifier/fixtures/tdx-lite.README.md | 6 +- verifier/src/verification.rs | 170 +++++++++++--------- 7 files changed, 179 insertions(+), 93 deletions(-) diff --git a/cc-eventlog/src/tdx.rs b/cc-eventlog/src/tdx.rs index bf7d677c0..5cdeb2aeb 100644 --- a/cc-eventlog/src/tdx.rs +++ b/cc-eventlog/src/tdx.rs @@ -11,6 +11,17 @@ use crate::{ tcg::TcgEventLog, }; +pub const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; +pub const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; +pub const TDX_ACPI_LOADER_EVENT: &str = "acpi-loader"; +pub const TDX_ACPI_RSDP_EVENT: &str = "acpi-rsdp"; +pub const TDX_ACPI_TABLES_EVENT: &str = "acpi-tables"; +pub const TDX_ACPI_DATA_EVENT_NAMES: [&str; 3] = [ + TDX_ACPI_LOADER_EVENT, + TDX_ACPI_RSDP_EVENT, + TDX_ACPI_TABLES_EVENT, +]; + /// This is the TDX event log format that is used to store the event log in the TDX guest. /// It is a simplified version of the TCG event log format, containing only a single digest /// and the raw event data. The IMR index is zero-based, unlike the TCG event log format @@ -97,9 +108,69 @@ impl From for TdxEvent { } } +pub fn is_tdx_acpi_data_event(event: &TdxEvent) -> bool { + event.imr == 0 + && event.event_type == TDX_ACPI_DATA_EVENT_TYPE + && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD +} + +/// Give dstack's three Pre202505 OVMF ACPI DATA RTMR0 events stable semantic +/// names. The firmware event payload is the same "ACPI DATA" marker for all +/// three entries, so the guest labels them before exposing the event log. +pub fn label_tdx_acpi_data_events(event_logs: &mut [TdxEvent]) { + let mut acpi_idx = 0; + for event in event_logs + .iter_mut() + .filter(|event| is_tdx_acpi_data_event(event)) + { + if let Some(name) = TDX_ACPI_DATA_EVENT_NAMES.get(acpi_idx) { + event.event = (*name).to_string(); + } + acpi_idx += 1; + } +} + /// Read both boottime and runtime event logs. pub fn read_event_log() -> Result> { let mut event_logs = TcgEventLog::decode_from_ccel_file()?.to_cc_event_log()?; + label_tdx_acpi_data_events(&mut event_logs); event_logs.extend(RuntimeEvent::read_all()?.into_iter().map(Into::into)); Ok(event_logs) } + +#[cfg(test)] +mod tests { + use super::*; + + fn acpi_data_event(digest_byte: u8) -> TdxEvent { + TdxEvent { + imr: 0, + event_type: TDX_ACPI_DATA_EVENT_TYPE, + digest: vec![digest_byte; 48], + event: String::new(), + event_payload: TDX_ACPI_DATA_EVENT_PAYLOAD.to_vec(), + } + } + + #[test] + fn labels_pre202505_acpi_data_events_in_order() { + let mut events = vec![ + TdxEvent::new(0, 4, String::new(), vec![0]), + acpi_data_event(1), + acpi_data_event(2), + acpi_data_event(3), + TdxEvent::new(3, DSTACK_RUNTIME_EVENT_TYPE, "app-id".into(), vec![4]), + ]; + + label_tdx_acpi_data_events(&mut events); + + let names = events + .iter() + .filter(|event| is_tdx_acpi_data_event(event)) + .map(|event| event.event.as_str()) + .collect::>(); + assert_eq!(names, TDX_ACPI_DATA_EVENT_NAMES); + assert_eq!(events[0].event, ""); + assert_eq!(events[4].event, "app-id"); + } +} diff --git a/docs/security/security-model.md b/docs/security/security-model.md index 6a5c24ee1..b81a65ee7 100644 --- a/docs/security/security-model.md +++ b/docs/security/security-model.md @@ -128,9 +128,11 @@ The reason boot-time event log entries (RTMR0-2) are dropped is that **nothing d TDX lite mode verifies the OS image without downloading the image and without running QEMU to regenerate ACPI tables. It still uses the three RTMR0 `ACPI -DATA` digests from the attestation event log as opaque measurement inputs and -checks that the recomputed RTMR values match the hardware-signed quote. What it -does not do is reconstruct and byte-compare the full ACPI table contents. +DATA` digests from the attestation event log as measurement inputs. The guest +labels those three events as `acpi-loader`, `acpi-rsdp`, and `acpi-tables` +before exposing the event log, and the verifier checks that the recomputed RTMR +values match the hardware-signed quote. What it does not do is reconstruct and +byte-compare the full ACPI table contents. This is safe for dstack's threat model because ACPI tables are treated as untrusted host-provided platform description, not as trusted guest code. The diff --git a/dstack-attest/src/v1.rs b/dstack-attest/src/v1.rs index a5fa5b750..3fa28952a 100644 --- a/dstack-attest/src/v1.rs +++ b/dstack-attest/src/v1.rs @@ -3,20 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 use anyhow::{anyhow, bail, Context, Result}; -use cc_eventlog::{RuntimeEvent, TdxEvent}; +use cc_eventlog::{ + tdx::{self, TDX_ACPI_DATA_EVENT_PAYLOAD}, + RuntimeEvent, TdxEvent, +}; use dstack_types::mr_config::MrConfigV3; use serde::{Deserialize, Serialize}; use tpm_types::TpmQuote; pub const ATTESTATION_VERSION: u64 = 1; -const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; -const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; - pub(crate) fn is_tdx_acpi_data_event(event: &TdxEvent) -> bool { - event.imr == 0 - && event.event_type == TDX_ACPI_DATA_EVENT_TYPE - && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD + tdx::is_tdx_acpi_data_event(event) } pub(crate) fn strip_tdx_runtime_event_log(event_log: Vec) -> Vec { @@ -372,6 +370,7 @@ impl Attestation { #[cfg(test)] mod tests { use super::*; + use cc_eventlog::tdx::TDX_ACPI_DATA_EVENT_TYPE; fn test_mr_config_document() -> String { MrConfigV3::new( diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index e5fefc398..d055e04c6 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { - "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3370024414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef0024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b600244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b5165137b226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333037383632383038343262373336343238376133613730643936663765333039323532383537626562343566623166393133313461326561383633646230616463303463383433316563626632396139363634303536303436333161356161623837333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", + "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3372c616370692d6c6f6164657224414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef24616370692d7273647024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b62c616370692d7461626c6573244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b5165137b226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333037383632383038343262373336343238376133613730643936663765333039323532383537626562343566623166393133313461326561383633646230616463303463383433316563626632396139363634303536303436333161356161623837333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index bd92d9429..cf45eb4dc 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -1,6 +1,6 @@ { "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"050bf89570575fe8fab4cb8f0a62a9e64efe8ead\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", + "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"acpi-loader\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"acpi-rsdp\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"acpi-tables\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"050bf89570575fe8fab4cb8f0a62a9e64efe8ead\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", "report_data": "646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51", "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 95b25f731..8eea115b4 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -32,9 +32,9 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) - `vm_config.os_image_hash = 07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d` -- The top-level `event_log` and stripped attestation keep the three RTMR0 - `ACPI DATA` digests and marker payloads needed by the lite verifier, plus - RTMR3 runtime events. +- The top-level `event_log` and stripped attestation keep the three named RTMR0 + `ACPI DATA` digests (`acpi-loader`, `acpi-rsdp`, `acpi-tables`) and marker + payloads needed by the lite verifier, plus RTMR3 runtime events. To verify without image download, use a config whose download URL is unreachable; the lite verifier should still pass: diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index ecddf017e..42948b253 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -9,7 +9,13 @@ use std::{ }; use anyhow::{anyhow, bail, Context, Result}; -use cc_eventlog::TdxEvent; +use cc_eventlog::{ + tdx::{ + TDX_ACPI_DATA_EVENT_PAYLOAD, TDX_ACPI_DATA_EVENT_TYPE, TDX_ACPI_LOADER_EVENT, + TDX_ACPI_RSDP_EVENT, TDX_ACPI_TABLES_EVENT, + }, + TdxEvent, +}; use dstack_mr::{ tdx::TdxRtmr0AcpiHashes, RtmrLog, RtmrLogs, TdxMeasurementDetails, TdxMeasurements, }; @@ -381,61 +387,53 @@ impl CvmVerifier { .is_some_and(|digest| digest == expected)) } - fn tdx_acpi_digest_candidates_from_event_log(event_log: &[TdxEvent]) -> Result>> { - const TDX_ACPI_DATA_EVENT_TYPE: u32 = 10; - const TDX_ACPI_DATA_EVENT_PAYLOAD: &[u8] = b"ACPI DATA"; - + fn tdx_acpi_hashes_from_event_log(event_log: &[TdxEvent]) -> Result { let rtmr0_events = event_log .iter() .filter(|event| event.imr == 0) .collect::>(); - let candidates = rtmr0_events + let acpi_events = rtmr0_events .iter() .filter(|event| { event.event_type == TDX_ACPI_DATA_EVENT_TYPE && event.event_payload == TDX_ACPI_DATA_EVENT_PAYLOAD }) - .map(|event| event.digest()) .collect::>(); - if candidates.len() != 3 { + if acpi_events.len() != 3 { bail!( - "TDX lite attestation requires exactly 3 RTMR0 ACPI DATA digests; found {} candidates and {} RTMR0 events", - candidates.len(), + "TDX lite attestation requires exactly 3 RTMR0 ACPI DATA events; found {} candidates and {} RTMR0 events", + acpi_events.len(), rtmr0_events.len() ); } - for (idx, digest) in candidates.iter().enumerate() { + + let digest_for = |name: &str| -> Result> { + let matches = acpi_events + .iter() + .copied() + .filter(|event| event.event == name) + .collect::>(); + if matches.len() != 1 { + bail!( + "TDX lite attestation requires exactly one RTMR0 ACPI DATA event named {name}; found {}", + matches.len() + ); + } + let digest = matches[0].digest(); if digest.len() != 48 { bail!( - "TDX RTMR0 ACPI DATA digest {idx} has invalid length {}, expected 48", + "TDX RTMR0 ACPI DATA event {name} has invalid digest length {}, expected 48", digest.len() ); } - } - Ok(candidates) - } + Ok(digest) + }; - fn tdx_acpi_hash_permutations(digests: &[Vec]) -> Vec { - debug_assert_eq!(digests.len(), 3); - let mut permutations = Vec::with_capacity(6); - for loader_idx in 0..3 { - for rsdp_idx in 0..3 { - if rsdp_idx == loader_idx { - continue; - } - for tables_idx in 0..3 { - if tables_idx == loader_idx || tables_idx == rsdp_idx { - continue; - } - permutations.push(TdxRtmr0AcpiHashes { - loader: digests[loader_idx].clone(), - rsdp: digests[rsdp_idx].clone(), - tables: digests[tables_idx].clone(), - }); - } - } - } - permutations + Ok(TdxRtmr0AcpiHashes { + loader: digest_for(TDX_ACPI_LOADER_EVENT)?, + rsdp: digest_for(TDX_ACPI_RSDP_EVENT)?, + tables: digest_for(TDX_ACPI_TABLES_EVENT)?, + }) } /// Helper method to ensure image is downloaded and return image paths @@ -772,7 +770,7 @@ impl CvmVerifier { &self, vm_config: &VmConfig, attestation: &VerifiedAttestation, - debug: bool, + _debug: bool, _details: &mut VerificationDetails, ) -> Result<()> { let Some(report) = &attestation.report.tdx_report() else { @@ -834,48 +832,27 @@ impl CvmVerifier { // Compute expected measurements. New TDX images advertise the // measurement.json-derived TDX os_image_hash; verify those without // downloading the image or running QEMU-derived ACPI table generators. - // The event log supplies only the three hardware-bound RTMR0 ACPI DATA - // digests. Their payloads do not distinguish loader/RSDP/tables, so try - // all assignments and accept the one that replays to the quote RTMRs. - // This avoids hard-coding OVMF-version-specific RTMR0 indexes. - let acpi_digests = Self::tdx_acpi_digest_candidates_from_event_log(event_log) - .context("TDX lite attestation is missing RTMR0 ACPI DATA digests")?; - let mut last_error = None; - for acpi_hashes in Self::tdx_acpi_hash_permutations(&acpi_digests) { - let mrs = match dstack_mr::tdx::tdx_measurements_from_measurement_document( - document, - vm_config, - &acpi_hashes, - ) - .context("Failed to compute TDX expected measurements without image download") - { - Ok(mrs) => mrs, - Err(e) => { - last_error = Some(e); - continue; - } - }; - - let expected_mrs = Mrs { - mrtd: mrs.mrtd.clone(), - rtmr0: mrs.rtmr0.clone(), - rtmr1: mrs.rtmr1.clone(), - rtmr2: mrs.rtmr2.clone(), - }; - match expected_mrs.assert_eq(&verified_mrs) { - Ok(()) => return Ok(()), - Err(e) => last_error = Some(e), - } - } + // The guest labels the three RTMR0 ACPI DATA events as acpi-loader, + // acpi-rsdp, and acpi-tables before exposing the event log, so the + // verifier does not guess based on event order. + let acpi_hashes = Self::tdx_acpi_hashes_from_event_log(event_log) + .context("TDX lite attestation is missing named RTMR0 ACPI DATA digests")?; + let mrs = dstack_mr::tdx::tdx_measurements_from_measurement_document( + document, + vm_config, + &acpi_hashes, + ) + .context("Failed to compute TDX expected measurements without image download")?; - let result = Err(last_error.unwrap_or_else(|| { - anyhow!("MRs do not match for any RTMR0 ACPI DATA digest assignment") - })) - .context("MRs do not match"); - if !debug { - return result; - } - result + let expected_mrs = Mrs { + mrtd: mrs.mrtd.clone(), + rtmr0: mrs.rtmr0.clone(), + rtmr1: mrs.rtmr1.clone(), + rtmr2: mrs.rtmr2.clone(), + }; + expected_mrs + .assert_eq(&verified_mrs) + .context("MRs do not match") } fn compare_tdx_mrs( @@ -1202,6 +1179,43 @@ impl Mrs { mod tests { use super::*; + fn acpi_event(name: &str, digest_byte: u8) -> TdxEvent { + TdxEvent { + imr: 0, + event_type: TDX_ACPI_DATA_EVENT_TYPE, + digest: vec![digest_byte; 48], + event: name.to_string(), + event_payload: TDX_ACPI_DATA_EVENT_PAYLOAD.to_vec(), + } + } + + #[test] + fn tdx_lite_acpi_hashes_are_selected_by_event_name() { + let event_log = vec![ + acpi_event(TDX_ACPI_RSDP_EVENT, 2), + acpi_event(TDX_ACPI_TABLES_EVENT, 3), + acpi_event(TDX_ACPI_LOADER_EVENT, 1), + ]; + + let hashes = + CvmVerifier::tdx_acpi_hashes_from_event_log(&event_log).expect("named ACPI hashes"); + + assert_eq!(hashes.loader, vec![1u8; 48]); + assert_eq!(hashes.rsdp, vec![2u8; 48]); + assert_eq!(hashes.tables, vec![3u8; 48]); + } + + #[test] + fn tdx_lite_acpi_hashes_reject_unlabeled_events() { + let event_log = vec![ + acpi_event("", 1), + acpi_event(TDX_ACPI_RSDP_EVENT, 2), + acpi_event(TDX_ACPI_TABLES_EVENT, 3), + ]; + + assert!(CvmVerifier::tdx_acpi_hashes_from_event_log(&event_log).is_err()); + } + #[test] fn decode_key_provider_info_parses_json_and_tolerates_garbage() { let info = From 2e410d625ecfa94ca8276e799de816cb6321fed3 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 18:41:37 -0700 Subject: [PATCH 16/18] feat(vmm): auto-select TDX attestation variant --- vmm/src/app.rs | 164 +++++++++++++++++++++++++++++++++++++++++++--- vmm/src/config.rs | 80 ++++++++++++++++++++-- vmm/vmm.toml | 9 ++- 3 files changed, 238 insertions(+), 15 deletions(-) diff --git a/vmm/src/app.rs b/vmm/src/app.rs index 56893a674..a20ef3b74 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1338,6 +1338,14 @@ fn sha256_file(path: impl AsRef) -> Result<[u8; 32]> { Ok(out) } +fn image_supports_tdx_lite(image: &Image) -> bool { + image + .tdx_digest + .as_deref() + .is_some_and(|digest| !digest.trim().is_empty()) + && image.tdx_measurement.is_some() +} + fn make_vm_config( cfg: &Config, manifest: &Manifest, @@ -1345,19 +1353,21 @@ fn make_vm_config( _compose_hash: &str, mr_config: Option, ) -> Result { - let is_amd_sev_snp = - cfg.cvm.resolved_platform() == crate::config::TeePlatform::AmdSevSnp && !manifest.no_tee; - let is_tdx = cfg.cvm.resolved_platform() == crate::config::TeePlatform::Tdx && !manifest.no_tee; + let platform = cfg.cvm.resolved_platform(); + let is_amd_sev_snp = platform == crate::config::TeePlatform::AmdSevSnp && !manifest.no_tee; + let is_tdx = platform == crate::config::TeePlatform::Tdx && !manifest.no_tee; let tdx_attestation_variant = if is_tdx { - cfg.cvm.tdx_attestation_variant + cfg.cvm + .tdx_attestation_variant + .resolve(manifest.memory, image_supports_tdx_lite(image)) } else { dstack_types::TdxAttestationVariant::Legacy }; // AMD SEV-SNP binds the OS image through the launch-measurement-derived // os_image_hash, computed at image build time and shipped in - // `measurement.json.snp.os_image_hash` (legacy images used `digest.sev.txt`). TDX keeps - // using the generic content digest unless the - // operator explicitly opts into the lite attestation variant. + // `measurement.json.snp.os_image_hash` (legacy images used `digest.sev.txt`). + // TDX keeps using the generic content digest unless the resolved + // attestation policy selects the lite variant. let os_image_hash = if is_amd_sev_snp { let digest = image.sev_digest.as_deref().context( "amd sev-snp image is missing measurement.json SNP hash; \ @@ -1444,7 +1454,11 @@ fn make_vm_config( #[cfg(test)] mod tests { use super::*; - use crate::config::{load_config_figment, TeePlatform}; + use crate::config::{load_config_figment, TdxAttestationVariantConfig, TeePlatform}; + use dstack_types::{ + TdxImageMeasurement, TdxMrtdCandidates, TdxOsImageMeasurement, + TdxOsImageMeasurementDocument, TdxTdvfMeasurement, + }; use rocket::figment::Figment; use std::time::UNIX_EPOCH; @@ -1525,6 +1539,82 @@ mod tests { ovmf } + fn test_manifest(memory: u32) -> Manifest { + Manifest { + id: "tdx-test".to_string(), + name: "tdx-test".to_string(), + app_id: hex_of(0x11, 20), + vcpu: 2, + memory, + disk_size: 1024, + image: "dstack-test".to_string(), + port_map: vec![], + created_at_ms: 0, + hugepages: false, + pin_numa: false, + gpus: None, + kms_urls: vec![], + gateway_urls: vec![], + no_tee: false, + networking: None, + } + } + + fn dummy_tdx_measurement_document() -> TdxOsImageMeasurementDocument { + TdxOsImageMeasurementDocument::new(TdxOsImageMeasurement { + image: TdxImageMeasurement { + kernel_cmdline_sha384: vec![0x10; 48], + kernel_authenticode: vec![0x20; 48], + initrd_sha384: vec![0x30; 48], + }, + tdvf: TdxTdvfMeasurement { + ovmf_variant: Default::default(), + mrtd: TdxMrtdCandidates { + single_pass: vec![0x40; 48], + two_pass: vec![0x50; 48], + }, + td_hob_witness: vec![0x60; 16], + }, + }) + } + + fn test_tdx_image(supports_lite: bool) -> Image { + let tdx_measurement = supports_lite.then(dummy_tdx_measurement_document); + Image { + info: ImageInfo { + cmdline: None, + kernel: "kernel".to_string(), + initrd: "initrd".to_string(), + hda: None, + rootfs: None, + bios: None, + bios_sev: None, + rootfs_hash: None, + shared_ro: false, + version: "0.6.0".to_string(), + is_dev: false, + ovmf_variant: None, + }, + initrd: PathBuf::from("initrd"), + kernel: PathBuf::from("kernel"), + hda: None, + rootfs: None, + bios: None, + bios_sev: None, + digest: Some(hex_of(0xaa, 32)), + tdx_digest: tdx_measurement.as_ref().map(|d| d.os_image_hash.clone()), + tdx_measurement, + sev_digest: None, + } + } + + fn test_tdx_config() -> Result { + let mut config: Config = Figment::from(load_config_figment(None)).extract()?; + config.cvm.platform = Some(TeePlatform::Tdx); + config.cvm.tdx_attestation_variant = TdxAttestationVariantConfig::Auto; + Ok(config) + } + #[test] fn effective_vcpu_count_clamps_zero_to_one() { assert_eq!(effective_vcpu_count(0, None), 1); @@ -1549,6 +1639,64 @@ mod tests { assert!(amd_sev_snp_measurement_base_cmdline(Some(" ")).is_err()); } + #[test] + fn tdx_auto_variant_uses_legacy_for_low_non_2g_memory() -> Result<()> { + let config = test_tdx_config()?; + let manifest = test_manifest(1024); + let image = test_tdx_image(true); + let vm_config = make_vm_config(&config, &manifest, &image, &hex_of(0x22, 32), None)?; + + assert!(vm_config.get("tdx_attestation_variant").is_none()); + assert!(vm_config.get("tdx_measurement").is_none()); + assert_eq!( + vm_config["os_image_hash"] + .as_str() + .context("os_image_hash must be a string")?, + hex_of(0xaa, 32) + ); + Ok(()) + } + + #[test] + fn tdx_auto_variant_uses_lite_for_2g_supported_image() -> Result<()> { + let config = test_tdx_config()?; + let manifest = test_manifest(2048); + let image = test_tdx_image(true); + let expected_tdx_digest = image + .tdx_digest + .clone() + .context("test image must carry TDX digest")?; + let vm_config = make_vm_config(&config, &manifest, &image, &hex_of(0x22, 32), None)?; + + assert_eq!(vm_config["tdx_attestation_variant"], "lite"); + assert!(vm_config.get("tdx_measurement").is_some()); + assert_eq!( + vm_config["os_image_hash"] + .as_str() + .context("os_image_hash must be a string")?, + expected_tdx_digest + ); + Ok(()) + } + + #[test] + fn tdx_auto_variant_falls_back_to_legacy_when_image_lacks_lite_support() -> Result<()> { + let config = test_tdx_config()?; + let manifest = test_manifest(3072); + let image = test_tdx_image(false); + let vm_config = make_vm_config(&config, &manifest, &image, &hex_of(0x22, 32), None)?; + + assert!(vm_config.get("tdx_attestation_variant").is_none()); + assert!(vm_config.get("tdx_measurement").is_none()); + assert_eq!( + vm_config["os_image_hash"] + .as_str() + .context("os_image_hash must be a string")?, + hex_of(0xaa, 32) + ); + Ok(()) + } + #[test] fn amd_sev_snp_sys_config_includes_measurement_input_and_mr_config() -> Result<()> { let temp = std::env::temp_dir().join(format!( diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 788865d49..aa63fd014 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -209,6 +209,41 @@ impl CvmConfig { } } +/// VMM-side policy for selecting the TDX attestation/hash scheme. +/// +/// This is intentionally separate from `dstack_types::TdxAttestationVariant`: +/// the VM config shared with KMS/verifier must contain the resolved runtime +/// variant (`legacy` or `lite`), never the VMM-only `auto` policy. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum TdxAttestationVariantConfig { + Legacy, + Lite, + #[default] + Auto, +} + +impl TdxAttestationVariantConfig { + const TWO_GIB_MIB: u32 = 2 * 1024; + const THREE_GIB_MIB: u32 = 3 * 1024; + + pub fn resolve(self, memory_mib: u32, image_supports_lite: bool) -> TdxAttestationVariant { + match self { + Self::Legacy => TdxAttestationVariant::Legacy, + Self::Lite => TdxAttestationVariant::Lite, + Self::Auto => { + if memory_mib < Self::THREE_GIB_MIB && memory_mib != Self::TWO_GIB_MIB { + TdxAttestationVariant::Legacy + } else if image_supports_lite { + TdxAttestationVariant::Lite + } else { + TdxAttestationVariant::Legacy + } + } + } + } +} + #[derive(Debug, Clone, Deserialize)] pub struct CvmConfig { /// TEE platform to use when launching CVMs. Omit (or set `auto`) to detect @@ -261,11 +296,13 @@ pub struct CvmConfig { /// QEMU hotplug_off pub qemu_hotplug_off: bool, - /// TDX attestation/hash scheme. `legacy` keeps the existing digest.txt + - /// dstack-acpi-tables verifier path; `lite` opts into the - /// measurement.json + no-QEMU verifier path. + /// TDX attestation/hash scheme policy. `legacy` keeps the existing + /// digest.txt + dstack-acpi-tables verifier path; `lite` opts into the + /// measurement.json + no-QEMU verifier path; `auto` selects `legacy` for + /// CVMs below 3 GiB except exactly 2 GiB, otherwise uses `lite` when the + /// image carries TDX measurement material and falls back to `legacy`. #[serde(default)] - pub tdx_attestation_variant: TdxAttestationVariant, + pub tdx_attestation_variant: TdxAttestationVariantConfig, /// Networking configuration pub networking: Networking, @@ -710,6 +747,41 @@ mod tests { ); } + #[test] + fn tdx_attestation_variant_config_accepts_auto_and_resolves() { + let parse = |s: &str| serde_json::from_str::(s).unwrap(); + assert_eq!(parse(r#""legacy""#), TdxAttestationVariantConfig::Legacy); + assert_eq!(parse(r#""lite""#), TdxAttestationVariantConfig::Lite); + assert_eq!(parse(r#""auto""#), TdxAttestationVariantConfig::Auto); + + use dstack_types::TdxAttestationVariant::{Legacy, Lite}; + + // Explicit settings bypass auto heuristics. + assert_eq!( + TdxAttestationVariantConfig::Legacy.resolve(2048, true), + Legacy + ); + assert_eq!(TdxAttestationVariantConfig::Lite.resolve(1024, false), Lite); + + // Auto avoids lite for sub-3 GiB memory sizes except exactly 2 GiB. + assert_eq!( + TdxAttestationVariantConfig::Auto.resolve(1024, true), + Legacy + ); + assert_eq!( + TdxAttestationVariantConfig::Auto.resolve(2816, true), + Legacy + ); + assert_eq!(TdxAttestationVariantConfig::Auto.resolve(2048, true), Lite); + + // At 3 GiB and above, auto follows image support. + assert_eq!(TdxAttestationVariantConfig::Auto.resolve(3072, true), Lite); + assert_eq!( + TdxAttestationVariantConfig::Auto.resolve(3072, false), + Legacy + ); + } + #[test] fn tee_platform_auto_detects_amd_sev_snp_from_flag() { let cpuinfo = "flags : fpu svm sev sev_es sev_snp debug_swap"; diff --git a/vmm/vmm.toml b/vmm/vmm.toml index cde99b7a7..48b61904d 100644 --- a/vmm/vmm.toml +++ b/vmm/vmm.toml @@ -45,9 +45,12 @@ use_mrconfigid = true #qemu_version = "" qemu_pci_hole64_size = 0 qemu_hotplug_off = false -# TDX attestation/hash scheme: "legacy" (digest.txt + legacy verifier) or -# "lite" (measurement.json.tdx.os_image_hash + no-QEMU verifier). -tdx_attestation_variant = "legacy" +# TDX attestation/hash scheme policy: +# - "legacy": digest.txt + legacy verifier +# - "lite": measurement.json.tdx.os_image_hash + no-QEMU verifier +# - "auto": legacy for CVM memory below 3 GiB except exactly 2 GiB; otherwise +# lite when the image supports it, legacy when it does not. +tdx_attestation_variant = "auto" host_share_mode = "9p" From 53defce6cb4f68036384d3bff84585d0afcc1348 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 19:34:14 -0700 Subject: [PATCH 17/18] refactor: unify os image hash materials --- docs/amd-sev-snp-review-readiness.md | 4 +- dstack-attest/tests/sev_snp_verify.rs | 119 +++++++--- dstack-mr/src/main.rs | 114 ++++----- dstack-mr/src/measurement.rs | 33 ++- dstack-mr/src/sev.rs | 229 +++++++++++------- dstack-mr/src/tdx.rs | 31 +-- dstack-types/src/lib.rs | 231 ++++++++++++------ kms/src/main_service.rs | 58 +++-- kms/src/main_service/amd_attest.rs | 145 ++++++++---- kms/src/onboard_service.rs | 34 ++- verifier/fixtures/tdx-lite-attestation.json | 2 +- verifier/fixtures/tdx-lite-getquote.json | 2 +- verifier/fixtures/tdx-lite.README.md | 7 +- verifier/src/verification.rs | 56 ++--- vmm/src/app.rs | 249 +++++++------------- vmm/src/app/image.rs | 73 +++--- vmm/src/config.rs | 2 +- vmm/vmm.toml | 2 +- 18 files changed, 789 insertions(+), 602 deletions(-) diff --git a/docs/amd-sev-snp-review-readiness.md b/docs/amd-sev-snp-review-readiness.md index eda547f13..99c685731 100644 --- a/docs/amd-sev-snp-review-readiness.md +++ b/docs/amd-sev-snp-review-readiness.md @@ -119,8 +119,8 @@ After those fixes, the manual smoke progressed through full dstack-managed SNP g - Configfs TSM report collection falls back to the SEV-SNP extended-report ioctl when configfs does not carry certificate collateral. - If verifier-side evidence still lacks ASK/VCEK collateral, the verifier can fetch AMD KDS ARK/ASK/VCEK using the report `chip_id` and reported TCB, then verify the signed report fail-closed. - KMS measurement recomputation now uses the image's original kernel cmdline for SNP launch measurement, while app identity is bound by MrConfigV3/HOST_DATA instead of appended cmdline fields. -- VMM now extracts the image OVMF SEV metadata and OVMF launch digest seed, includes them in the `sev_snp_measurement` document string, and passes that through the guest to KMS; KMS no longer needs a single locally configured `ovmf_path`, so different image/OVMF versions can be verified by their self-contained launch inputs. -- SNP `BootInfo.os_image_hash` is the canonical image-invariant projection of the verified launch inputs: rootfs identity is derived from the measured `dstack.rootfs_hash=...` cmdline parameter, and the hash covers the cmdline, kernel/initrd hashes, and OVMF hash/sections while excluding per-deployment values like vCPU count/model and guest features. +- VMM now passes the image's split `measurement.snp.cbor` material plus per-launch SNP fields through the guest to KMS; KMS no longer needs a single locally configured `ovmf_path`, so different image/OVMF versions can be verified by their self-contained launch inputs. +- SNP `BootInfo.os_image_hash` is the unified image digest (`sha256(sha256sum.txt)`). The `measurement.snp.cbor` entry in `sha256sum.txt` commits to the cmdline, kernel/initrd hashes, and OVMF hash/sections while excluding per-deployment values like vCPU count/model and guest features. Latest sanitized remote smoke result with PR-built host binaries and a coherent `MACHINE = "sev-snp"` guest image: diff --git a/dstack-attest/tests/sev_snp_verify.rs b/dstack-attest/tests/sev_snp_verify.rs index 510c6b1a1..c008e92e2 100644 --- a/dstack-attest/tests/sev_snp_verify.rs +++ b/dstack-attest/tests/sev_snp_verify.rs @@ -10,9 +10,10 @@ //! one built into `sev-snp-qvl`. use dstack_attest::attestation::{AttestationQuote, VersionedAttestation}; -use dstack_mr::sev::verify_sev_launch; +use dstack_mr::sev::{sev_os_image_measurement_from_input, verify_sev_launch, MeasurementInput}; use dstack_types::{mr_config::MrConfigV3, KeyProviderKind}; use sev_snp_qvl::{verify_amd_snp_attestation, AmdSnpAttestationInput, VerifiedAmdSnpReport}; +use sha2::{Digest, Sha256}; /// Real SEV-SNP attestation captured from a dstack CVM (VersionedAttestation, SCALE V0). const SEV_ATTESTATION_BIN: &[u8] = include_bytes!("sev_snp_attestation.bin"); @@ -83,20 +84,21 @@ fn verify_sev_snp_attestation_bin() { // does after the hardware report verifies. Recompute the launch measurement // from the self-contained `sev_snp_measurement` document embedded in the // attestation config, require it to equal the hardware MEASUREMENT, require - // HOST_DATA to bind the MrConfigV3 document, and derive the os_image_hash. - let binding = dstack_mr::sev::verify_sev_launch( - &verified.measurement, - &verified.host_data, - &attestation.config, - ) - .expect("recompute SEV launch + derive os_image_hash from the attestation config"); - - // The os_image_hash matches the value advertised in the CVM config and the - // image build's digest.sev.txt. + // HOST_DATA to bind the MrConfigV3 document, and verify the unified + // os_image_hash against sha256sum.txt + measurement.snp.cbor. + let config = upgrade_snp_config_for_split_measurement(&attestation.config); + let binding = + dstack_mr::sev::verify_sev_launch(&verified.measurement, &verified.host_data, &config) + .expect("recompute SEV launch + verify os_image_hash from the attestation config"); + + // The os_image_hash matches the value advertised in the CVM config. + let config_value: serde_json::Value = serde_json::from_str(&config).expect("config json"); assert_eq!( hex::encode(&binding.os_image_hash), - "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda", - "derived os_image_hash" + config_value["os_image_hash"] + .as_str() + .expect("os_image_hash"), + "verified os_image_hash" ); // The HOST_DATA-bound app identity is recovered from the mr_config document. assert_eq!( @@ -111,8 +113,6 @@ fn verify_sev_snp_attestation_bin() { // Forged / tampered quote coverage (all offline, using the real fixture). // --------------------------------------------------------------------------- -const OS_IMAGE_HASH: &str = "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda"; - fn decoded_attestation() -> dstack_attest::attestation::Attestation { let versioned = VersionedAttestation::from_scale(SEV_ATTESTATION_BIN).expect("decode VersionedAttestation"); @@ -130,8 +130,48 @@ fn fixture_report() -> Vec { quote.report.clone() } +fn upgrade_snp_config_for_split_measurement(config: &str) -> String { + let mut value: serde_json::Value = serde_json::from_str(config).expect("config json"); + let measurement_doc = value["sev_snp_measurement"] + .as_str() + .expect("sev_snp_measurement string") + .to_string(); + let measurement_value: serde_json::Value = + serde_json::from_str(&measurement_doc).expect("measurement json"); + if measurement_value.get("measurement").is_some() + && measurement_value.get("sha256sum").is_some() + { + return config.to_string(); + } + + let input: MeasurementInput = + serde_json::from_value(measurement_value).expect("legacy SNP measurement input"); + let measurement = sev_os_image_measurement_from_input(&input) + .expect("image measurement") + .to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(Sha256::digest(&measurement)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + let document = dstack_mr::sev::SnpMeasurementDocument { + sha256sum, + measurement, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type, + guest_features: input.guest_features, + }; + value["os_image_hash"] = serde_json::Value::String(hex::encode( + dstack_types::image_hash_from_sha256sum(&document.sha256sum), + )); + value["sev_snp_measurement"] = + serde_json::Value::String(serde_json::to_string(&document).expect("serialize document")); + value.to_string() +} + fn fixture_config() -> String { - decoded_attestation().config + upgrade_snp_config_for_split_measurement(&decoded_attestation().config) } fn verified_fixture_report() -> VerifiedAmdSnpReport { @@ -144,18 +184,33 @@ fn verified_fixture_report() -> VerifiedAmdSnpReport { .expect("verify SEV-SNP attestation offline") } -/// Rewrite one field inside the embedded `sev_snp_measurement` document. -fn with_measurement_field(config: &str, f: impl FnOnce(&mut serde_json::Value)) -> String { +/// Rewrite the image CBOR inside the embedded `sev_snp_measurement` document. +fn with_image_measurement( + config: &str, + f: impl FnOnce(&mut dstack_types::SevOsImageMeasurement), +) -> String { let mut value: serde_json::Value = serde_json::from_str(config).expect("config json"); let measurement_doc = value["sev_snp_measurement"] .as_str() .expect("sev_snp_measurement string") .to_string(); - let mut measurement: serde_json::Value = + let mut document: dstack_mr::sev::SnpMeasurementDocument = serde_json::from_str(&measurement_doc).expect("measurement json"); - f(&mut measurement); + let mut image = dstack_types::SevOsImageMeasurement::from_cbor_slice(&document.measurement) + .expect("decode measurement.snp.cbor"); + f(&mut image); + document.measurement = image.to_cbor_vec(); + document.sha256sum = format!( + "{} {}\n", + hex::encode(Sha256::digest(&document.measurement)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + value["os_image_hash"] = serde_json::Value::String(hex::encode( + dstack_types::image_hash_from_sha256sum(&document.sha256sum), + )); value["sev_snp_measurement"] = - serde_json::Value::String(serde_json::to_string(&measurement).expect("reserialize")); + serde_json::Value::String(serde_json::to_string(&document).expect("reserialize")); value.to_string() } @@ -278,8 +333,8 @@ fn tampered_launch_inputs_break_os_image_binding() { // recomputed measurement no longer equals the hardware MEASUREMENT, so the // forged (allow-listed-looking) os_image_hash is never trusted. let verified = verified_fixture_report(); - let tampered = with_measurement_field(&fixture_config(), |m| { - m["kernel_hash"] = serde_json::Value::String("00".repeat(32)); + let tampered = with_image_measurement(&fixture_config(), |m| { + m.kernel_hash = vec![0; 32]; }); let err = verify_sev_launch(&verified.measurement, &verified.host_data, &tampered) .expect_err("tampered launch inputs must reject"); @@ -311,20 +366,20 @@ fn substituted_mr_config_breaks_host_data_binding() { } #[test] -fn advertised_os_image_hash_is_ignored() { - // A forged top-level os_image_hash is ignored; the authoritative value is - // derived from the measurement-bound launch inputs. +fn advertised_os_image_hash_must_match_sha256sum() { + // A forged top-level os_image_hash is rejected because it must equal + // sha256(sha256sum.txt) for the supplied measurement material. let verified = verified_fixture_report(); let mut value: serde_json::Value = serde_json::from_str(&fixture_config()).expect("config json"); value["os_image_hash"] = serde_json::Value::String("de".repeat(32)); let tampered = value.to_string(); - let binding = verify_sev_launch(&verified.measurement, &verified.host_data, &tampered) - .expect("a bogus advertised os_image_hash is ignored, not fatal"); - assert_eq!( - hex::encode(&binding.os_image_hash), - OS_IMAGE_HASH, - "derived os_image_hash must win over the advertised one" + let err = verify_sev_launch(&verified.measurement, &verified.host_data, &tampered) + .expect_err("a bogus advertised os_image_hash must reject"); + assert!( + err.to_string() + .contains("amd sev-snp measurement material does not match os_image_hash"), + "unexpected error: {err:?}" ); } diff --git a/dstack-mr/src/main.rs b/dstack-mr/src/main.rs index a6ace663f..18be3b728 100644 --- a/dstack-mr/src/main.rs +++ b/dstack-mr/src/main.rs @@ -7,20 +7,21 @@ //! Exposes build-time OS-image measurement material/hash computations. use anyhow::{bail, Context, Result}; -use dstack_types::OsImageMeasurementDocument; use serde_json::Value; +use std::io::Write; use std::path::Path; const USAGE: &str = "\ usage: dstack-mr measure-os - dstack-mr inspect-measurement - dstack-mr sev-os-image-hash - dstack-mr tdx-os-image-measurement - dstack-mr tdx-os-image-hash + dstack-mr inspect-measurement [tdx|snp] + dstack-mr tdx-measurement-cbor + dstack-mr snp-measurement-cbor + dstack-mr tdx-measurement-hash + dstack-mr snp-measurement-hash features: - cbor-measurement-v2"; + split-cbor-measurement-v3"; fn main() -> Result<()> { let mut args = std::env::args().skip(1); @@ -39,8 +40,13 @@ fn main() -> Result<()> { Ok(()) } Some("inspect-measurement") => { - let measurement_json = args.next().context(USAGE)?; - let document = inspect_measurement(Path::new(&measurement_json)) + let first = args.next().context(USAGE)?; + let second = args.next(); + let (kind, measurement_cbor) = match second { + Some(path) => (first, path), + None => (infer_measurement_kind(&first)?, first), + }; + let document = inspect_measurement(&kind, Path::new(&measurement_cbor)) .context("failed to inspect os image measurement document")?; println!( "{}", @@ -49,30 +55,37 @@ fn main() -> Result<()> { ); Ok(()) } - Some("sev-os-image-hash") => { + Some("snp-measurement-cbor") => { let image_dir = args.next().context(USAGE)?; - let hash = dstack_mr::sev::sev_os_image_hash_for_image_dir(Path::new(&image_dir)) - .context("failed to compute amd sev-snp os_image_hash")?; - println!("{}", hex::encode(hash)); + let cbor = + dstack_mr::sev::sev_os_image_measurement_cbor_for_image_dir(Path::new(&image_dir)) + .context("failed to compute amd sev-snp measurement CBOR")?; + std::io::stdout() + .write_all(&cbor) + .context("failed to write amd sev-snp measurement CBOR")?; Ok(()) } - Some("tdx-os-image-measurement") => { + Some("tdx-measurement-cbor") => { let image_dir = args.next().context(USAGE)?; - let document = dstack_mr::tdx::tdx_os_image_measurement_document_for_image_dir( - Path::new(&image_dir), - ) - .context("failed to compute tdx os image measurement material")?; - println!( - "{}", - serde_json::to_string(&document) - .context("failed to serialize tdx measurement material")? - ); + let cbor = + dstack_mr::tdx::tdx_os_image_measurement_cbor_for_image_dir(Path::new(&image_dir)) + .context("failed to compute tdx measurement CBOR")?; + std::io::stdout() + .write_all(&cbor) + .context("failed to write tdx measurement CBOR")?; Ok(()) } - Some("tdx-os-image-hash") => { + Some("snp-measurement-hash") | Some("sev-measurement-hash") => { let image_dir = args.next().context(USAGE)?; - let hash = dstack_mr::tdx::tdx_os_image_hash_for_image_dir(Path::new(&image_dir)) - .context("failed to compute tdx os_image_hash")?; + let hash = dstack_mr::sev::sev_measurement_hash_for_image_dir(Path::new(&image_dir)) + .context("failed to compute amd sev-snp measurement hash")?; + println!("{}", hex::encode(hash)); + Ok(()) + } + Some("tdx-measurement-hash") => { + let image_dir = args.next().context(USAGE)?; + let hash = dstack_mr::tdx::tdx_measurement_hash_for_image_dir(Path::new(&image_dir)) + .context("failed to compute tdx measurement hash")?; println!("{}", hex::encode(hash)); Ok(()) } @@ -85,40 +98,27 @@ fn main() -> Result<()> { } } -fn inspect_measurement(path: &Path) -> Result { - let document_text = fs_err::read_to_string(path) - .with_context(|| format!("failed to read {}", path.display()))?; - let document: OsImageMeasurementDocument = serde_json::from_str(&document_text) - .with_context(|| format!("failed to parse {}", path.display()))?; - let mut out: Value = serde_json::from_str(&document_text) - .with_context(|| format!("failed to parse {}", path.display()))?; - - if let (Some(tdx), Some(tdx_value)) = (&document.tdx, out.get_mut("tdx")) { - replace_measurement_field( - tdx_value, - tdx.decode_measurement_value() - .map_err(anyhow::Error::msg) - .context("failed to decode tdx measurement CBOR")?, - ); - } - if let (Some(snp), Some(snp_value)) = (&document.snp, out.get_mut("snp")) { - replace_measurement_field( - snp_value, - snp.decode_measurement_value() - .map_err(anyhow::Error::msg) - .context("failed to decode snp measurement CBOR")?, - ); +fn inspect_measurement(kind: &str, path: &Path) -> Result { + let cbor = fs_err::read(path).with_context(|| format!("failed to read {}", path.display()))?; + match kind { + "tdx" => dstack_types::TdxOsImageMeasurement::cbor_json_value_from_slice(&cbor) + .map_err(anyhow::Error::msg), + "snp" | "sev" => dstack_types::SevOsImageMeasurement::cbor_json_value_from_slice(&cbor) + .map_err(anyhow::Error::msg), + other => bail!("unknown measurement kind {other:?}; expected tdx or snp"), } - Ok(out) } -fn replace_measurement_field(section: &mut Value, decoded_measurement: Value) { - let Some(section) = section.as_object_mut() else { - return; - }; - if section.contains_key("measurement") { - section.insert("measurement".to_string(), decoded_measurement); - } else if section.contains_key("m") { - section.insert("m".to_string(), decoded_measurement); +fn infer_measurement_kind(path: &str) -> Result { + let filename = Path::new(path) + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or(path); + if filename.contains(".tdx.") || filename.contains("tdx") { + Ok("tdx".to_string()) + } else if filename.contains(".snp.") || filename.contains("snp") || filename.contains("sev") { + Ok("snp".to_string()) + } else { + bail!("cannot infer measurement kind from {filename:?}; pass tdx or snp explicitly") } } diff --git a/dstack-mr/src/measurement.rs b/dstack-mr/src/measurement.rs index 602afee60..5351be395 100644 --- a/dstack-mr/src/measurement.rs +++ b/dstack-mr/src/measurement.rs @@ -2,11 +2,12 @@ // // SPDX-License-Identifier: Apache-2.0 -//! Unified build-time OS-image measurement document. +//! Compatibility helpers for build-time OS-image measurement documents. use anyhow::{Context, Result}; use dstack_types::{ OsImageMeasurementDocument, SevOsImageMeasurementDocument, TdxOsImageMeasurementDocument, + SNP_MEASUREMENT_FILENAME, TDX_MEASUREMENT_FILENAME, }; use fs_err as fs; use serde::Deserialize; @@ -18,10 +19,11 @@ struct ImageMetadata { bios_sev: Option, } -/// Generate `measurement.json` for an image directory. +/// Generate a compatibility `measurement.json` for an image directory that has +/// already produced `sha256sum.txt` plus split measurement CBOR files. /// -/// TDX material is mandatory for the normal dstack image. SNP material is -/// included when metadata declares a dedicated `bios-sev` firmware. +/// New image builds should ship `measurement.tdx.cbor` / `measurement.snp.cbor` +/// directly instead of this combined JSON document. pub fn os_image_measurement_document_for_image_dir( image_dir: &Path, ) -> Result { @@ -30,20 +32,29 @@ pub fn os_image_measurement_document_for_image_dir( .with_context(|| format!("cannot read {}", meta_path.display()))?; let meta: ImageMetadata = serde_json::from_str(&meta_str).context("failed to parse image metadata.json")?; + let sha256sum_path = image_dir.join("sha256sum.txt"); + let sha256sum = fs::read(&sha256sum_path) + .with_context(|| format!("cannot read {}", sha256sum_path.display()))?; - let tdx = TdxOsImageMeasurementDocument::new( - crate::tdx::tdx_os_image_measurement_for_image_dir(image_dir) - .context("failed to build TDX measurement document")?, - ); + let tdx_path = image_dir.join(TDX_MEASUREMENT_FILENAME); + let tdx = if tdx_path.exists() { + Some(TdxOsImageMeasurementDocument::new( + sha256sum.clone(), + fs::read(&tdx_path).with_context(|| format!("cannot read {}", tdx_path.display()))?, + )) + } else { + None + }; let snp = if meta.bios_sev.is_some() { + let snp_path = image_dir.join(SNP_MEASUREMENT_FILENAME); Some(SevOsImageMeasurementDocument::new( - crate::sev::sev_os_image_measurement_for_image_dir(image_dir) - .context("failed to build SNP measurement document")?, + sha256sum, + fs::read(&snp_path).with_context(|| format!("cannot read {}", snp_path.display()))?, )) } else { None }; - Ok(OsImageMeasurementDocument::new(Some(tdx), snp)) + Ok(OsImageMeasurementDocument::new(tdx, snp)) } diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index 59e96a1de..29f3c90da 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -2,13 +2,12 @@ // // SPDX-License-Identifier: Apache-2.0 -//! AMD SEV-SNP launch-measurement recomputation and `os_image_hash` derivation. +//! AMD SEV-SNP launch-measurement recomputation. //! //! This is the single source of truth shared by `dstack-kms` (key release) and //! `dstack-verifier` (attestation verification). It recomputes the expected SNP //! launch `MEASUREMENT` from self-contained launch inputs (the -//! `sev_snp_measurement` document a VMM embeds in `vm_config`) and derives the -//! image-invariant `os_image_hash`. +//! `sev_snp_measurement` document a VMM embeds in `vm_config`). //! //! It deals only in primitive, hardware-verified values (`measurement`, //! `host_data`) so it can stay free of attestation/RA-TLS types and be reused by @@ -325,13 +324,6 @@ fn measured_kernel_cmdline(input: &str) -> String { input.trim().to_string() } -fn kernel_cmdline_sha256(input: &str) -> Vec { - let cmdline = measured_kernel_cmdline(input); - let mut cmdline_bytes = cmdline.as_bytes().to_vec(); - cmdline_bytes.push(0); - Sha256::digest(&cmdline_bytes).to_vec() -} - fn effective_initrd_hash_from_hex(value: &str) -> Result> { if value.is_empty() { return Ok(Sha256::digest(b"").to_vec()); @@ -757,7 +749,7 @@ fn sev_os_image_measurement( // is already committed by `kernel_cmdline_sha256`. rootfs_hash_from_cmdline(Some(&input.base_cmdline))?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256(&input.base_cmdline), + base_cmdline: measured_kernel_cmdline(&input.base_cmdline), ovmf_hash: decode_required_hex("ovmf_hash", &input.ovmf_hash, 48)?, kernel_hash: decode_required_hex("kernel_hash", &input.kernel_hash, 32)?, initrd_hash: effective_initrd_hash_from_hex(&input.initrd_hash)?, @@ -775,20 +767,10 @@ fn sev_os_image_measurement( }) } -/// Derive the OS image hash from a self-contained SNP measurement document. -/// -/// os_image_hash identifies the OS image only, so it covers exactly the -/// image-determined measurement inputs and EXCLUDES per-deployment values -/// (`vcpus`, `vcpu_type`, `guest_features`). Hashing the full -/// `MeasurementInput` made the same image hash differently per vCPU count, -/// which broke per-image on-chain allow-listing. App/config identity is bound -/// separately by MrConfigV3/HOST_DATA. The canonical hashing lives in -/// `dstack_types::SevOsImageMeasurement` so the image build can reproduce the -/// same value as `digest.sev.txt`. -pub fn snp_measurement_os_image_hash(measurement_document: &str) -> Result> { - let input: MeasurementInput = serde_json::from_str(measurement_document) - .context("failed to parse sev-snp measurement document for os_image_hash")?; - Ok(sev_os_image_measurement(&input)?.os_image_hash().to_vec()) +pub fn sev_os_image_measurement_from_input( + input: &MeasurementInput, +) -> Result { + sev_os_image_measurement(input) } /// OVMF launch-measurement metadata: the GCTX launch digest of the firmware @@ -884,10 +866,10 @@ pub fn sev_os_image_measurement_for_image_dir( rootfs_hash_from_cmdline(meta.cmdline.as_deref())?; Ok(dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: kernel_cmdline_sha256( + base_cmdline: measured_kernel_cmdline( meta.cmdline .as_deref() - .context("metadata.json cmdline is required for amd sev-snp os_image_hash")?, + .context("metadata.json cmdline is required for amd sev-snp measurement")?, ), ovmf_hash: decode_required_hex("ovmf_hash", &ovmf.ovmf_hash, 48)?, kernel_hash: file_sha256(&image_dir.join(&meta.kernel))?, @@ -906,24 +888,14 @@ pub fn sev_os_image_measurement_for_image_dir( }) } -/// Compute the AMD SEV-SNP `os_image_hash` from an OS image directory. -/// -/// This is the canonical legacy producer of `digest.sev.txt`. New images carry -/// the same value in `measurement.json.snp.os_image_hash`. The value equals the -/// `os_image_hash` the KMS and verifier derive from a hardware-verified launch -/// measurement, because both go through [`snp_measurement_os_image_hash`] / -/// `dstack_types::SevOsImageMeasurement`. -pub fn sev_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { - Ok(sev_os_image_measurement_for_image_dir(image_dir)?.os_image_hash()) +/// Compute the AMD SEV-SNP measurement-material hash from an OS image directory. +pub fn sev_measurement_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { + Ok(sev_os_image_measurement_for_image_dir(image_dir)?.measurement_hash()) } -/// Build the SNP section of `measurement.json`. -pub fn sev_os_image_measurement_document_for_image_dir( - image_dir: &Path, -) -> Result { - Ok(dstack_types::SevOsImageMeasurementDocument::new( - sev_os_image_measurement_for_image_dir(image_dir)?, - )) +/// Generate the raw `measurement.snp.cbor` bytes for an image directory. +pub fn sev_os_image_measurement_cbor_for_image_dir(image_dir: &Path) -> Result> { + Ok(sev_os_image_measurement_for_image_dir(image_dir)?.to_cbor_vec()) } /// `sha256(MEASUREMENT || HOST_DATA)` — the SNP aggregated identity digest. @@ -972,15 +944,59 @@ pub fn validate_snp_mr_config_binding( #[derive(Debug, serde::Deserialize)] struct SevSnpMeasurementVmConfig { + #[serde(with = "serde_human_bytes", default)] + os_image_hash: Vec, sev_snp_measurement: Option, mr_config: Option, } +#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[serde(deny_unknown_fields)] +pub struct SnpMeasurementDocument { + #[serde(with = "serde_human_bytes")] + pub sha256sum: Vec, + #[serde(with = "serde_human_bytes")] + pub measurement: Vec, + pub vcpus: u32, + pub vcpu_type: Option, + pub guest_features: u64, +} + +pub fn measurement_input_from_snp_document( + document: &SnpMeasurementDocument, +) -> Result { + let image = dstack_types::SevOsImageMeasurement::from_cbor_slice(&document.measurement) + .map_err(anyhow::Error::msg) + .context("invalid measurement.snp.cbor")?; + Ok(MeasurementInput { + base_cmdline: image.base_cmdline, + ovmf_hash: hex::encode(image.ovmf_hash), + kernel_hash: hex::encode(image.kernel_hash), + initrd_hash: hex::encode(image.initrd_hash), + sev_hashes_table_gpa: image.sev_hashes_table_gpa, + sev_es_reset_eip: image.sev_es_reset_eip, + vcpus: document.vcpus, + vcpu_type: document.vcpu_type.clone(), + guest_features: document.guest_features, + ovmf_sections: image + .ovmf_sections + .into_iter() + .map(|s| OvmfSectionParam { + gpa: s.gpa, + size: s.size, + section_type: s.section_type, + }) + .collect(), + }) +} + /// Launch inputs extracted from a VMM-produced `vm_config` string. pub struct SnpLaunchInputs { pub input: MeasurementInput, - /// Raw `sev_snp_measurement` document used for os_image_hash derivation. + /// Raw `sev_snp_measurement` document carried by vm_config. pub measurement_document: String, + /// Unified OS image hash from vm_config: `sha256(sha256sum.txt)`. + pub os_image_hash: Vec, /// Raw MrConfigV3 document bound by HOST_DATA. pub mr_config_document: String, } @@ -1012,8 +1028,26 @@ pub fn parse_snp_inputs_from_vm_config(vm_config: &str) -> Result Result Result, /// App/config identity bound by HOST_DATA. pub mr_config: MrConfigV3, @@ -1046,7 +1081,8 @@ pub struct SevImageBinding { /// 2. recomputes the launch measurement and checks it equals `measurement` /// (this is what makes the otherwise-untrusted launch inputs trustworthy), /// 3. checks `HOST_DATA` binds the `mr_config` document, and -/// 4. derives the image-invariant `os_image_hash`. +/// 4. returns the unified `os_image_hash` after checking it commits to the +/// supplied `sha256sum.txt` and `measurement.snp.cbor`. pub fn verify_sev_launch( verified_measurement: &[u8; 48], verified_host_data: &[u8; 32], @@ -1059,9 +1095,8 @@ pub fn verify_sev_launch( bail!("amd sev-snp measurement mismatch"); } let mr_config = validate_snp_mr_config_binding(verified_host_data, &inputs.mr_config_document)?; - let os_image_hash = snp_measurement_os_image_hash(&inputs.measurement_document)?; Ok(SevImageBinding { - os_image_hash, + os_image_hash: inputs.os_image_hash, mr_config, }) } @@ -1196,8 +1231,31 @@ mod tests { } } + fn snp_document(input: &MeasurementInput) -> SnpMeasurementDocument { + let measurement = sev_os_image_measurement_from_input(input) + .expect("image measurement") + .to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(Sha256::digest(&measurement)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + SnpMeasurementDocument { + sha256sum, + measurement, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type.clone(), + guest_features: input.guest_features, + } + } + fn measurement_document(input: &MeasurementInput) -> String { - serde_json::to_string(input).expect("measurement input should serialize") + serde_json::to_string(&snp_document(input)).expect("measurement document serializes") + } + + fn os_image_hash(input: &MeasurementInput) -> Vec { + dstack_types::image_hash_from_sha256sum(&snp_document(input).sha256sum).to_vec() } #[test] @@ -1244,10 +1302,8 @@ mod tests { } #[test] - fn snp_os_image_hash_covers_image_fields_only() { + fn unified_os_image_hash_covers_sha256sum_entries() { let input = valid_input(); - let os_image_hash = - |i: &MeasurementInput| snp_measurement_os_image_hash(&measurement_document(i)).unwrap(); let baseline = os_image_hash(&input); // Image-determined fields MUST change the os_image_hash. @@ -1282,8 +1338,8 @@ mod tests { ); } - // Per-deployment fields MUST NOT change the os_image_hash (the same OS - // image must hash identically regardless of vCPU count, CPU model, etc.). + // Per-deployment fields MUST NOT change the os_image_hash because they + // are outside measurement.snp.cbor and sha256sum.txt. let deployment_cases: Vec<(&str, fn(&mut MeasurementInput))> = vec![ ("vcpus", |i| i.vcpus = 3), ("vcpu_type", |i| { @@ -1363,7 +1419,7 @@ mod tests { const REAL_MEASUREMENT_DOC: &str = r#"{"base_cmdline":"console=ttyS0 init=/init panic=1 net.ifnames=0 biosdevname=0 mce=off oops=panic pci=noearly pci=nommconf random.trust_cpu=y random.trust_bootloader=n tsc=reliable no-kvmclock dstack.rootfs_hash=ca5adaef0ac3a36108035925763b48a5818f634e700fbaab561d419fd30d7121 dstack.rootfs_size=490713088","ovmf_hash":"ffb57e393469a497c0e3b07bd1c97d8611e555f464d14491837665893ac642b263a71f9507ff100a847897fe0c3f8c6f","kernel_hash":"dd9ea274ce9a07090b22e8284b0c841b65c021c2d15ca57d0f16731089dd226c","initrd_hash":"5f844c4a2ca5a3d0711b3db38293b21ba929bb8e0b3c5bc1a779a57f69221c19","sev_hashes_table_gpa":8457216,"sev_es_reset_eip":8433668,"vcpus":2,"vcpu_type":"EPYC-v4","guest_features":1,"ovmf_sections":[{"gpa":8388608,"size":36864,"section_type":1},{"gpa":8429568,"size":12288,"section_type":1},{"gpa":8441856,"size":4096,"section_type":2},{"gpa":8445952,"size":4096,"section_type":3},{"gpa":8450048,"size":4096,"section_type":4},{"gpa":8458240,"size":61440,"section_type":1},{"gpa":8454144,"size":4096,"section_type":16}]}"#; #[test] - fn real_fixture_recomputes_measurement_and_os_image_hash() { + fn real_fixture_recomputes_measurement() { let input: MeasurementInput = serde_json::from_str(REAL_MEASUREMENT_DOC).expect("real measurement doc parses"); validate_measurement_input(&input).expect("real measurement input is valid"); @@ -1376,14 +1432,11 @@ mod tests { "7f51e17f72a04d5422cb2c00998166536019a217376f3aa45a630e59c805a599847ff250dbffcd07e1ba639771d6f05d", ); - // os_image_hash derived from the same document must match the current - // measurement.json projection for these launch inputs. - let os_image_hash = - snp_measurement_os_image_hash(REAL_MEASUREMENT_DOC).expect("derive os_image_hash"); - assert_eq!( - hex::encode(os_image_hash), - "b6e8403b8f6167bcef4e39aa1039d8728fe624532ca6cedf2625a87fac2e5fda", - ); + let document = snp_document(&input); + let image_hash = dstack_types::image_hash_from_sha256sum(&document.sha256sum); + dstack_types::SevOsImageMeasurementDocument::new(document.sha256sum, document.measurement) + .verify(&image_hash) + .expect("fixture measurement material verifies against sha256sum.txt"); } // ---- Forged-quote / tampered-input coverage for `verify_sev_launch` ---- @@ -1406,7 +1459,8 @@ mod tests { fn synthetic_vm_config(input: &MeasurementInput, mr_config: &MrConfigV3) -> String { serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(input).expect("serialize input"), + "os_image_hash": hex::encode(os_image_hash(input)), + "sev_snp_measurement": measurement_document(input), "mr_config": mr_config.to_canonical_json(), }) .to_string() @@ -1428,10 +1482,7 @@ mod tests { let (input, mr_config, measurement, host_data, vm_config) = honest_case(); let binding = verify_sev_launch(&measurement, &host_data, &vm_config) .expect("honest launch verifies"); - assert_eq!( - binding.os_image_hash, - snp_measurement_os_image_hash(&serde_json::to_string(&input).unwrap()).unwrap() - ); + assert_eq!(binding.os_image_hash, os_image_hash(&input)); assert_eq!(binding.mr_config.app_id, mr_config.app_id); } @@ -1524,8 +1575,7 @@ mod tests { err.to_string().contains("amd sev-snp measurement mismatch"), "unexpected error: {err:?}" ); - let tampered_hash = - snp_measurement_os_image_hash(&serde_json::to_string(&tampered).unwrap()).unwrap(); + let tampered_hash = os_image_hash(&tampered); assert_ne!( honest.os_image_hash, tampered_hash, "a tampered rootfs hash must change the derived os_image_hash" @@ -1572,23 +1622,24 @@ mod tests { } #[test] - fn verify_sev_launch_ignores_advertised_os_image_hash() { - // The os_image_hash is derived from the measurement-bound inputs; a - // top-level attacker-advertised os_image_hash is ignored entirely. + fn verify_sev_launch_rejects_bad_advertised_os_image_hash() { + // The advertised os_image_hash must equal sha256(sha256sum.txt), and + // sha256sum.txt must commit to measurement.snp.cbor. let (input, mr_config, measurement, host_data, _vm) = honest_case(); let bogus = vec![0xde; 32]; let vm_config = serde_json::json!({ "os_image_hash": hex::encode(&bogus), - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), + "sev_snp_measurement": measurement_document(&input), "mr_config": mr_config.to_canonical_json(), }) .to_string(); - let binding = verify_sev_launch(&measurement, &host_data, &vm_config) - .expect("bogus advertised os_image_hash is ignored, not fatal"); - let expected = - snp_measurement_os_image_hash(&serde_json::to_string(&input).unwrap()).unwrap(); - assert_eq!(binding.os_image_hash, expected); - assert_ne!(binding.os_image_hash, bogus); + let err = verify_sev_launch(&measurement, &host_data, &vm_config) + .expect_err("bogus advertised os_image_hash must reject"); + assert!( + err.to_string() + .contains("amd sev-snp measurement material does not match os_image_hash"), + "unexpected error: {err:?}" + ); } #[test] @@ -1597,14 +1648,12 @@ mod tests { // image's inputs: the booted image's MEASUREMENT differs from the // advertised inputs' recomputed measurement. let honest = valid_input(); - let honest_hash = - snp_measurement_os_image_hash(&serde_json::to_string(&honest).unwrap()).unwrap(); + let honest_hash = os_image_hash(&honest); let mut malicious = honest.clone(); malicious.kernel_hash = hex_of(0xab, 32); // different kernel == different image let malicious_measurement = compute_expected_measurement(&malicious).unwrap(); - let malicious_hash = - snp_measurement_os_image_hash(&serde_json::to_string(&malicious).unwrap()).unwrap(); + let malicious_hash = os_image_hash(&malicious); assert_ne!( honest_hash, malicious_hash, "different image must hash differently" @@ -1636,9 +1685,11 @@ mod tests { "unexpected error: {err:?}" ); - let no_mr_config = - serde_json::json!({ "sev_snp_measurement": serde_json::to_string(&input).unwrap() }) - .to_string(); + let no_mr_config = serde_json::json!({ + "os_image_hash": hex::encode(os_image_hash(&input)), + "sev_snp_measurement": measurement_document(&input) + }) + .to_string(); let err = verify_sev_launch(&measurement, &host_data, &no_mr_config) .expect_err("missing mr_config must fail closed"); assert!( diff --git a/dstack-mr/src/tdx.rs b/dstack-mr/src/tdx.rs index f604bb0b5..087556567 100644 --- a/dstack-mr/src/tdx.rs +++ b/dstack-mr/src/tdx.rs @@ -264,7 +264,7 @@ pub fn tdx_os_image_measurement_for_image_dir(image_dir: &Path) -> Result Result Result { - Ok(TdxOsImageMeasurementDocument::new( - tdx_os_image_measurement_for_image_dir(image_dir)?, - )) +/// Generate the raw `measurement.tdx.cbor` bytes for an image directory. +pub fn tdx_os_image_measurement_cbor_for_image_dir(image_dir: &Path) -> Result> { + Ok(tdx_os_image_measurement_for_image_dir(image_dir)?.to_cbor_vec()) } -/// Compute the TDX static-material OS image hash for an image directory. -pub fn tdx_os_image_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { - Ok(tdx_os_image_measurement_for_image_dir(image_dir)?.os_image_hash()) +/// Compute the TDX static measurement-material hash for an image directory. +pub fn tdx_measurement_hash_for_image_dir(image_dir: &Path) -> Result<[u8; 32]> { + Ok(tdx_os_image_measurement_for_image_dir(image_dir)?.measurement_hash()) } -/// Compute expected TDX measurements from the self-contained `measurement.json` -/// TDX document and the three ACPI table digests captured in RTMR[0]. +/// Compute expected TDX measurements from self-contained TDX measurement +/// material and the three ACPI table digests captured in RTMR[0]. /// /// This path intentionally does not download or read the OS image. Because /// QEMU's patched kernel Authenticode hash depends on exact guest RAM below @@ -352,12 +345,6 @@ pub fn tdx_measurements_from_measurement_document( vm_config: &VmConfig, acpi_hashes: &TdxRtmr0AcpiHashes, ) -> Result { - if document.version != TdxOsImageMeasurementDocument::VERSION { - bail!( - "unsupported TDX measurement document version {}", - document.version - ); - } if !tdx_kernel_hash_uses_precomputed_high_mem(vm_config.memory_size) { bail!( "TDX lite attestation without image download requires memory_size == {} bytes ({} MiB) or >= {} bytes ({} MiB); got {} bytes", diff --git a/dstack-types/src/lib.rs b/dstack-types/src/lib.rs index ab0b5a229..e9803dd46 100644 --- a/dstack-types/src/lib.rs +++ b/dstack-types/src/lib.rs @@ -42,10 +42,10 @@ impl OvmfVariant { /// TDX launch measurement using the legacy image/QEMU-derived path. /// /// `Lite` opts into the no-QEMU verifier path: `vm_config.os_image_hash` -/// is `measurement.json.tdx.os_image_hash`, `vm_config.tdx_measurement` carries -/// the self-contained measurement material, and KMS/verifier select the new -/// logic from this vm_config flag while the attestation quote remains the -/// existing `DstackTdx`. +/// remains the unified image digest (`sha256(sha256sum.txt)`), +/// `vm_config.tdx_measurement` carries `sha256sum.txt` plus the TDX measurement +/// CBOR file, and KMS/verifier select the new logic from this vm_config flag +/// while the attestation quote remains the existing `DstackTdx`. #[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, Default)] #[serde(rename_all = "snake_case")] pub enum TdxAttestationVariant { @@ -328,8 +328,76 @@ fn sha256(bytes: &[u8]) -> [u8; 32] { Sha256::digest(bytes).into() } -fn sha256_hex(bytes: &[u8]) -> String { - hex::encode(sha256(bytes)) +pub const TDX_MEASUREMENT_FILENAME: &str = "measurement.tdx.cbor"; +pub const SNP_MEASUREMENT_FILENAME: &str = "measurement.snp.cbor"; + +pub fn image_hash_from_sha256sum(sha256sum: &[u8]) -> [u8; 32] { + sha256(sha256sum) +} + +pub fn sha256sum_entry_hash(sha256sum: &[u8], filename: &str) -> Result<[u8; 32], String> { + let text = std::str::from_utf8(sha256sum) + .map_err(|e| format!("sha256sum.txt is not valid UTF-8: {e}"))?; + let mut found = None; + for (line_no, line) in text.lines().enumerate() { + let line = line.trim(); + if line.is_empty() { + continue; + } + let mut parts = line.split_whitespace(); + let Some(hash_hex) = parts.next() else { + continue; + }; + let Some(path) = parts.next() else { + return Err(format!( + "sha256sum.txt line {} is missing filename", + line_no + 1 + )); + }; + if path != filename { + continue; + } + if found.is_some() { + return Err(format!( + "sha256sum.txt contains duplicate {filename} entries" + )); + } + let hash = hex::decode(hash_hex) + .map_err(|e| format!("sha256sum.txt {filename} hash is not valid hex: {e}"))?; + let hash: [u8; 32] = hash.try_into().map_err(|hash: Vec| { + format!( + "sha256sum.txt {filename} hash has invalid length {}, expected 32", + hash.len() + ) + })?; + found = Some(hash); + } + found.ok_or_else(|| format!("sha256sum.txt is missing {filename}")) +} + +pub fn verify_measurement_material( + os_image_hash: &[u8], + sha256sum: &[u8], + measurement: &[u8], + filename: &str, +) -> Result<(), String> { + if image_hash_from_sha256sum(sha256sum).as_slice() != os_image_hash { + return Err(format!( + "os_image_hash mismatch: expected sha256(sha256sum.txt)={}, actual={}", + hex::encode(os_image_hash), + hex::encode(image_hash_from_sha256sum(sha256sum)) + )); + } + let expected_measurement_hash = sha256sum_entry_hash(sha256sum, filename)?; + let actual_measurement_hash = sha256(measurement); + if expected_measurement_hash != actual_measurement_hash { + return Err(format!( + "{filename} hash mismatch: sha256sum.txt={}, actual={}", + hex::encode(expected_measurement_hash), + hex::encode(actual_measurement_hash) + )); + } + Ok(()) } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -360,21 +428,16 @@ impl From for OvmfSection { } } -/// Image-invariant projection that determines the AMD SEV-SNP OS image -/// identity. It deliberately excludes per-deployment values (vcpus, vcpu_type, -/// guest_features, app_id, compose_hash): the same OS image must hash -/// identically regardless of how it is launched. -/// -/// `os_image_hash` is SHA-256 over the CBOR representation of this projection, -/// not over the outer measurement.json field names. +/// Image-invariant AMD SEV-SNP measurement material. It deliberately excludes +/// per-deployment values (vcpus, vcpu_type, guest_features, app_id, +/// compose_hash): the same OS image carries identical SNP material regardless of +/// how it is launched. The OS image identity itself is always +/// `sha256(sha256sum.txt)`; this material is bound to that identity by the +/// `measurement.snp.cbor` entry in `sha256sum.txt`. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SevOsImageMeasurement { - /// SHA-256 of the kernel command line bytes as measured in the SEV-SNP hash - /// table (trimmed command line plus trailing NUL byte). This avoids carrying - /// the full plaintext command line in image metadata while preserving the - /// exact measured value used by OVMF/QEMU. - #[serde(with = "hex_bytes")] - pub kernel_cmdline_sha256: Vec, + /// Original image kernel cmdline used for SNP measured launch. + pub base_cmdline: String, #[serde(with = "hex_bytes")] pub ovmf_hash: Vec, #[serde(with = "hex_bytes")] @@ -388,9 +451,10 @@ pub struct SevOsImageMeasurement { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] struct CborSevOsImageMeasurement { - /// Measured kernel cmdline SHA-256. - #[serde(rename = "cmdline_sha256", with = "hex_bytes")] - kernel_cmdline_sha256: Vec, + version: u32, + /// Original image kernel cmdline used for SNP measured launch. + #[serde(rename = "cmdline")] + base_cmdline: String, /// OVMF launch digest. #[serde(with = "hex_bytes")] ovmf_hash: Vec, @@ -411,7 +475,8 @@ struct CborSevOsImageMeasurement { impl From<&SevOsImageMeasurement> for CborSevOsImageMeasurement { fn from(measurement: &SevOsImageMeasurement) -> Self { Self { - kernel_cmdline_sha256: measurement.kernel_cmdline_sha256.clone(), + version: SevOsImageMeasurement::VERSION, + base_cmdline: measurement.base_cmdline.clone(), ovmf_hash: measurement.ovmf_hash.clone(), kernel_hash: measurement.kernel_hash.clone(), initrd_hash: measurement.initrd_hash.clone(), @@ -425,7 +490,7 @@ impl From<&SevOsImageMeasurement> for CborSevOsImageMeasurement { impl From for SevOsImageMeasurement { fn from(measurement: CborSevOsImageMeasurement) -> Self { Self { - kernel_cmdline_sha256: measurement.kernel_cmdline_sha256, + base_cmdline: measurement.base_cmdline, ovmf_hash: measurement.ovmf_hash, kernel_hash: measurement.kernel_hash, initrd_hash: measurement.initrd_hash, @@ -441,7 +506,9 @@ impl From for SevOsImageMeasurement { } impl SevOsImageMeasurement { - /// CBOR representation used as the `os_image_hash` input. + pub const VERSION: u32 = 3; + + /// CBOR representation stored as `measurement.snp.cbor`. pub fn to_cbor_vec(&self) -> Vec { cbor_to_vec( &CborSevOsImageMeasurement::from(self), @@ -450,7 +517,15 @@ impl SevOsImageMeasurement { } pub fn from_cbor_slice(bytes: &[u8]) -> Result { - cbor_from_slice::(bytes, "SevOsImageMeasurement").map(Into::into) + let cbor = cbor_from_slice::(bytes, "SevOsImageMeasurement")?; + if cbor.version != Self::VERSION { + return Err(format!( + "SevOsImageMeasurement: unsupported version {}, expected {}", + cbor.version, + Self::VERSION + )); + } + Ok(cbor.into()) } pub fn cbor_json_value_from_slice(bytes: &[u8]) -> Result { @@ -459,39 +534,35 @@ impl SevOsImageMeasurement { .map_err(|e| format!("SevOsImageMeasurement: failed to convert CBOR to JSON: {e}")) } - /// SHA-256 over the CBOR representation of this projection. - pub fn os_image_hash(&self) -> [u8; 32] { + /// SHA-256 over the CBOR measurement material. + pub fn measurement_hash(&self) -> [u8; 32] { sha256(&self.to_cbor_vec()) } } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SevOsImageMeasurementDocument { - /// Document schema version. - #[serde(alias = "v")] - pub version: u32, - /// SHA-256 over the CBOR `measurement` bytes. This field is not included in - /// its own hash input. - #[serde(alias = "h")] - pub os_image_hash: String, - /// CBOR bytes for `SevOsImageMeasurement`. + /// Raw `sha256sum.txt` bytes. `sha256(sha256sum)` is the unified + /// `os_image_hash`. + #[serde(with = "hex_bytes")] + pub sha256sum: Vec, + /// Raw bytes of `measurement.snp.cbor`. #[serde(alias = "m", with = "hex_bytes")] pub measurement: Vec, } impl SevOsImageMeasurementDocument { - pub const VERSION: u32 = 2; - - pub fn new(measurement: SevOsImageMeasurement) -> Self { - let measurement = measurement.to_cbor_vec(); - let os_image_hash = sha256_hex(&measurement); + pub fn new(sha256sum: Vec, measurement: Vec) -> Self { Self { - version: Self::VERSION, - os_image_hash, + sha256sum, measurement, } } + pub fn from_measurement(sha256sum: Vec, measurement: SevOsImageMeasurement) -> Self { + Self::new(sha256sum, measurement.to_cbor_vec()) + } + pub fn decode_measurement(&self) -> Result { SevOsImageMeasurement::from_cbor_slice(&self.measurement) } @@ -500,20 +571,22 @@ impl SevOsImageMeasurementDocument { SevOsImageMeasurement::cbor_json_value_from_slice(&self.measurement) } - pub fn measurement_os_image_hash(&self) -> [u8; 32] { - sha256(&self.measurement) + pub fn verify(&self, os_image_hash: &[u8]) -> Result<(), String> { + verify_measurement_material( + os_image_hash, + &self.sha256sum, + &self.measurement, + SNP_MEASUREMENT_FILENAME, + ) } } -/// Image-invariant projection that determines the TDX OS image identity. -/// -/// This is the build-time, image-static material for the verifier-side +/// Image-invariant TDX measurement material for the verifier-side /// no-image-download TDX path. Dynamic VM parameters (vCPU count, RAM size, /// QEMU PCI topology, GPU count, etc.) are deliberately excluded and must be -/// supplied by `VmConfig` when replaying RTMRs. -/// -/// `os_image_hash` is SHA-256 over the CBOR representation of this projection, -/// not over the outer measurement.json field names. +/// supplied by `VmConfig` when replaying RTMRs. The OS image identity itself is +/// always `sha256(sha256sum.txt)`; this material is bound to that identity by +/// the `measurement.tdx.cbor` entry in `sha256sum.txt`. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct TdxOsImageMeasurement { pub image: TdxImageMeasurement, @@ -591,6 +664,7 @@ struct CborTdxTdvfMeasurement { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] struct CborTdxOsImageMeasurement { + version: u32, image: CborTdxImageMeasurement, tdvf: CborTdxTdvfMeasurement, } @@ -598,6 +672,7 @@ struct CborTdxOsImageMeasurement { impl From<&TdxOsImageMeasurement> for CborTdxOsImageMeasurement { fn from(measurement: &TdxOsImageMeasurement) -> Self { Self { + version: TdxOsImageMeasurement::VERSION, image: CborTdxImageMeasurement { kernel_cmdline_sha384: measurement.image.kernel_cmdline_sha384.clone(), kernel_authenticode: measurement.image.kernel_authenticode.clone(), @@ -637,20 +712,19 @@ impl From for TdxOsImageMeasurement { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct TdxOsImageMeasurementDocument { - /// Document schema version. - #[serde(alias = "v")] - pub version: u32, - /// SHA-256 over the CBOR `measurement` bytes. This field is not included in - /// its own hash input. - #[serde(alias = "h")] - pub os_image_hash: String, - /// CBOR bytes for `TdxOsImageMeasurement`. + /// Raw `sha256sum.txt` bytes. `sha256(sha256sum)` is the unified + /// `os_image_hash`. + #[serde(with = "hex_bytes")] + pub sha256sum: Vec, + /// Raw bytes of `measurement.tdx.cbor`. #[serde(alias = "m", with = "hex_bytes")] pub measurement: Vec, } impl TdxOsImageMeasurement { - /// CBOR representation used as the `os_image_hash` input. + pub const VERSION: u32 = 3; + + /// CBOR representation stored as `measurement.tdx.cbor`. pub fn to_cbor_vec(&self) -> Vec { cbor_to_vec( &CborTdxOsImageMeasurement::from(self), @@ -660,6 +734,13 @@ impl TdxOsImageMeasurement { pub fn from_cbor_slice(bytes: &[u8]) -> Result { let cbor = cbor_from_slice::(bytes, "TdxOsImageMeasurement")?; + if cbor.version != Self::VERSION { + return Err(format!( + "TdxOsImageMeasurement: unsupported version {}, expected {}", + cbor.version, + Self::VERSION + )); + } Ok(cbor.into()) } @@ -669,25 +750,24 @@ impl TdxOsImageMeasurement { .map_err(|e| format!("TdxOsImageMeasurement: failed to convert CBOR to JSON: {e}")) } - /// SHA-256 over the CBOR representation of this projection. - pub fn os_image_hash(&self) -> [u8; 32] { + /// SHA-256 over the CBOR measurement material. + pub fn measurement_hash(&self) -> [u8; 32] { sha256(&self.to_cbor_vec()) } } impl TdxOsImageMeasurementDocument { - pub const VERSION: u32 = 2; - - pub fn new(measurement: TdxOsImageMeasurement) -> Self { - let measurement = measurement.to_cbor_vec(); - let os_image_hash = sha256_hex(&measurement); + pub fn new(sha256sum: Vec, measurement: Vec) -> Self { Self { - version: Self::VERSION, - os_image_hash, + sha256sum, measurement, } } + pub fn from_measurement(sha256sum: Vec, measurement: TdxOsImageMeasurement) -> Self { + Self::new(sha256sum, measurement.to_cbor_vec()) + } + pub fn decode_measurement(&self) -> Result { TdxOsImageMeasurement::from_cbor_slice(&self.measurement) } @@ -696,8 +776,13 @@ impl TdxOsImageMeasurementDocument { TdxOsImageMeasurement::cbor_json_value_from_slice(&self.measurement) } - pub fn measurement_os_image_hash(&self) -> [u8; 32] { - sha256(&self.measurement) + pub fn verify(&self, os_image_hash: &[u8]) -> Result<(), String> { + verify_measurement_material( + os_image_hash, + &self.sha256sum, + &self.measurement, + TDX_MEASUREMENT_FILENAME, + ) } } @@ -713,7 +798,7 @@ pub struct OsImageMeasurementDocument { } impl OsImageMeasurementDocument { - pub const VERSION: u32 = 2; + pub const VERSION: u32 = 3; pub fn new( tdx: Option, diff --git a/kms/src/main_service.rs b/kms/src/main_service.rs index ca40541d3..9bbfefc80 100644 --- a/kms/src/main_service.rs +++ b/kms/src/main_service.rs @@ -645,17 +645,47 @@ mod tests { } } + fn snp_measurement_document( + input: &MeasurementInput, + ) -> dstack_mr::sev::SnpMeasurementDocument { + let measurement = dstack_mr::sev::sev_os_image_measurement_from_input(input) + .unwrap() + .to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(sha2::Sha256::digest(&measurement)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + dstack_mr::sev::SnpMeasurementDocument { + sha256sum, + measurement, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type.clone(), + guest_features: input.guest_features, + } + } + + fn snp_vm_config( + input: &MeasurementInput, + mr_config: &dstack_types::mr_config::MrConfigV3, + ) -> String { + let document = snp_measurement_document(input); + serde_json::json!({ + "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.sha256sum)), + "sev_snp_measurement": serde_json::to_string(&document).unwrap(), + "mr_config": mr_config.to_canonical_json(), + }) + .to_string() + } + #[test] fn build_boot_info_for_attestation_accepts_snp_vm_config_path() { let input = valid_snp_measurement_input(); let measurement = compute_expected_measurement(&input).unwrap(); let mr_config = valid_snp_mr_config(); let attestation = verified_snp_attestation(measurement, [0xab; 64]); - let vm_config = serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), - "mr_config": mr_config.to_canonical_json(), - }) - .to_string(); + let vm_config = snp_vm_config(&input, &mr_config); let boot_info = build_boot_info_for_attestation(&attestation, false, &vm_config) .expect("snp attestation should build boot info through vm_config path"); @@ -671,11 +701,7 @@ mod tests { let input = valid_snp_measurement_input(); let measurement = compute_expected_measurement(&input).unwrap(); let mr_config = valid_snp_mr_config(); - let embedded_config = serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), - "mr_config": mr_config.to_canonical_json(), - }) - .to_string(); + let embedded_config = snp_vm_config(&input, &mr_config); let attestation = verified_snp_attestation_with_config( measurement, [0xab; 64], @@ -697,11 +723,7 @@ mod tests { let measurement = compute_expected_measurement(&input).unwrap(); let mr_config = valid_snp_mr_config(); let attestation = verified_snp_attestation(measurement, [0xab; 64]); - let vm_config = serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), - "mr_config": mr_config.to_canonical_json(), - }) - .to_string(); + let vm_config = snp_vm_config(&input, &mr_config); let boot_info = build_boot_info_for_attestation(&attestation, false, &vm_config) .expect("self-contained SNP vm_config should not require KMS-local sev_snp config"); @@ -714,11 +736,7 @@ mod tests { let measurement = compute_expected_measurement(&input).unwrap(); let mr_config = valid_snp_mr_config(); let attestation = verified_snp_attestation(measurement, [0xab; 64]); - let vm_config = serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), - "mr_config": mr_config.to_canonical_json(), - }) - .to_string(); + let vm_config = snp_vm_config(&input, &mr_config); build_boot_info_for_attestation(&attestation, false, &vm_config).unwrap() } diff --git a/kms/src/main_service/amd_attest.rs b/kms/src/main_service/amd_attest.rs index da6831170..65d97c213 100644 --- a/kms/src/main_service/amd_attest.rs +++ b/kms/src/main_service/amd_attest.rs @@ -36,10 +36,9 @@ use super::upgrade_authority::BootInfo; // working. `allow(unused_imports)` because some are consumed only by tests. #[allow(unused_imports)] pub(crate) use dstack_mr::sev::{ - compute_expected_measurement, parse_snp_inputs_from_vm_config, snp_measurement_os_image_hash, - snp_mr_aggregated_digest, validate_measurement_input, validate_snp_mr_config_binding, - MeasurementInput, OvmfSectionParam, SnpLaunchInputs, MAX_OVMF_METADATA_PAGES, - MAX_OVMF_SECTIONS, MAX_VCPUS, + compute_expected_measurement, parse_snp_inputs_from_vm_config, snp_mr_aggregated_digest, + validate_measurement_input, validate_snp_mr_config_binding, MeasurementInput, OvmfSectionParam, + SnpLaunchInputs, MAX_OVMF_METADATA_PAGES, MAX_OVMF_SECTIONS, MAX_VCPUS, }; pub(crate) fn validate_amd_snp_measurement_binding( @@ -77,8 +76,7 @@ pub(crate) fn build_amd_snp_boot_info( ) -> Result { let mr_config = test_mr_config(vec![0x11; 20], vec![0x22; 32]); let mr_config_document = mr_config.to_canonical_json(); - let measurement_document = serde_json::to_string(input) - .context("failed to serialize amd sev-snp measurement input")?; + let os_image_hash = test_os_image_hash(input)?; let host_data = MrConfigV3::snp_host_data_from_document(&mr_config_document); build_amd_snp_boot_info_with_tcb_status( verified_measurement, @@ -87,7 +85,7 @@ pub(crate) fn build_amd_snp_boot_info( "UpToDate", &[], input, - &measurement_document, + &os_image_hash, &mr_config_document, ) } @@ -100,13 +98,12 @@ fn build_amd_snp_boot_info_with_tcb_status( tcb_status: &str, advisory_ids: &[String], input: &MeasurementInput, - measurement_document: &str, + os_image_hash: &[u8], mr_config_document: &str, ) -> Result { validate_amd_snp_measurement_binding(verified_measurement, input)?; let mr_config = validate_snp_mr_config_binding(verified_host_data, mr_config_document)?; - let os_image_hash = snp_measurement_os_image_hash(measurement_document)?; let mr_system = Sha256::digest(verified_measurement).to_vec(); let mr_aggregated = snp_mr_aggregated_digest(verified_measurement, verified_host_data); let key_provider_info = mr_config_key_provider_info(&mr_config)?; @@ -114,7 +111,7 @@ fn build_amd_snp_boot_info_with_tcb_status( Ok(BootInfo { attestation_mode: AttestationMode::DstackAmdSevSnp, mr_aggregated, - os_image_hash, + os_image_hash: os_image_hash.to_vec(), mr_system, app_id: mr_config.app_id.clone(), compose_hash: mr_config.compose_hash.clone(), @@ -136,8 +133,8 @@ fn build_amd_snp_boot_info_with_tcb_status( pub(crate) fn build_amd_snp_boot_info_from_verified_attestation( attestation: &VerifiedAttestation, input: &MeasurementInput, - measurement_document: &str, mr_config_document: &str, + os_image_hash: &[u8], ) -> Result { let verified = attestation .report @@ -150,7 +147,7 @@ pub(crate) fn build_amd_snp_boot_info_from_verified_attestation( verified.tcb_info.tcb_status(), &verified.advisory_ids, input, - measurement_document, + os_image_hash, mr_config_document, ) } @@ -166,14 +163,15 @@ pub(crate) fn build_amd_snp_boot_info_from_verified_attestation_and_vm_config( ) -> Result { let SnpLaunchInputs { input, - measurement_document, + os_image_hash, mr_config_document, + .. } = parse_snp_inputs_from_vm_config(vm_config)?; build_amd_snp_boot_info_from_verified_attestation( attestation, &input, - &measurement_document, &mr_config_document, + &os_image_hash, ) } @@ -201,6 +199,51 @@ fn test_mr_config(app_id: Vec, compose_hash: Vec) -> MrConfigV3 { ) } +#[cfg(test)] +fn test_snp_measurement_document( + input: &MeasurementInput, +) -> Result { + let measurement = dstack_mr::sev::sev_os_image_measurement_from_input(input)?.to_cbor_vec(); + let measurement_hash = Sha256::digest(&measurement); + let sha256sum = format!( + "{} {}\n", + hex::encode(measurement_hash), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + Ok(dstack_mr::sev::SnpMeasurementDocument { + sha256sum, + measurement, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type.clone(), + guest_features: input.guest_features, + }) +} + +#[cfg(test)] +fn test_os_image_hash(input: &MeasurementInput) -> Result> { + Ok( + dstack_types::image_hash_from_sha256sum(&test_snp_measurement_document(input)?.sha256sum) + .to_vec(), + ) +} + +#[cfg(test)] +fn test_snp_measurement_document_json(input: &MeasurementInput) -> Result { + serde_json::to_string(&test_snp_measurement_document(input)?) + .context("failed to serialize test SNP measurement document") +} + +#[cfg(test)] +fn test_vm_config(input: &MeasurementInput, mr_config: &MrConfigV3) -> Result { + Ok(serde_json::json!({ + "os_image_hash": hex::encode(test_os_image_hash(input)?), + "sev_snp_measurement": test_snp_measurement_document_json(input)?, + "mr_config": mr_config.to_canonical_json(), + }) + .to_string()) +} + #[cfg(test)] mod tests { use super::*; @@ -251,7 +294,7 @@ mod tests { } fn measurement_document(input: &MeasurementInput) -> String { - serde_json::to_string(input).expect("measurement input should serialize") + test_snp_measurement_document_json(input).expect("measurement input should serialize") } fn verified_snp_attestation( @@ -327,10 +370,7 @@ mod tests { assert_eq!(boot_info.device_id, chip_id.to_vec()); assert_eq!(boot_info.app_id, vec![0x11; 20]); assert_eq!(boot_info.compose_hash, vec![0x22; 32]); - assert_eq!( - boot_info.os_image_hash, - snp_measurement_os_image_hash(&measurement_document(&input)).unwrap() - ); + assert_eq!(boot_info.os_image_hash, test_os_image_hash(&input).unwrap()); assert_eq!(boot_info.mr_system.len(), 32); assert!(!boot_info.key_provider_info.is_empty()); assert_eq!(boot_info.instance_id.len(), 20); @@ -357,8 +397,8 @@ mod tests { let boot_info = build_amd_snp_boot_info_from_verified_attestation( &attestation, &input, - &measurement_document(&input), &mr_config_document, + &test_os_image_hash(&input)?, ) .expect("verified snp attestation should feed boot info helper"); @@ -418,8 +458,8 @@ mod tests { let boot_info = build_amd_snp_boot_info_from_verified_attestation( &attestation, &input, - &measurement_document(&input), &mr_config_document, + &test_os_image_hash(&input)?, ) .expect("verified snp attestation should feed boot info helper"); @@ -436,11 +476,7 @@ mod tests { let chip_id = [0xab; 64]; let mr_config = valid_mr_config(&input)?; let attestation = verified_snp_attestation(verified, chip_id, &mr_config); - let vm_config = serde_json::json!({ - "sev_snp_measurement": measurement_document(&input), - "mr_config": mr_config.to_canonical_json(), - }) - .to_string(); + let vm_config = test_vm_config(&input, &mr_config)?; let boot_info = build_amd_snp_boot_info_from_verified_attestation_and_vm_config( &attestation, @@ -463,7 +499,7 @@ mod tests { let err = build_amd_snp_boot_info_from_verified_attestation_and_vm_config( &attestation, - r#"{"os_image_hash":"0x00"}"#, + &serde_json::json!({ "os_image_hash": hex::encode([0u8; 32]) }).to_string(), ) .expect_err("missing sev_snp_measurement must fail closed"); assert!( @@ -475,10 +511,15 @@ mod tests { #[test] fn vm_config_measurement_parser_rejects_unknown_measurement_fields() { - let mut measurement = serde_json::to_value(valid_input()).unwrap(); + let input = valid_input(); + let mr_config = valid_mr_config(&input).unwrap(); + let mut measurement = + serde_json::to_value(test_snp_measurement_document(&input).unwrap()).unwrap(); measurement["unexpected"] = serde_json::json!(true); let vm_config = serde_json::json!({ + "os_image_hash": hex::encode(test_os_image_hash(&input).unwrap()), "sev_snp_measurement": measurement.to_string(), + "mr_config": mr_config.to_canonical_json(), }) .to_string(); @@ -492,20 +533,34 @@ mod tests { #[test] fn vm_config_measurement_parser_bounds_ovmf_sections_during_deserialization() { - let mut measurement = serde_json::to_value(valid_input()).unwrap(); - measurement["ovmf_sections"] = serde_json::Value::Array( - (0..=MAX_OVMF_SECTIONS) - .map(|_| { - serde_json::json!({ - "gpa": 0x100000u64, - "size": 0x1000u64, - "section_type": 1u32, - }) - }) - .collect(), - ); + let input = valid_input(); + let mr_config = valid_mr_config(&input).unwrap(); + let mut image = dstack_mr::sev::sev_os_image_measurement_from_input(&input).unwrap(); + image.ovmf_sections = (0..=MAX_OVMF_SECTIONS) + .map(|_| dstack_types::OvmfSection { + gpa: 0x100000, + size: 0x1000, + section_type: 1, + }) + .collect(); + let measurement_cbor = image.to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(Sha256::digest(&measurement_cbor)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + let document = dstack_mr::sev::SnpMeasurementDocument { + sha256sum, + measurement: measurement_cbor, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type.clone(), + guest_features: input.guest_features, + }; let vm_config = serde_json::json!({ - "sev_snp_measurement": measurement.to_string(), + "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.sha256sum)), + "sev_snp_measurement": serde_json::to_string(&document).unwrap(), + "mr_config": mr_config.to_canonical_json(), }) .to_string(); @@ -548,8 +603,8 @@ mod tests { let err = build_amd_snp_boot_info_from_verified_attestation( &attestation, &input, - &measurement_document(&input), &mr_config_document, + &test_os_image_hash(&input)?, ) .expect_err("non-snp verified attestation must reject"); assert!( @@ -567,7 +622,7 @@ mod tests { let chip_id = [0xcd; 64]; let mr_config = test_mr_config(vec![0x11; 20], vec![0x22; 32]); let mr_config_document = mr_config.to_canonical_json(); - let measurement_doc = measurement_document(&input); + let os_image_hash = test_os_image_hash(&input)?; let host_data = MrConfigV3::snp_host_data_from_document(&mr_config_document); let boot_info = build_amd_snp_boot_info_with_tcb_status( &verified, @@ -576,7 +631,7 @@ mod tests { "UpToDate", &[], &input, - &measurement_doc, + &os_image_hash, &mr_config_document, )?; @@ -596,7 +651,7 @@ mod tests { "UpToDate", &[], &input, - &measurement_doc, + &os_image_hash, &changed_mr_config_document, )?; diff --git a/kms/src/onboard_service.rs b/kms/src/onboard_service.rs index 272e5dc56..deb105f39 100644 --- a/kms/src/onboard_service.rs +++ b/kms/src/onboard_service.rs @@ -193,8 +193,7 @@ fn build_attestation_info_response( mod tests { use super::*; use crate::main_service::amd_attest::{ - compute_expected_measurement, snp_measurement_os_image_hash, MeasurementInput, - OvmfSectionParam, + compute_expected_measurement, MeasurementInput, OvmfSectionParam, }; use sha2::Digest; @@ -275,14 +274,38 @@ mod tests { } } + fn snp_measurement_document( + input: &MeasurementInput, + ) -> dstack_mr::sev::SnpMeasurementDocument { + let measurement = dstack_mr::sev::sev_os_image_measurement_from_input(input) + .unwrap() + .to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(sha2::Sha256::digest(&measurement)), + dstack_types::SNP_MEASUREMENT_FILENAME + ) + .into_bytes(); + dstack_mr::sev::SnpMeasurementDocument { + sha256sum, + measurement, + vcpus: input.vcpus, + vcpu_type: input.vcpu_type.clone(), + guest_features: input.guest_features, + } + } + #[test] fn attestation_info_response_uses_snp_boot_info_and_chip_id() { let input = valid_snp_measurement_input(); let measurement = compute_expected_measurement(&input).unwrap(); let mr_config = valid_snp_mr_config(); let attestation = verified_snp_attestation(measurement, [0xab; 64]); + let snp_document = snp_measurement_document(&input); + let os_image_hash = dstack_types::image_hash_from_sha256sum(&snp_document.sha256sum); let vm_config = serde_json::json!({ - "sev_snp_measurement": serde_json::to_string(&input).unwrap(), + "os_image_hash": hex::encode(os_image_hash), + "sev_snp_measurement": serde_json::to_string(&snp_document).unwrap(), "mr_config": mr_config.to_canonical_json(), }) .to_string(); @@ -303,10 +326,7 @@ mod tests { ); assert_eq!(response.ppid, vec![0xab; 64]); assert_eq!(response.mr_aggregated.len(), 32); - assert_eq!( - response.os_image_hash, - snp_measurement_os_image_hash(&serde_json::to_string(&input).unwrap()).unwrap() - ); + assert_eq!(response.os_image_hash, os_image_hash.to_vec()); assert_eq!(response.attestation_mode, "dstack-amd-sev-snp"); assert_eq!(response.site_name, "test-site"); assert_eq!(response.eth_rpc_url, "https://rpc.example"); diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index d055e04c6..cbf01f193 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3372c616370692d6c6f6164657224414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef24616370692d7273647024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b62c616370692d7461626c6573244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b5165137b226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333037383632383038343262373336343238376133613730643936663765333039323532383537626562343566623166393133313461326561383633646230616463303463383433316563626632396139363634303536303436333161356161623837333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", - "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"sha256sum\":\"3863396539353566306235373763633839343561383931613334636366613562386530386262356535643234393939323630336536346464313438373065336320206d6561737572656d656e742e7464782e63626f720a\",\"measurement\":\"a36776657273696f6e0365696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index cf45eb4dc..43e7b544a 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -2,5 +2,5 @@ "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"acpi-loader\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"acpi-rsdp\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"acpi-tables\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"050bf89570575fe8fab4cb8f0a62a9e64efe8ead\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", "report_data": "646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51", - "vm_config": "{\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"version\":2,\"os_image_hash\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\",\"measurement\":\"a265696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"sha256sum\":\"3863396539353566306235373763633839343561383931613334636366613562386530386262356535643234393939323630336536346464313438373065336320206d6561737572656d656e742e7464782e63626f720a\",\"measurement\":\"a36776657273696f6e0365696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 8eea115b4..9b05985c5 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -2,8 +2,9 @@ This fixture was captured from the local meta-dstack e2e stack using TDX `tdx_attestation_variant = "lite"`. It covers the KMS/verifier path that -verifies the OS image from `vm_config.tdx_measurement`, without downloading the -image and without running the QEMU ACPI table helper. +verifies the OS image from `vm_config.tdx_measurement` (`sha256sum.txt` bytes +plus `measurement.tdx.cbor` bytes), without downloading the image and without +running the QEMU ACPI table helper. Files: @@ -31,7 +32,7 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) -- `vm_config.os_image_hash = 07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d` +- `vm_config.os_image_hash = e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db` - The top-level `event_log` and stripped attestation keep the three named RTMR0 `ACPI DATA` digests (`acpi-loader`, `acpi-rsdp`, `acpi-tables`) and marker payloads needed by the lite verifier, plus RTMR3 runtime events. diff --git a/verifier/src/verification.rs b/verifier/src/verification.rs index 42948b253..2acc89bd9 100644 --- a/verifier/src/verification.rs +++ b/verifier/src/verification.rs @@ -648,8 +648,8 @@ impl CvmVerifier { /// document in its `vm_config`; we recompute the launch measurement from /// those inputs and require it to equal the hardware-signed `MEASUREMENT` /// (which is what makes the otherwise-untrusted inputs trustworthy), require - /// `HOST_DATA` to bind the MrConfigV3 document, and then derive the - /// image-invariant `os_image_hash`. The shared recomputation in + /// `HOST_DATA` to bind the MrConfigV3 document, and then verify/return the + /// unified `os_image_hash` (`sha256(sha256sum.txt)`). The shared recomputation in /// `dstack_mr::sev` is the same code path the KMS uses for key release, so a /// quote that the KMS would release keys for verifies here too. fn verify_os_image_hash_for_dstack_sev( @@ -666,9 +666,8 @@ impl CvmVerifier { let binding = dstack_mr::sev::verify_sev_launch(&report.measurement, &report.host_data, raw_config) .context("amd sev-snp launch verification failed")?; - // The os_image_hash derived from the measurement-bound launch inputs is - // the authoritative one; surface it (overriding any guest-advertised - // value, which is not independently trusted). + // verify_sev_launch has checked that vm_config.os_image_hash commits to + // the supplied sha256sum.txt and measurement.snp.cbor material. vm_config.os_image_hash = binding.os_image_hash; details.tcb_status = Some(report.tcb_info.tcb_status().to_string()); details.advisory_ids = report.advisory_ids.clone(); @@ -798,23 +797,10 @@ impl CvmVerifier { .tdx_measurement .as_ref() .context("tdx lite attestation requires vm_config.tdx_measurement")?; - let document_hash = hex::decode(&document.os_image_hash) - .context("vm_config.tdx_measurement.os_image_hash is not valid hex")?; - if document_hash != vm_config.os_image_hash { - bail!( - "tdx measurement os_image_hash mismatch: vm_config={}, document={}", - hex::encode(&vm_config.os_image_hash), - document.os_image_hash - ); - } - let computed_hash = document.measurement_os_image_hash(); - if computed_hash.as_slice() != vm_config.os_image_hash { - bail!( - "tdx measurement document hash mismatch: vm_config={}, computed={}", - hex::encode(&vm_config.os_image_hash), - hex::encode(computed_hash) - ); - } + document + .verify(&vm_config.os_image_hash) + .map_err(anyhow::Error::msg) + .context("tdx lite measurement material does not match os_image_hash")?; let measurement = document .decode_measurement() .map_err(anyhow::Error::msg) @@ -829,8 +815,8 @@ impl CvmVerifier { } } - // Compute expected measurements. New TDX images advertise the - // measurement.json-derived TDX os_image_hash; verify those without + // Compute expected measurements. TDX lite keeps the unified image hash + // and carries split measurement material; verify it without // downloading the image or running QEMU-derived ACPI table generators. // The guest labels the three RTMR0 ACPI DATA events as acpi-loader, // acpi-rsdp, and acpi-tables before exposing the event log, so the @@ -1095,24 +1081,12 @@ impl CvmVerifier { } } - // Legacy images use sha256(sha256sum.txt) as os_image_hash. Newer - // TDX/SNP images may instead be addressed by measurement.json-derived - // hashes, so accept those too after recomputing them from extracted - // image files. + // All image modes are addressed by sha256(sha256sum.txt). Extra + // measurement CBOR files are ordinary sha256sum.txt entries and do not + // define alternate image hashes. let legacy_os_image_hash = Sha256::new_with_prefix(files_doc.as_bytes()).finalize(); - let mut image_hash_matches = hex::encode(legacy_os_image_hash) == hex_os_image_hash; - if !image_hash_matches { - image_hash_matches = dstack_mr::tdx::tdx_os_image_hash_for_image_dir(&extracted_dir) - .map(|hash| hex::encode(hash) == hex_os_image_hash) - .unwrap_or(false) - || dstack_mr::sev::sev_os_image_hash_for_image_dir(&extracted_dir) - .map(|hash| hex::encode(hash) == hex_os_image_hash) - .unwrap_or(false); - } - if !image_hash_matches { - bail!( - "os_image_hash matches neither sha256sum.txt nor measurement.json-derived hashes" - ); + if hex::encode(legacy_os_image_hash) != hex_os_image_hash { + bail!("os_image_hash does not match sha256(sha256sum.txt)"); } // Move the extracted files to the destination directory diff --git a/vmm/src/app.rs b/vmm/src/app.rs index a20ef3b74..777c40c10 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1304,33 +1304,6 @@ fn mr_config_from_vm_config(sys_config: &serde_json::Value) -> Result Result { - Ok(hex::encode(sha256_file(path)?)) -} - -fn amd_sev_snp_ovmf_measurement_info(image: &Image) -> Result { - // Measure the same firmware the guest launches with: the SEV firmware - // (bios-sev) when present, falling back to the generic bios. The OVMF - // parsing/GCTX logic is shared with `dstack-mr sev-os-image-hash`. - let bios = image - .firmware(true) - .map(|p| p.as_path()) - .ok_or_else(|| anyhow::anyhow!("bios/OVMF is required for amd sev-snp measurement"))?; - dstack_mr::sev::ovmf_measurement_info(bios).with_context(|| { - format!( - "failed to extract amd sev-snp OVMF measurement metadata from {}", - bios.display() - ) - }) -} - -fn amd_sev_snp_measurement_base_cmdline(base_cmdline: Option<&str>) -> Result { - match base_cmdline.map(str::trim) { - Some(cmdline) if !cmdline.is_empty() => Ok(cmdline.to_string()), - _ => anyhow::bail!("metadata.json cmdline is required for amd sev-snp measurement"), - } -} - fn sha256_file(path: impl AsRef) -> Result<[u8; 32]> { let data = fs::read(path).context("Failed to read file for sha256")?; let mut out = [0u8; 32]; @@ -1340,9 +1313,9 @@ fn sha256_file(path: impl AsRef) -> Result<[u8; 32]> { fn image_supports_tdx_lite(image: &Image) -> bool { image - .tdx_digest + .digest .as_deref() - .is_some_and(|digest| !digest.trim().is_empty()) + .is_some_and(|d| !d.trim().is_empty()) && image.tdx_measurement.is_some() } @@ -1363,35 +1336,19 @@ fn make_vm_config( } else { dstack_types::TdxAttestationVariant::Legacy }; - // AMD SEV-SNP binds the OS image through the launch-measurement-derived - // os_image_hash, computed at image build time and shipped in - // `measurement.json.snp.os_image_hash` (legacy images used `digest.sev.txt`). - // TDX keeps using the generic content digest unless the resolved - // attestation policy selects the lite variant. - let os_image_hash = if is_amd_sev_snp { - let digest = image.sev_digest.as_deref().context( - "amd sev-snp image is missing measurement.json SNP hash; \ - rebuild the image so `dstack-mr os-image-measurement` emits it", - )?; - hex::decode(digest).context("SNP os_image_hash is not valid hex")? - } else if tdx_attestation_variant.is_lite() { - let digest = image.tdx_digest.as_deref().context( - "tdx lite attestation requested but image is missing \ - measurement.json TDX hash; rebuild the image so \ - `dstack-mr os-image-measurement` emits it", - )?; - hex::decode(digest).context("TDX os_image_hash is not valid hex")? - } else { - image - .digest - .as_ref() - .and_then(|d| hex::decode(d).ok()) - .unwrap_or_default() - }; + // All dstack OS-image verification modes use the same public image + // identity: digest.txt = sha256(sha256sum.txt). Lite TDX/SNP carry extra + // split CBOR measurement material, but that material is committed by + // sha256sum.txt instead of defining a second image hash. + let os_image_hash = image + .digest + .as_ref() + .and_then(|d| hex::decode(d).ok()) + .unwrap_or_default(); let tdx_measurement = if tdx_attestation_variant.is_lite() { Some(image.tdx_measurement.clone().context( "tdx lite attestation requested but image is missing \ - measurement.json TDX measurement material", + measurement.tdx.cbor/sha256sum.txt measurement material", )?) } else { None @@ -1423,26 +1380,20 @@ fn make_vm_config( // For backward compatibility config["spec_version"] = serde_json::Value::from(1); if is_amd_sev_snp { - // The rootfs identity is part of the measured kernel cmdline; do not - // carry it as a standalone, unmeasured launch-input field. - dstack_mr::sev::rootfs_hash_from_cmdline(image.info.cmdline.as_deref())?; if let Some(mr_config) = mr_config { MrConfigV3::from_document(&mr_config).context("Invalid mr_config document")?; config["mr_config"] = serde_json::Value::String(mr_config); } - let ovmf = amd_sev_snp_ovmf_measurement_info(image)?; - let measurement = json!({ - "base_cmdline": amd_sev_snp_measurement_base_cmdline(image.info.cmdline.as_deref())?, - "ovmf_hash": ovmf.ovmf_hash, - "kernel_hash": file_sha256_hex(&image.kernel)?, - "initrd_hash": file_sha256_hex(&image.initrd)?, - "sev_hashes_table_gpa": ovmf.sev_hashes_table_gpa, - "sev_es_reset_eip": ovmf.sev_es_reset_eip, - "vcpus": effective_vcpus, - "vcpu_type": "EPYC-v4", - "guest_features": 1, - "ovmf_sections": ovmf.sections, - }); + let image_measurement = image.sev_measurement.as_ref().context( + "amd sev-snp image is missing measurement.snp.cbor/sha256sum.txt measurement material", + )?; + let measurement = dstack_mr::sev::SnpMeasurementDocument { + sha256sum: image_measurement.sha256sum.clone(), + measurement: image_measurement.measurement.clone(), + vcpus: effective_vcpus, + vcpu_type: Some("EPYC-v4".to_string()), + guest_features: 1, + }; config["sev_snp_measurement"] = serde_json::Value::String( serde_json::to_string(&measurement) .context("Failed to serialize amd sev-snp measurement input")?, @@ -1561,7 +1512,7 @@ mod tests { } fn dummy_tdx_measurement_document() -> TdxOsImageMeasurementDocument { - TdxOsImageMeasurementDocument::new(TdxOsImageMeasurement { + let measurement = TdxOsImageMeasurement { image: TdxImageMeasurement { kernel_cmdline_sha384: vec![0x10; 48], kernel_authenticode: vec![0x20; 48], @@ -1575,7 +1526,15 @@ mod tests { }, td_hob_witness: vec![0x60; 16], }, - }) + }; + let measurement = measurement.to_cbor_vec(); + let sha256sum = format!( + "{} {}\n", + hex::encode(Sha256::digest(&measurement)), + dstack_types::TDX_MEASUREMENT_FILENAME + ) + .into_bytes(); + TdxOsImageMeasurementDocument::new(sha256sum, measurement) } fn test_tdx_image(supports_lite: bool) -> Image { @@ -1602,9 +1561,8 @@ mod tests { bios: None, bios_sev: None, digest: Some(hex_of(0xaa, 32)), - tdx_digest: tdx_measurement.as_ref().map(|d| d.os_image_hash.clone()), tdx_measurement, - sev_digest: None, + sev_measurement: None, } } @@ -1629,16 +1587,6 @@ mod tests { assert_eq!(effective_vcpu_count(3, None), 3); } - #[test] - fn amd_sev_snp_measurement_base_cmdline_trims_image_cmdline() { - assert_eq!( - amd_sev_snp_measurement_base_cmdline(Some(" console=ttyS0 loglevel=7 ")).unwrap(), - "console=ttyS0 loglevel=7" - ); - assert!(amd_sev_snp_measurement_base_cmdline(None).is_err()); - assert!(amd_sev_snp_measurement_base_cmdline(Some(" ")).is_err()); - } - #[test] fn tdx_auto_variant_uses_legacy_for_low_non_2g_memory() -> Result<()> { let config = test_tdx_config()?; @@ -1662,10 +1610,6 @@ mod tests { let config = test_tdx_config()?; let manifest = test_manifest(2048); let image = test_tdx_image(true); - let expected_tdx_digest = image - .tdx_digest - .clone() - .context("test image must carry TDX digest")?; let vm_config = make_vm_config(&config, &manifest, &image, &hex_of(0x22, 32), None)?; assert_eq!(vm_config["tdx_attestation_variant"], "lite"); @@ -1674,7 +1618,7 @@ mod tests { vm_config["os_image_hash"] .as_str() .context("os_image_hash must be a string")?, - expected_tdx_digest + hex_of(0xaa, 32) ); Ok(()) } @@ -1756,19 +1700,30 @@ mod tests { ) .to_canonical_json(); - // measurement.json is produced at build time by the `dstack-mr - // os-image-measurement` command; the VMM reads it instead of recomputing. - // Emit it here so the deploy path (make_vm_config) can read it back. - let snp_document = - dstack_mr::sev::sev_os_image_measurement_document_for_image_dir(&image_dir)?; - let build_hash = - hex::decode(&snp_document.os_image_hash).context("snp os_image_hash must be hex")?; - let measurement_document = - dstack_types::OsImageMeasurementDocument::new(None, Some(snp_document)); + // The image build emits split SNP measurement CBOR, includes it in + // sha256sum.txt, and keeps digest.txt as sha256(sha256sum.txt). + let snp_cbor = dstack_mr::sev::sev_os_image_measurement_cbor_for_image_dir(&image_dir)?; fs::write( - image_dir.join("measurement.json"), - serde_json::to_string(&measurement_document)?, + image_dir.join(dstack_types::SNP_MEASUREMENT_FILENAME), + &snp_cbor, )?; + let mut sha256sum = String::new(); + for name in [ + "ovmf.fd", + "kernel", + "initrd", + "metadata.json", + dstack_types::SNP_MEASUREMENT_FILENAME, + ] { + sha256sum.push_str(&format!( + "{} {}\n", + hex::encode(Sha256::digest(fs::read(image_dir.join(name))?)), + name + )); + } + fs::write(image_dir.join("sha256sum.txt"), &sha256sum)?; + let build_hash = Sha256::digest(sha256sum.as_bytes()).to_vec(); + fs::write(image_dir.join("digest.txt"), hex::encode(&build_hash))?; let sys_config_document = make_sys_config(&config, &manifest, &compose_hash, Some(mr_config))?; @@ -1781,7 +1736,11 @@ mod tests { let measurement_document = vm_config["sev_snp_measurement"] .as_str() .context("sev_snp_measurement must be a string")?; - let measurement: serde_json::Value = serde_json::from_str(measurement_document)?; + let measurement: dstack_mr::sev::SnpMeasurementDocument = + serde_json::from_str(measurement_document)?; + let image_measurement = + dstack_types::SevOsImageMeasurement::from_cbor_slice(&measurement.measurement) + .map_err(anyhow::Error::msg)?; let mr_config_document = sys_config["mr_config"] .as_str() .context("mr_config must be a string")?; @@ -1790,86 +1749,42 @@ mod tests { assert_eq!(parsed_mr_config.app_id, vec![0x11; 20]); assert_eq!(parsed_mr_config.compose_hash, vec![0x22; 32]); assert_eq!(vm_config["mr_config"], sys_config["mr_config"]); - // The deploy path must surface the os_image_hash straight from - // measurement.json (not recompute it). assert_eq!( vm_config["os_image_hash"] .as_str() .context("os_image_hash must be a string")?, hex::encode(&build_hash), - "vm_config os_image_hash must come from measurement.json" + "vm_config os_image_hash must come from digest.txt" ); - assert!(measurement.get("app_id").is_none()); - assert!(measurement.get("compose_hash").is_none()); - assert!(measurement.get("rootfs_hash").is_none()); assert_eq!( - measurement["base_cmdline"], + image_measurement.base_cmdline, format!("console=ttyS0 dstack.rootfs_hash={}", hex_of(0x33, 32)) ); assert_eq!( - measurement["kernel_hash"], - hex::encode(Sha256::digest(b"snp-test-kernel")) + image_measurement.kernel_hash, + Sha256::digest(b"snp-test-kernel").to_vec() ); assert_eq!( - measurement["initrd_hash"], - hex::encode(Sha256::digest(b"snp-test-initrd")) + image_measurement.initrd_hash, + Sha256::digest(b"snp-test-initrd").to_vec() ); - assert_eq!(measurement["vcpus"], 2); - assert_eq!(measurement["vcpu_type"], "EPYC-v4"); - assert_eq!(measurement["guest_features"], 1); + assert_eq!(measurement.vcpus, 2); + assert_eq!(measurement.vcpu_type.as_deref(), Some("EPYC-v4")); + assert_eq!(measurement.guest_features, 1); assert_eq!( - measurement["ovmf_hash"] - .as_str() - .context("ovmf_hash must be a string")? - .len(), - 96 - ); - assert_eq!(measurement["sev_hashes_table_gpa"], 0x4000); - assert_eq!(measurement["sev_es_reset_eip"], 0xffff_fff0u32); - assert_eq!( - measurement["ovmf_sections"] - .as_array() - .context("ovmf_sections must be an array")? - .len(), - 4 - ); - - // The build-time os_image_hash (measurement.json.snp.os_image_hash) must - // equal the os_image_hash a verifier derives from - // the launch measurement document, i.e. the image-invariant projection. - let as_bytes = |v: &serde_json::Value| hex::decode(v.as_str().unwrap()).unwrap(); - dstack_mr::sev::rootfs_hash_from_cmdline(measurement["base_cmdline"].as_str())?; - let projected = dstack_types::SevOsImageMeasurement { - kernel_cmdline_sha256: { - let mut cmdline = measurement["base_cmdline"] - .as_str() - .unwrap() - .as_bytes() - .to_vec(); - cmdline.push(0); - Sha256::digest(&cmdline).to_vec() - }, - ovmf_hash: as_bytes(&measurement["ovmf_hash"]), - kernel_hash: as_bytes(&measurement["kernel_hash"]), - initrd_hash: as_bytes(&measurement["initrd_hash"]), - sev_hashes_table_gpa: measurement["sev_hashes_table_gpa"].as_u64().unwrap(), - sev_es_reset_eip: measurement["sev_es_reset_eip"].as_u64().unwrap() as u32, - ovmf_sections: measurement["ovmf_sections"] - .as_array() - .unwrap() - .iter() - .map(|s| dstack_types::OvmfSection { - gpa: s["gpa"].as_u64().unwrap(), - size: s["size"].as_u64().unwrap(), - section_type: s["section_type"].as_u64().unwrap() as u32, - }) - .collect(), - }; - assert_eq!( - build_hash, - projected.os_image_hash().to_vec(), - "measurement.json SNP hash must match the os_image_hash derived from the launch measurement" + image_measurement.ovmf_hash.len(), + 48, + "ovmf_hash must be 48 bytes" ); + assert_eq!(image_measurement.sev_hashes_table_gpa, 0x4000); + assert_eq!(image_measurement.sev_es_reset_eip, 0xffff_fff0u32); + assert_eq!(image_measurement.ovmf_sections.len(), 4); + dstack_types::SevOsImageMeasurementDocument::new( + measurement.sha256sum, + measurement.measurement, + ) + .verify(&build_hash) + .map_err(anyhow::Error::msg)?; Ok(()) } } diff --git a/vmm/src/app/image.rs b/vmm/src/app/image.rs index f7bdb2e7f..40f7df4fd 100644 --- a/vmm/src/app/image.rs +++ b/vmm/src/app/image.rs @@ -7,7 +7,10 @@ use path_absolutize::Absolutize; use std::path::{Path, PathBuf}; use anyhow::{bail, Context, Result}; -use dstack_types::{OsImageMeasurementDocument, TdxOsImageMeasurementDocument}; +use dstack_types::{ + SevOsImageMeasurementDocument, TdxOsImageMeasurementDocument, SNP_MEASUREMENT_FILENAME, + TDX_MEASUREMENT_FILENAME, +}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] @@ -72,13 +75,10 @@ pub struct Image { pub bios: Option, pub bios_sev: Option, pub digest: Option, - /// TDX os_image_hash, read from `measurement.json.tdx.os_image_hash`. - pub tdx_digest: Option, - /// TDX no-image-download measurement material, read from `measurement.json.tdx`. + /// TDX no-image-download measurement material. pub tdx_measurement: Option, - /// AMD SEV-SNP os_image_hash, read from `measurement.json.snp.os_image_hash` - /// for new images, falling back to legacy `digest.sev.txt`. - pub sev_digest: Option, + /// AMD SEV-SNP no-image-download measurement material. + pub sev_measurement: Option, } impl Image { @@ -107,31 +107,47 @@ impl Image { let digest = fs::read_to_string(base_path.join("digest.txt")) .ok() .map(|s| s.trim().to_string()); - let measurement_path = base_path.join("measurement.json"); - let measurement = if measurement_path.exists() { - let file = fs::File::open(&measurement_path) - .with_context(|| format!("failed to open {}", measurement_path.display()))?; + let sha256sum_path = base_path.join("sha256sum.txt"); + let sha256sum = if sha256sum_path.exists() { Some( - serde_json::from_reader::<_, OsImageMeasurementDocument>(file) - .with_context(|| format!("failed to parse {}", measurement_path.display()))?, + fs::read(&sha256sum_path) + .with_context(|| format!("failed to read {}", sha256sum_path.display()))?, ) } else { None }; - let legacy_sev_digest = fs::read_to_string(base_path.join("digest.sev.txt")) - .ok() - .map(|s| s.trim().to_string()) - .filter(|s| !s.is_empty()); - let sev_digest = measurement - .as_ref() - .and_then(|m| m.snp.as_ref()) - .map(|snp| snp.os_image_hash.clone()) - .or(legacy_sev_digest); - let tdx_digest = measurement - .as_ref() - .and_then(|m| m.tdx.as_ref()) - .map(|tdx| tdx.os_image_hash.clone()); - let tdx_measurement = measurement.as_ref().and_then(|m| m.tdx.clone()); + let tdx_path = base_path.join(TDX_MEASUREMENT_FILENAME); + let tdx_cbor = if tdx_path.exists() { + Some( + fs::read(&tdx_path) + .with_context(|| format!("failed to read {}", tdx_path.display()))?, + ) + } else { + None + }; + let tdx_measurement = match (&sha256sum, tdx_cbor) { + (Some(sha256sum), Some(measurement)) => Some(TdxOsImageMeasurementDocument::new( + sha256sum.clone(), + measurement, + )), + _ => None, + }; + let snp_path = base_path.join(SNP_MEASUREMENT_FILENAME); + let snp_cbor = if snp_path.exists() { + Some( + fs::read(&snp_path) + .with_context(|| format!("failed to read {}", snp_path.display()))?, + ) + } else { + None + }; + let sev_measurement = match (&sha256sum, snp_cbor) { + (Some(sha256sum), Some(measurement)) => Some(SevOsImageMeasurementDocument::new( + sha256sum.clone(), + measurement, + )), + _ => None, + }; if info.version.is_empty() { // Older images does not have version field. Fallback to the version of the image folder name info.version = guess_version(&base_path).unwrap_or_default(); @@ -145,9 +161,8 @@ impl Image { bios, bios_sev, digest, - tdx_digest, tdx_measurement, - sev_digest, + sev_measurement, } .ensure_exists() } diff --git a/vmm/src/config.rs b/vmm/src/config.rs index aa63fd014..330a2e440 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -298,7 +298,7 @@ pub struct CvmConfig { /// TDX attestation/hash scheme policy. `legacy` keeps the existing /// digest.txt + dstack-acpi-tables verifier path; `lite` opts into the - /// measurement.json + no-QEMU verifier path; `auto` selects `legacy` for + /// split measurement CBOR + no-QEMU verifier path; `auto` selects `legacy` for /// CVMs below 3 GiB except exactly 2 GiB, otherwise uses `lite` when the /// image carries TDX measurement material and falls back to `legacy`. #[serde(default)] diff --git a/vmm/vmm.toml b/vmm/vmm.toml index 48b61904d..42ac81079 100644 --- a/vmm/vmm.toml +++ b/vmm/vmm.toml @@ -47,7 +47,7 @@ qemu_pci_hole64_size = 0 qemu_hotplug_off = false # TDX attestation/hash scheme policy: # - "legacy": digest.txt + legacy verifier -# - "lite": measurement.json.tdx.os_image_hash + no-QEMU verifier +# - "lite": digest.txt + measurement.tdx.cbor + no-QEMU verifier # - "auto": legacy for CVM memory below 3 GiB except exactly 2 GiB; otherwise # lite when the image supports it, legacy when it does not. tdx_attestation_variant = "auto" From 2a30f8edd9d3a59a7d6bde84ac4f55c1b57265eb Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 29 Jun 2026 20:25:24 -0700 Subject: [PATCH 18/18] feat: base64 measurement material in vm config --- dstack-attest/tests/sev_snp_verify.rs | 10 ++-- dstack-mr/src/sev.rs | 49 +++++++++++++----- dstack-types/src/lib.rs | 56 ++++++++++----------- kms/src/main_service.rs | 4 +- kms/src/main_service/amd_attest.rs | 12 ++--- kms/src/onboard_service.rs | 4 +- verifier/fixtures/tdx-lite-attestation.json | 2 +- verifier/fixtures/tdx-lite-getquote.json | 2 +- verifier/fixtures/tdx-lite.README.md | 2 + vmm/src/app.rs | 4 +- 10 files changed, 86 insertions(+), 59 deletions(-) diff --git a/dstack-attest/tests/sev_snp_verify.rs b/dstack-attest/tests/sev_snp_verify.rs index c008e92e2..8fa4c3317 100644 --- a/dstack-attest/tests/sev_snp_verify.rs +++ b/dstack-attest/tests/sev_snp_verify.rs @@ -139,7 +139,7 @@ fn upgrade_snp_config_for_split_measurement(config: &str) -> String { let measurement_value: serde_json::Value = serde_json::from_str(&measurement_doc).expect("measurement json"); if measurement_value.get("measurement").is_some() - && measurement_value.get("sha256sum").is_some() + && measurement_value.get("checksum_file").is_some() { return config.to_string(); } @@ -156,14 +156,14 @@ fn upgrade_snp_config_for_split_measurement(config: &str) -> String { ) .into_bytes(); let document = dstack_mr::sev::SnpMeasurementDocument { - sha256sum, + checksum_file: sha256sum, measurement, vcpus: input.vcpus, vcpu_type: input.vcpu_type, guest_features: input.guest_features, }; value["os_image_hash"] = serde_json::Value::String(hex::encode( - dstack_types::image_hash_from_sha256sum(&document.sha256sum), + dstack_types::image_hash_from_sha256sum(&document.checksum_file), )); value["sev_snp_measurement"] = serde_json::Value::String(serde_json::to_string(&document).expect("serialize document")); @@ -200,14 +200,14 @@ fn with_image_measurement( .expect("decode measurement.snp.cbor"); f(&mut image); document.measurement = image.to_cbor_vec(); - document.sha256sum = format!( + document.checksum_file = format!( "{} {}\n", hex::encode(Sha256::digest(&document.measurement)), dstack_types::SNP_MEASUREMENT_FILENAME ) .into_bytes(); value["os_image_hash"] = serde_json::Value::String(hex::encode( - dstack_types::image_hash_from_sha256sum(&document.sha256sum), + dstack_types::image_hash_from_sha256sum(&document.checksum_file), )); value["sev_snp_measurement"] = serde_json::Value::String(serde_json::to_string(&document).expect("reserialize")); diff --git a/dstack-mr/src/sev.rs b/dstack-mr/src/sev.rs index 29f3c90da..157d083bf 100644 --- a/dstack-mr/src/sev.rs +++ b/dstack-mr/src/sev.rs @@ -950,12 +950,12 @@ struct SevSnpMeasurementVmConfig { mr_config: Option, } -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)] #[serde(deny_unknown_fields)] pub struct SnpMeasurementDocument { - #[serde(with = "serde_human_bytes")] - pub sha256sum: Vec, - #[serde(with = "serde_human_bytes")] + #[serde(with = "serde_human_bytes::base64")] + pub checksum_file: Vec, + #[serde(with = "serde_human_bytes::base64")] pub measurement: Vec, pub vcpus: u32, pub vcpu_type: Option, @@ -1002,7 +1002,7 @@ pub struct SnpLaunchInputs { } /// Parse the SNP launch-measurement inputs (`sev_snp_measurement`) and the -/// `mr_config` document out of a VMM `vm_config` JSON string. +/// `mr_config` document out of a VMM `vm_config` string. /// /// The fields are intentionally explicit so missing SNP launch inputs fail /// closed instead of falling back to TDX event-log decoding. Both the top-level @@ -1040,7 +1040,7 @@ pub fn parse_snp_inputs_from_vm_config(vm_config: &str) -> Result Vec { - dstack_types::image_hash_from_sha256sum(&snp_document(input).sha256sum).to_vec() + dstack_types::image_hash_from_sha256sum(&snp_document(input).checksum_file).to_vec() } #[test] @@ -1433,10 +1455,13 @@ mod tests { ); let document = snp_document(&input); - let image_hash = dstack_types::image_hash_from_sha256sum(&document.sha256sum); - dstack_types::SevOsImageMeasurementDocument::new(document.sha256sum, document.measurement) - .verify(&image_hash) - .expect("fixture measurement material verifies against sha256sum.txt"); + let image_hash = dstack_types::image_hash_from_sha256sum(&document.checksum_file); + dstack_types::SevOsImageMeasurementDocument::new( + document.checksum_file, + document.measurement, + ) + .verify(&image_hash) + .expect("fixture measurement material verifies against sha256sum.txt"); } // ---- Forged-quote / tampered-input coverage for `verify_sev_launch` ---- diff --git a/dstack-types/src/lib.rs b/dstack-types/src/lib.rs index e9803dd46..92007937d 100644 --- a/dstack-types/src/lib.rs +++ b/dstack-types/src/lib.rs @@ -331,12 +331,12 @@ fn sha256(bytes: &[u8]) -> [u8; 32] { pub const TDX_MEASUREMENT_FILENAME: &str = "measurement.tdx.cbor"; pub const SNP_MEASUREMENT_FILENAME: &str = "measurement.snp.cbor"; -pub fn image_hash_from_sha256sum(sha256sum: &[u8]) -> [u8; 32] { - sha256(sha256sum) +pub fn image_hash_from_sha256sum(checksum_file: &[u8]) -> [u8; 32] { + sha256(checksum_file) } -pub fn sha256sum_entry_hash(sha256sum: &[u8], filename: &str) -> Result<[u8; 32], String> { - let text = std::str::from_utf8(sha256sum) +pub fn sha256sum_entry_hash(checksum_file: &[u8], filename: &str) -> Result<[u8; 32], String> { + let text = std::str::from_utf8(checksum_file) .map_err(|e| format!("sha256sum.txt is not valid UTF-8: {e}"))?; let mut found = None; for (line_no, line) in text.lines().enumerate() { @@ -377,18 +377,18 @@ pub fn sha256sum_entry_hash(sha256sum: &[u8], filename: &str) -> Result<[u8; 32] pub fn verify_measurement_material( os_image_hash: &[u8], - sha256sum: &[u8], + checksum_file: &[u8], measurement: &[u8], filename: &str, ) -> Result<(), String> { - if image_hash_from_sha256sum(sha256sum).as_slice() != os_image_hash { + if image_hash_from_sha256sum(checksum_file).as_slice() != os_image_hash { return Err(format!( "os_image_hash mismatch: expected sha256(sha256sum.txt)={}, actual={}", hex::encode(os_image_hash), - hex::encode(image_hash_from_sha256sum(sha256sum)) + hex::encode(image_hash_from_sha256sum(checksum_file)) )); } - let expected_measurement_hash = sha256sum_entry_hash(sha256sum, filename)?; + let expected_measurement_hash = sha256sum_entry_hash(checksum_file, filename)?; let actual_measurement_hash = sha256(measurement); if expected_measurement_hash != actual_measurement_hash { return Err(format!( @@ -542,25 +542,25 @@ impl SevOsImageMeasurement { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SevOsImageMeasurementDocument { - /// Raw `sha256sum.txt` bytes. `sha256(sha256sum)` is the unified - /// `os_image_hash`. - #[serde(with = "hex_bytes")] - pub sha256sum: Vec, + /// Raw checksum file bytes (`sha256sum.txt`). `sha256(checksum_file)` is + /// the unified `os_image_hash`. + #[serde(with = "serde_human_bytes::base64")] + pub checksum_file: Vec, /// Raw bytes of `measurement.snp.cbor`. - #[serde(alias = "m", with = "hex_bytes")] + #[serde(with = "serde_human_bytes::base64")] pub measurement: Vec, } impl SevOsImageMeasurementDocument { - pub fn new(sha256sum: Vec, measurement: Vec) -> Self { + pub fn new(checksum_file: Vec, measurement: Vec) -> Self { Self { - sha256sum, + checksum_file, measurement, } } - pub fn from_measurement(sha256sum: Vec, measurement: SevOsImageMeasurement) -> Self { - Self::new(sha256sum, measurement.to_cbor_vec()) + pub fn from_measurement(checksum_file: Vec, measurement: SevOsImageMeasurement) -> Self { + Self::new(checksum_file, measurement.to_cbor_vec()) } pub fn decode_measurement(&self) -> Result { @@ -574,7 +574,7 @@ impl SevOsImageMeasurementDocument { pub fn verify(&self, os_image_hash: &[u8]) -> Result<(), String> { verify_measurement_material( os_image_hash, - &self.sha256sum, + &self.checksum_file, &self.measurement, SNP_MEASUREMENT_FILENAME, ) @@ -712,12 +712,12 @@ impl From for TdxOsImageMeasurement { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct TdxOsImageMeasurementDocument { - /// Raw `sha256sum.txt` bytes. `sha256(sha256sum)` is the unified - /// `os_image_hash`. - #[serde(with = "hex_bytes")] - pub sha256sum: Vec, + /// Raw checksum file bytes (`sha256sum.txt`). `sha256(checksum_file)` is + /// the unified `os_image_hash`. + #[serde(with = "serde_human_bytes::base64")] + pub checksum_file: Vec, /// Raw bytes of `measurement.tdx.cbor`. - #[serde(alias = "m", with = "hex_bytes")] + #[serde(with = "serde_human_bytes::base64")] pub measurement: Vec, } @@ -757,15 +757,15 @@ impl TdxOsImageMeasurement { } impl TdxOsImageMeasurementDocument { - pub fn new(sha256sum: Vec, measurement: Vec) -> Self { + pub fn new(checksum_file: Vec, measurement: Vec) -> Self { Self { - sha256sum, + checksum_file, measurement, } } - pub fn from_measurement(sha256sum: Vec, measurement: TdxOsImageMeasurement) -> Self { - Self::new(sha256sum, measurement.to_cbor_vec()) + pub fn from_measurement(checksum_file: Vec, measurement: TdxOsImageMeasurement) -> Self { + Self::new(checksum_file, measurement.to_cbor_vec()) } pub fn decode_measurement(&self) -> Result { @@ -779,7 +779,7 @@ impl TdxOsImageMeasurementDocument { pub fn verify(&self, os_image_hash: &[u8]) -> Result<(), String> { verify_measurement_material( os_image_hash, - &self.sha256sum, + &self.checksum_file, &self.measurement, TDX_MEASUREMENT_FILENAME, ) diff --git a/kms/src/main_service.rs b/kms/src/main_service.rs index 9bbfefc80..8ee247d89 100644 --- a/kms/src/main_service.rs +++ b/kms/src/main_service.rs @@ -658,7 +658,7 @@ mod tests { ) .into_bytes(); dstack_mr::sev::SnpMeasurementDocument { - sha256sum, + checksum_file: sha256sum, measurement, vcpus: input.vcpus, vcpu_type: input.vcpu_type.clone(), @@ -672,7 +672,7 @@ mod tests { ) -> String { let document = snp_measurement_document(input); serde_json::json!({ - "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.sha256sum)), + "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.checksum_file)), "sev_snp_measurement": serde_json::to_string(&document).unwrap(), "mr_config": mr_config.to_canonical_json(), }) diff --git a/kms/src/main_service/amd_attest.rs b/kms/src/main_service/amd_attest.rs index 65d97c213..bcbbdbf4d 100644 --- a/kms/src/main_service/amd_attest.rs +++ b/kms/src/main_service/amd_attest.rs @@ -212,7 +212,7 @@ fn test_snp_measurement_document( ) .into_bytes(); Ok(dstack_mr::sev::SnpMeasurementDocument { - sha256sum, + checksum_file: sha256sum, measurement, vcpus: input.vcpus, vcpu_type: input.vcpu_type.clone(), @@ -222,10 +222,10 @@ fn test_snp_measurement_document( #[cfg(test)] fn test_os_image_hash(input: &MeasurementInput) -> Result> { - Ok( - dstack_types::image_hash_from_sha256sum(&test_snp_measurement_document(input)?.sha256sum) - .to_vec(), + Ok(dstack_types::image_hash_from_sha256sum( + &test_snp_measurement_document(input)?.checksum_file, ) + .to_vec()) } #[cfg(test)] @@ -551,14 +551,14 @@ mod tests { ) .into_bytes(); let document = dstack_mr::sev::SnpMeasurementDocument { - sha256sum, + checksum_file: sha256sum, measurement: measurement_cbor, vcpus: input.vcpus, vcpu_type: input.vcpu_type.clone(), guest_features: input.guest_features, }; let vm_config = serde_json::json!({ - "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.sha256sum)), + "os_image_hash": hex::encode(dstack_types::image_hash_from_sha256sum(&document.checksum_file)), "sev_snp_measurement": serde_json::to_string(&document).unwrap(), "mr_config": mr_config.to_canonical_json(), }) diff --git a/kms/src/onboard_service.rs b/kms/src/onboard_service.rs index deb105f39..691926155 100644 --- a/kms/src/onboard_service.rs +++ b/kms/src/onboard_service.rs @@ -287,7 +287,7 @@ mod tests { ) .into_bytes(); dstack_mr::sev::SnpMeasurementDocument { - sha256sum, + checksum_file: sha256sum, measurement, vcpus: input.vcpus, vcpu_type: input.vcpu_type.clone(), @@ -302,7 +302,7 @@ mod tests { let mr_config = valid_snp_mr_config(); let attestation = verified_snp_attestation(measurement, [0xab; 64]); let snp_document = snp_measurement_document(&input); - let os_image_hash = dstack_types::image_hash_from_sha256sum(&snp_document.sha256sum); + let os_image_hash = dstack_types::image_hash_from_sha256sum(&snp_document.checksum_file); let vm_config = serde_json::json!({ "os_image_hash": hex::encode(os_image_hash), "sev_snp_measurement": serde_json::to_string(&snp_document).unwrap(), diff --git a/verifier/fixtures/tdx-lite-attestation.json b/verifier/fixtures/tdx-lite-attestation.json index cbf01f193..a2335fe48 100644 --- a/verifier/fixtures/tdx-lite-attestation.json +++ b/verifier/fixtures/tdx-lite-attestation.json @@ -1,4 +1,4 @@ { "attestation": "0000394e040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000a000000c0095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a3372c616370692d6c6f6164657224414350492044415441000000000a000000c08d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef24616370692d7273647024414350492044415441000000000a000000c03070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b62c616370692d7461626c6573244143504920444154410300000001000008004073797374656d2d707265706172696e6700030000000100000800186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e03000000010000080030636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa90300000001000008002c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead03000000010000080030626f6f742d6d722d646f6e6500030000000100000800346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d030000000100000800306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d0300000001000008002873746f726167652d66730c7a66730300000001000008003073797374656d2d726561647900244073797374656d2d707265706172696e6700186170702d69645086b0e55f2fa8e4fb69d890f14f54d5612707646e30636f6d706f73652d686173688086b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa92c696e7374616e63652d696450050bf89570575fe8fab4cb8f0a62a9e64efe8ead30626f6f742d6d722d646f6e6500346f732d696d6167652d686173688007a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d306b65792d70726f766964657231037b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d2873746f726167652d66730c7a66733073797374656d2d726561647900646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b5165137b226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226370755f636f756e74223a322c226d656d6f72795f73697a65223a323134373438333634382c2271656d755f76657273696f6e223a22382e322e32222c227063695f686f6c6536345f73697a65223a302c22687567657061676573223a66616c73652c226e756d5f67707573223a302c226e756d5f6e767377697463686573223a302c22686f74706c75675f6f6666223a66616c73652c22696d616765223a2264737461636b2d302e362e30222c22686f73745f73686172655f6d6f6465223a223970222c226f766d665f76617269616e74223a22707265323032353035222c227464785f6174746573746174696f6e5f76617269616e74223a226c697465222c227464785f6d6561737572656d656e74223a7b2276657273696f6e223a322c226f735f696d6167655f68617368223a2230376132333838633761366131623661363436643434336631353137393930613465633239343437316436333134366364613964353639373237363530353164222c226d6561737572656d656e74223a22613236353639366436313637363561333665363336643634366336393665363535663733363836313333333833343538333037383632383038343262373336343238376133613730643936663765333039323532383537626562343566623166393133313461326561383633646230616463303463383433316563626632396139363634303536303436333161356161623837333662363537323665363536633566363137353734363836353665373436393633366636343635353833306163376536333264636635636432613166653563316634316634643962383231393537306536346564336336313033386664626632353430346536663534326666643537663237366263353037363330376566616638383265366436343137373664363936653639373437323634356637333638363133333338333435383330346665346637373130313334613631643764656633353761646436616335306264626665656535303332613463313030333735653230373231366666653432613362643538323262323465363739663931353031666666373935623831353231363437343634373636366133363436663736366436363639373037323635333233303332333533303335363436643732373436346132366237333639366536373663363535663730363137333733353833306136663261633934353138313036383661346462323539666538666135343338646334613538626461396664326635623166623039323833333537303535303064323961313563393233383734313661326635326464646365393963383366383638373437373666356637303631373337333538333066643638353532326365373931646665663637343134363134656230376430336663303761333263356136366633363238386233323964616239326237323462313536346337336434333666666239656138343438386335316163356131633536363734363435663638366636323463383031303039303430303036303930323062303231303130227d2c22737065635f76657273696f6e223a317d", - "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"sha256sum\":\"3863396539353566306235373763633839343561383931613334636366613562386530386262356535643234393939323630336536346464313438373065336320206d6561737572656d656e742e7464782e63626f720a\",\"measurement\":\"a36776657273696f6e0365696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"measurement\":\"o2d2ZXJzaW9uA2VpbWFnZaNuY21kbGluZV9zaGEzODRYMHhigIQrc2Qoejpw2W9+MJJShXvrRfsfkTFKLqhj2wrcBMhDHsvympZkBWBGMaWquHNrZXJuZWxfYXV0aGVudGljb2RlWDCsfmMtz1zSof5cH0H02bghlXDmTtPGEDj9vyVATm9UL/1X8na8UHYwfvr4gubWQXdtaW5pdHJkX3NoYTM4NFgwT+T3cQE0ph197zV63WrFC9v+7lAypMEAN14gchb/5Co71YIrJOZ5+RUB//eVuBUhZHRkdmajZG92bWZpcHJlMjAyNTA1ZG1ydGSia3NpbmdsZV9wYXNzWDCm8qyUUYEGhqTbJZ/o+lQ43EpYvan9L1sfsJKDNXBVANKaFckjh0FqL1Ld3Omcg/hodHdvX3Bhc3NYMP1oVSLOeR3+9nQUYU6wfQP8B6MsWmbzYoizKdq5K3JLFWTHPUNv+56oRIjFGsWhxWZ0ZF9ob2JMgBAJBAAGCQILAhAQ\",\"checksum_file\":\"OGM5ZTk1NWYwYjU3N2NjODk0NWE4OTFhMzRjY2ZhNWI4ZTA4YmI1ZTVkMjQ5OTkyNjAzZTY0ZGQxNDg3MGUzYyAgbWVhc3VyZW1lbnQudGR4LmNib3IK\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite-getquote.json b/verifier/fixtures/tdx-lite-getquote.json index 43e7b544a..57a30c837 100644 --- a/verifier/fixtures/tdx-lite-getquote.json +++ b/verifier/fixtures/tdx-lite-getquote.json @@ -2,5 +2,5 @@ "quote": "040002008100000000000000939a7233f79c4ca9940a0db3957f06071026ff2bbebac59cc1ef911279d9481b000000000c010400000000000000000000000000d0d80c085166ba78ccc69af268e5753cf0f3394523cb4ff7c50b08d9265c82489c099c377be6a400e4d2b57da924012c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000e702060000000000fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c50186b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8438db36b96f85d8752ff7f24a89ec05c79ec9eda2ba732c897fb970ca429365b7471b1c054cb84f17b1c2b23ba66402023546e7f3b9d1228e274f70c44d481162540f8452544520a796a52f06879709b81a824a26792a7822327504b0d2aee4c1b739ed451a637b0f82642e48a5ea83925d23633c72e7385c8e9aca4175e133ed1625b7d92eb39edf509c27ff392dc6f24c170d0fd63fc2b1b53202eea47b013978437fa6982cf5e0438ff95c208994aaa0f4ebab2e3a66824b5b56869137e646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51cc1000008bca152d0454bdfd5adab1bc3a527884f77ea7993d32ee0e4426b2ae0fe42bf3f5642d6abd763b4f4c6042133e2ed79cce743f2c54ff4c7ea5d712dc1172ec244fe5b32ac6ffeb104614bcb8894c7aaafbbbe6f6bfd852f5dcd6cf400557ee764e62850d955975d93eff63b17e6e13e329a7bb13926706c0430017d543ab01920600461000000404191b04ff0006000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000e5a3a7b5d830c2953b98534c6c59a3a34fdc34e933f7f5898f0a85cf08846bca0000000000000000000000000000000000000000000000000000000000000000dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1140324365c08f021a721dbe9175cb89dcd2235e2bd00bfb235b2a66b8c783600000000000000000000000000000000000000000000000000000000000000002af8cd12d44e0d22f904b15c02968b57b668e7f2487ba308e1d9a269ea125e48b243f7d32bb8551e1e3c2c09bd2162d36941eeb47be50b9b55a766a14d0cfe302000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f05005e0e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d49494538444343424a6167417749424167495556706163774c766c316d476155506b384b4375504141334769465177436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a59774e4445314d4441314d4455345768634e4d7a4d774e4445314d4441314d4455340a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d343941774548413049414245586a0a53374265726c3262726b65543677707878436a556536564775577268586e51767a41395862524768356b68637671766b566b427874715935475759544f6551340a5948496a636b7974734c6c5531774b594a74576a67674d4d4d4949444344416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c3359304c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f42425945464362386b6b73714d364c384f6765734c713943337339440a7a5333504d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f51594a4b6f5a496876684e415130420a424949434b6a4343416959774867594b4b6f5a496876684e4151304241515151514e367178312b487a7758704c373859496b716c646a434341574d47436971470a534962345451454e41514977676746544d42414743797147534962345451454e41514942416745454d42414743797147534962345451454e41514943416745450a4d42414743797147534962345451454e41514944416745434d42414743797147534962345451454e41514945416745434d42414743797147534962345451454e0a41514946416745454d42414743797147534962345451454e41514947416745424d42414743797147534962345451454e41514948416745414d424147437971470a534962345451454e41514949416745464d42414743797147534962345451454e4151494a416745414d42414743797147534962345451454e4151494b416745410a4d42414743797147534962345451454e4151494c416745414d42414743797147534962345451454e4151494d416745414d42414743797147534962345451454e0a4151494e416745414d42414743797147534962345451454e4151494f416745414d42414743797147534962345451454e41514950416745414d424147437971470a534962345451454e41514951416745414d42414743797147534962345451454e415149524167454e4d42384743797147534962345451454e41514953424241450a42414943424145414251414141414141414141414d42414743697147534962345451454e41514d45416741414d42514743697147534962345451454e415151450a42704441627741414144415042676f71686b69472b45304244514546436745424d42344743697147534962345451454e4151594545464a37386f7137314543670a6c7536335265417a675430775241594b4b6f5a496876684e41513042427a41324d42414743797147534962345451454e415163424151482f4d424147437971470a534962345451454e41516343415145414d42414743797147534962345451454e415163444151482f4d416f4743437147534d343942414d43413067414d4555430a494778676472434e7a344753716d32647a4c45533874757663717230444d692b427537533771537133325343416945417439454f6377584f6a31484a4c4462750a6d473357414549577962624f61635959612b7253384366526c514d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "event_log": "[{\"imr\":0,\"event_type\":2147483659,\"digest\":\"0b8772e5b0b41b83e6044a68397e02f49fb47066b4fbe4917ea2c45c64f323fdacbb37948f821ebaf8bc9c938ba8a749\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483658,\"digest\":\"344bc51c980ba621aaa00da3ed7436f7d6e549197dfe699515dfa2c6583d95e6412af21c097d473155875ffd561d6790\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"9dc3a1f80bcec915391dcda5ffbb15e7419f77eab462bbf72b42166fb70d50325e37b36f93537a863769bcf9bedae6fb\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"6f2e3cbc14f9def86980f5f66fd85e99d63e69a73014ed8a5633ce56eca5b64b692108c56110e22acadcef58c3250f1b\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"d607c0efb41c0d757d69bca0615c3a9ac0b1db06c557d992e906c6b7dee40e0e031640c7bfd7bcd35844ef9edeadc6f9\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"08a74f8963b337acb6c93682f934496373679dd26af1089cb4eaf0c30cf260a12e814856385ab8843e56a9acea19e127\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483649,\"digest\":\"18cc6e01f0c6ea99aa23f8a280423e94ad81d96d0aeb5180504fc0f7a40cb3619dd39bd6a95ec1680a86ed6ab0f9828d\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":10,\"digest\":\"095d04cf26fe03aef6e3561fa24c1aa1cea93f4aeaf563b1f9f7616184c53454875925759434769cec2490acb563a337\",\"event\":\"acpi-loader\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"8d9a4d4777a1bc77ecd9d8d37a4628129a80052a510320159a20a923bd07a0e90d8d1f2e1ebf088992b25f0d0fa672ef\",\"event\":\"acpi-rsdp\",\"event_payload\":\"414350492044415441\"},{\"imr\":0,\"event_type\":10,\"digest\":\"3070721e169bc41884724cb0e6b3082e1baf249083d8b389181ba50b9afa951057876c380b8870e8c2facf2eff67a2b6\",\"event\":\"acpi-tables\",\"event_payload\":\"414350492044415441\"},{\"imr\":1,\"event_type\":2147483651,\"digest\":\"ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d64177\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"1dd6f7b457ad880d840d41c961283bab688e94e4b59359ea45686581e90feccea3c624b1226113f824f315eb60ae0a7c\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":0,\"event_type\":2147483650,\"digest\":\"23ada07f5261f12f34a0bd8e46760962d6b4d576a416f1fea1c64bc656b1d28eacf7047ae6e967c58fd2a98bfa74c298\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"77a0dab2312b4e1e57a84d865a21e5b2ee8d677a21012ada819d0a98988078d3d740f6346bfe0abaa938ca20439a8d71\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":4,\"digest\":\"394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":2,\"event_type\":6,\"digest\":\"4fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b81521\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"214b0bef1379756011344877743fdc2a5382bac6e70362d624ccf3f654407c1b4badf7d8f9295dd3dabdef65b27677e0\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":1,\"event_type\":2147483655,\"digest\":\"0a2e01c85deae718a530ad8c6d20a84009babe6c8989269e950d8cf440c6e997695e64d455c4174a652cd080f6230b74\",\"event\":\"\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-preparing\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"app-id\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"compose-hash\",\"event_payload\":\"86b0e55f2fa8e4fb69d890f14f54d5612707646e2573d54e0d2ddaaade77caa9\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"instance-id\",\"event_payload\":\"050bf89570575fe8fab4cb8f0a62a9e64efe8ead\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"boot-mr-done\",\"event_payload\":\"\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"os-image-hash\",\"event_payload\":\"07a2388c7a6a1b6a646d443f1517990a4ec294471d63146cda9d56972765051d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"key-provider\",\"event_payload\":\"7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343266373165323334643733333961316365616361303963336333393165623831366335333366393830616461616233346631366561643039336666306163313030643963303332353361333035366636643237373335313235343333313830623365363163353461373866336664313333333738363965303035316465653036227d\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"storage-fs\",\"event_payload\":\"7a6673\"},{\"imr\":3,\"event_type\":134217729,\"digest\":\"\",\"event\":\"system-ready\",\"event_payload\":\"\"}]", "report_data": "646970313a3a736563703235366b31632d706b3a41353570576d74654a494a4f6a385f7049372d707a654478793147327131384744763838484e526442586b51", - "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"sha256sum\":\"3863396539353566306235373763633839343561383931613334636366613562386530386262356535643234393939323630336536346464313438373065336320206d6561737572656d656e742e7464782e63626f720a\",\"measurement\":\"a36776657273696f6e0365696d616765a36e636d646c696e655f7368613338345830786280842b7364287a3a70d96f7e309252857beb45fb1f91314a2ea863db0adc04c8431ecbf29a966405604631a5aab8736b65726e656c5f61757468656e7469636f64655830ac7e632dcf5cd2a1fe5c1f41f4d9b8219570e64ed3c61038fdbf25404e6f542ffd57f276bc5076307efaf882e6d641776d696e697472645f73686133383458304fe4f7710134a61d7def357add6ac50bdbfeee5032a4c100375e207216ffe42a3bd5822b24e679f91501fff795b815216474647666a3646f766d6669707265323032353035646d727464a26b73696e676c655f706173735830a6f2ac9451810686a4db259fe8fa5438dc4a58bda9fd2f5b1fb0928335705500d29a15c92387416a2f52dddce99c83f86874776f5f706173735830fd685522ce791dfef67414614eb07d03fc07a32c5a66f36288b329dab92b724b1564c73d436ffb9ea84488c51ac5a1c56674645f686f624c80100904000609020b021010\"},\"spec_version\":1}" + "vm_config": "{\"os_image_hash\":\"e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db\",\"cpu_count\":2,\"memory_size\":2147483648,\"qemu_version\":\"8.2.2\",\"pci_hole64_size\":0,\"hugepages\":false,\"num_gpus\":0,\"num_nvswitches\":0,\"hotplug_off\":false,\"image\":\"dstack-0.6.0\",\"host_share_mode\":\"9p\",\"ovmf_variant\":\"pre202505\",\"tdx_attestation_variant\":\"lite\",\"tdx_measurement\":{\"measurement\":\"o2d2ZXJzaW9uA2VpbWFnZaNuY21kbGluZV9zaGEzODRYMHhigIQrc2Qoejpw2W9+MJJShXvrRfsfkTFKLqhj2wrcBMhDHsvympZkBWBGMaWquHNrZXJuZWxfYXV0aGVudGljb2RlWDCsfmMtz1zSof5cH0H02bghlXDmTtPGEDj9vyVATm9UL/1X8na8UHYwfvr4gubWQXdtaW5pdHJkX3NoYTM4NFgwT+T3cQE0ph197zV63WrFC9v+7lAypMEAN14gchb/5Co71YIrJOZ5+RUB//eVuBUhZHRkdmajZG92bWZpcHJlMjAyNTA1ZG1ydGSia3NpbmdsZV9wYXNzWDCm8qyUUYEGhqTbJZ/o+lQ43EpYvan9L1sfsJKDNXBVANKaFckjh0FqL1Ld3Omcg/hodHdvX3Bhc3NYMP1oVSLOeR3+9nQUYU6wfQP8B6MsWmbzYoizKdq5K3JLFWTHPUNv+56oRIjFGsWhxWZ0ZF9ob2JMgBAJBAAGCQILAhAQ\",\"checksum_file\":\"OGM5ZTk1NWYwYjU3N2NjODk0NWE4OTFhMzRjY2ZhNWI4ZTA4YmI1ZTVkMjQ5OTkyNjAzZTY0ZGQxNDg3MGUzYyAgbWVhc3VyZW1lbnQudGR4LmNib3IK\"},\"spec_version\":1}" } diff --git a/verifier/fixtures/tdx-lite.README.md b/verifier/fixtures/tdx-lite.README.md index 9b05985c5..5e065f09a 100644 --- a/verifier/fixtures/tdx-lite.README.md +++ b/verifier/fixtures/tdx-lite.README.md @@ -33,6 +33,8 @@ Important fixture properties: - `vm_config.tdx_attestation_variant = "lite"` - `vm_config.memory_size = 2147483648` (2 GiB) - `vm_config.os_image_hash = e6f5cfec20c02e7b97baa213d0f718020b55e040172d90ccbcb946d56c8b09db` +- `vm_config.tdx_measurement.{checksum_file,measurement}` are JSON base64 byte + strings. - The top-level `event_log` and stripped attestation keep the three named RTMR0 `ACPI DATA` digests (`acpi-loader`, `acpi-rsdp`, `acpi-tables`) and marker payloads needed by the lite verifier, plus RTMR3 runtime events. diff --git a/vmm/src/app.rs b/vmm/src/app.rs index 777c40c10..e926253f1 100644 --- a/vmm/src/app.rs +++ b/vmm/src/app.rs @@ -1388,7 +1388,7 @@ fn make_vm_config( "amd sev-snp image is missing measurement.snp.cbor/sha256sum.txt measurement material", )?; let measurement = dstack_mr::sev::SnpMeasurementDocument { - sha256sum: image_measurement.sha256sum.clone(), + checksum_file: image_measurement.checksum_file.clone(), measurement: image_measurement.measurement.clone(), vcpus: effective_vcpus, vcpu_type: Some("EPYC-v4".to_string()), @@ -1780,7 +1780,7 @@ mod tests { assert_eq!(image_measurement.sev_es_reset_eip, 0xffff_fff0u32); assert_eq!(image_measurement.ovmf_sections.len(), 4); dstack_types::SevOsImageMeasurementDocument::new( - measurement.sha256sum, + measurement.checksum_file, measurement.measurement, ) .verify(&build_hash)