diff --git a/Cargo.lock b/Cargo.lock index 0706f65..f9a940e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,7 +297,6 @@ dependencies = [ "anyhow", "az-tdx-vtpm", "base64 0.22.1", - "configfs-tsm", "dcap-qvl 0.3.12 (git+https://github.com/Phala-Network/dcap-qvl.git?rev=f1dcc65371e941a7b83e3234833d23a1fb232ab1)", "hex", "http 1.4.0", @@ -314,6 +313,7 @@ dependencies = [ "serde", "serde-saphyr", "serde_json", + "tdx-attest 0.5.8", "tempfile", "thiserror 2.0.18", "time", @@ -733,6 +733,23 @@ dependencies = [ "shlex", ] +[[package]] +name = "cc-eventlog" +version = "0.5.8" +source = "git+https://github.com/Dstack-TEE/dstack.git?rev=4f602dddc0542cd34da031c90ac0b3a560f316ed#4f602dddc0542cd34da031c90ac0b3a560f316ed" +dependencies = [ + "anyhow", + "digest", + "ez-hash", + "fs-err", + "hex", + "parity-scale-codec", + "serde", + "serde-human-bytes", + "serde_json", + "sha2", +] + [[package]] name = "cc-eventlog" version = "0.5.11" @@ -839,12 +856,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12170080f3533d6f09a19f81596f836854d0fa4867dc32c8172b8474b4e9de61" -[[package]] -name = "configfs-tsm" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187437900921c8172f33316ad51a3267df588e99a2aebfa5ca1a2ed44df9e703" - [[package]] name = "console" version = "0.16.3" @@ -1339,7 +1350,7 @@ version = "0.5.11" source = "git+https://github.com/Dstack-TEE/dstack.git?rev=07d2cf6bd376a3c56f855aa47c8de003bb427e48#07d2cf6bd376a3c56f855aa47c8de003bb427e48" dependencies = [ "anyhow", - "cc-eventlog", + "cc-eventlog 0.5.11", "dcap-qvl 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "dstack-types", "errify", @@ -1356,7 +1367,7 @@ dependencies = [ "serde_json", "sha2", "sha3", - "tdx-attest", + "tdx-attest 0.5.11", "tracing", ] @@ -3125,7 +3136,7 @@ source = "git+https://github.com/Dstack-TEE/dstack.git?rev=07d2cf6bd376a3c56f855 dependencies = [ "anyhow", "bon", - "cc-eventlog", + "cc-eventlog 0.5.11", "dcap-qvl 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "dstack-attest", "dstack-types", @@ -3952,13 +3963,32 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "tdx-attest" +version = "0.5.8" +source = "git+https://github.com/Dstack-TEE/dstack.git?rev=4f602dddc0542cd34da031c90ac0b3a560f316ed#4f602dddc0542cd34da031c90ac0b3a560f316ed" +dependencies = [ + "anyhow", + "cc-eventlog 0.5.8", + "fs-err", + "hex", + "libc", + "parity-scale-codec", + "serde", + "serde-human-bytes", + "serde_json", + "sha2", + "thiserror 2.0.18", + "vsock", +] + [[package]] name = "tdx-attest" version = "0.5.11" source = "git+https://github.com/Dstack-TEE/dstack.git?rev=07d2cf6bd376a3c56f855aa47c8de003bb427e48#07d2cf6bd376a3c56f855aa47c8de003bb427e48" dependencies = [ "anyhow", - "cc-eventlog", + "cc-eventlog 0.5.11", "fs-err", "hex", "libc", diff --git a/crates/attestation/Cargo.toml b/crates/attestation/Cargo.toml index a9a35b6..f27bcb5 100644 --- a/crates/attestation/Cargo.toml +++ b/crates/attestation/Cargo.toml @@ -15,14 +15,14 @@ tokio = { workspace = true, features = ["fs"] } tokio-rustls = { workspace = true, default-features = false } anyhow = "1.0.100" +pem-rfc7468 = { version = "0.7.0", features = ["std"] } +tdx-attest = { git = "https://github.com/Dstack-TEE/dstack.git", rev = "4f602dddc0542cd34da031c90ac0b3a560f316ed" } base64 = "0.22.1" -configfs-tsm = "0.0.2" hex = "0.4.3" http = "1.3.1" num-bigint = "0.4.6" once_cell = "1.21.3" parity-scale-codec = "3.7.5" -pem-rfc7468 = { version = "0.7.0", features = ["std"] } rand_core = { version = "0.6.4", features = ["getrandom"] } reqwest = { version = "0.12.23", default-features = false, features = [ "rustls-tls-webpki-roots-no-provider" ] } serde = "1.0.228" diff --git a/crates/attestation/README.md b/crates/attestation/README.md index dd8e095..bc268ae 100644 --- a/crates/attestation/README.md +++ b/crates/attestation/README.md @@ -60,7 +60,9 @@ Google Cloud metadata API is used to detect whether we are on Google Cloud. In the case of attestation types `dcap-tdx`, `gcp-tdx`, and `qemu-tdx`, a standard DCAP attestation is generated using the `configfs-tsm` linux filesystem interface. This means that the binary must be run with access to -`/sys/kernel/config/tsm/report` which on many systems requires sudo. +`/sys/kernel/config/tsm/report` which on many systems requires sudo. If +configfs-tsm is unavailable, quote generation via vSOCK to the QGS will be +attempted. Alternatively, an external 'attestation provider service' URL can be provided which outsources the attestation generation to another process. diff --git a/crates/attestation/src/dcap.rs b/crates/attestation/src/dcap.rs index b7a3922..dca2c10 100644 --- a/crates/attestation/src/dcap.rs +++ b/crates/attestation/src/dcap.rs @@ -1,6 +1,5 @@ //! Data Center Attestation Primitives (DCAP) evidence generation and //! verification -use configfs_tsm::QuoteGenerationError; use dcap_qvl::{ QuoteCollateralV3, collateral::get_collateral_for_fmspc, @@ -21,7 +20,7 @@ const AZURE_BAD_FMSPC: &str = "90C06F000000"; /// For fetching collateral directly from Intel, if no PCCS is specified pub const PCS_URL: &str = "https://api.trustedservices.intel.com"; -/// Quote generation using configfs_tsm +/// Generate a TDX quote pub fn create_dcap_attestation(input_data: [u8; 64]) -> Result, AttestationError> { let quote = generate_quote(input_data)?; tracing::info!("Generated TDX quote of {} bytes", quote.len()); @@ -255,18 +254,16 @@ pub fn verify_dcap_attestation_sync( /// Create a mock quote for testing on non-confidential hardware #[cfg(any(test, feature = "mock"))] -fn generate_quote(input: [u8; 64]) -> Result, QuoteGenerationError> { +fn generate_quote(input: [u8; 64]) -> Result, tdx_attest::TdxAttestError> { generate_mock_tdx_quote(input).map_err(|error| { - QuoteGenerationError::IO(std::io::Error::other(format!( - "mock-tdx quote generation: {error}" - ))) + tdx_attest::TdxAttestError::QuoteFailure(format!("mock-tdx quote generation: {error}")) }) } /// Create a quote #[cfg(not(any(test, feature = "mock")))] -fn generate_quote(input: [u8; 64]) -> Result, QuoteGenerationError> { - configfs_tsm::create_tdx_quote(input) +fn generate_quote(input: [u8; 64]) -> Result, tdx_attest::TdxAttestError> { + tdx_attest::get_quote(&input) } /// Given a [Report] get the input data regardless of report type diff --git a/crates/attestation/src/lib.rs b/crates/attestation/src/lib.rs index 6fe5335..73bc5ba 100644 --- a/crates/attestation/src/lib.rs +++ b/crates/attestation/src/lib.rs @@ -104,7 +104,7 @@ impl AttestationType { } // Otherwise try DCAP quote - this internally checks that the quote provider // is `tdx_guest` - if configfs_tsm::create_tdx_quote([0; 64]).is_ok() { + if tdx_attest::get_quote(&[0; 64]).is_ok() { if running_on_gcp()? { return Ok(AttestationType::GcpTdx); } else { @@ -582,8 +582,8 @@ pub enum AttestationError { X509(#[from] x509_parser::error::X509Error), #[error("Configuration mismatch - expected no remote attestation")] AttestationGivenWhenNoneExpected, - #[error("Configfs-tsm quote generation: {0}")] - QuoteGeneration(#[from] configfs_tsm::QuoteGenerationError), + #[error("TDX quote generation: {0}")] + QuoteGeneration(#[from] tdx_attest::TdxAttestError), #[error("DCAP verification: {0}")] DcapVerification(#[from] DcapVerificationError), #[error("Attestation type not supported")]