Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions 3rdparty/internal/tee-attestation-verification/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Changelog

## [1.0.7]

[1.0.7]: https://github.com/microsoft/TEE-Attestation-Verification/releases/tag/tav-1.0.7

### Added

- C and .NET FFI constructors for decoding SNP reports without verification. (#101)

## [1.0.6]

[1.0.6]: https://github.com/microsoft/TEE-Attestation-Verification/releases/tag/tav-1.0.6

### Changed

- Updated the NuGet package README to consume C-ACI's published endorsement formats directly. (#98)

## [1.0.5]

[1.0.5]: https://github.com/microsoft/TEE-Attestation-Verification/releases/tag/tav-1.0.5

### Added

- Nuget packaging (#94)

## [1.0.4]

[1.0.4]: https://github.com/microsoft/TEE-Attestation-Verification/releases/tag/tav-1.0.4
Expand Down
10 changes: 5 additions & 5 deletions 3rdparty/internal/tee-attestation-verification/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tee-attestation-verification-lib"
version = "1.0.4"
version = "1.0.7"
edition = "2021"
rust-version = "1.77"
repository = "https://github.com/microsoft/TEE-Attestation-Verification"
Expand Down Expand Up @@ -45,7 +45,7 @@ env_logger = "0.11"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

[dependencies]
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.4", path = "../crypto", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.7", path = "../crypto", default-features = false }
zerocopy = {version = "0.8.31", features = ["derive"]}

# KDS (online certificate fetching) dependencies
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tee-attestation-verification-caci"
version = "1.0.4"
version = "1.0.7"
edition = "2021"
rust-version = "1.77"
repository = "https://github.com/microsoft/TEE-Attestation-Verification"
Expand Down Expand Up @@ -32,9 +32,9 @@ crypto_webcrypto = [
]

[dependencies]
attestation = { package = "tee-attestation-verification-lib", version = "1.0.4", path = "../attestation", default-features = false }
cose = { package = "tee-attestation-verification-cose", version = "1.0.4", path = "../cose", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.4", path = "../crypto", default-features = false }
attestation = { package = "tee-attestation-verification-lib", version = "1.0.7", path = "../attestation", default-features = false }
cose = { package = "tee-attestation-verification-cose", version = "1.0.7", path = "../cose", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.7", path = "../crypto", default-features = false }
serde_json = "1"

[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tee-attestation-verification-cose"
version = "1.0.4"
version = "1.0.7"
edition = "2021"
rust-version = "1.77"
repository = "https://github.com/microsoft/TEE-Attestation-Verification"
Expand All @@ -16,7 +16,7 @@ crypto_pure_rust = ["crypto/crypto_pure_rust"]
crypto_webcrypto = ["crypto/crypto_webcrypto"]

[dependencies]
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.4", path = "../crypto", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.7", path = "../crypto", default-features = false }
# project-everest/everparse tag v2026.07.02 resolves to this pinned commit.
cborrs = { git = "https://github.com/project-everest/everparse.git", rev = "950bc93838ac2faae51126d8acd0637cf8c8a569" }
cborrs-nondet = { git = "https://github.com/project-everest/everparse.git", rev = "950bc93838ac2faae51126d8acd0637cf8c8a569" }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tee-attestation-verification-crypto"
version = "1.0.4"
version = "1.0.7"
edition = "2021"
rust-version = "1.77"
repository = "https://github.com/microsoft/TEE-Attestation-Verification"
Expand Down
10 changes: 5 additions & 5 deletions 3rdparty/internal/tee-attestation-verification/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tee-attestation-verification-ffi"
version = "1.0.4"
version = "1.0.7"
edition = "2021"
rust-version = "1.77"
repository = "https://github.com/microsoft/TEE-Attestation-Verification"
Expand Down Expand Up @@ -33,10 +33,10 @@ crypto_webcrypto = [
]

[dependencies]
attestation = { package = "tee-attestation-verification-lib", version = "1.0.4", path = "../attestation", default-features = false }
caci = { package = "tee-attestation-verification-caci", version = "1.0.4", path = "../caci", default-features = false }
cose = { package = "tee-attestation-verification-cose", version = "1.0.4", path = "../cose", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.4", path = "../crypto", default-features = false }
attestation = { package = "tee-attestation-verification-lib", version = "1.0.7", path = "../attestation", default-features = false }
caci = { package = "tee-attestation-verification-caci", version = "1.0.7", path = "../caci", default-features = false }
cose = { package = "tee-attestation-verification-cose", version = "1.0.7", path = "../cose", default-features = false }
crypto = { package = "tee-attestation-verification-crypto", version = "1.0.7", path = "../crypto", default-features = false }
serde_json = "1"
zerocopy = { version = "0.8.31", features = ["derive"] }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ TAV_CACI_API TavError *tav_verify_caci_uvm_endorsement(
/*
* Verify the relying-party CACI policy over staged verified artifacts.
*
* attestation must be a report returned by tav_verify_snp_attestation. The
* caller is responsible for not passing a report created by
* tav_snp_attestation_report_from_unverified_bytes.
*
* The minimum TCB policy is passed as two parallel arrays of minimum_tcb_count
* entries: minimum_tcb_cpuids holds one uint32_t CPUID per entry, and
* minimum_tcb_values holds minimum_tcb_count contiguous 8-byte TCB values (the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ extern "C" {
*
* Usage summary:
* - Call tav_verify_snp_attestation with the raw attestation report and the
* ARK, ASK, and VCEK certificates in PEM format.
* - On success, verification writes a TavSnpAttestationReport* to out_report.
* ARK, ASK, and VCEK certificates in PEM format, or call
* tav_snp_attestation_report_from_unverified_bytes for fixed-size decoding
* without authentication or semantic validation.
* - On success, either function writes a TavSnpAttestationReport* to out_report.
* Pass that report handle to the tav_snp_attestation_report_* accessors.
* - Free the report handle with tav_snp_attestation_report_free when finished.
*
* Error behavior:
* - tav_verify_snp_attestation returns NULL on success, or an owned TavError*
* on failure. Inspect failures with tav_error_code and tav_error_message,
* then free them with tav_error_free.
* - tav_verify_snp_attestation reports invalid verification inputs and invalid
* out_report state as TavError failures. Each input buffer is capped at
* 1 GiB.
* - Both report constructors return NULL on success, or an owned TavError* on
* failure. Inspect failures with tav_error_code and tav_error_message, then
* free them with tav_error_free.
* - Both constructors report invalid inputs and invalid out_report state as
* TavError failures. Each input buffer is capped at 1 GiB.
* - Error accessors are defensive for NULL TavError pointers: tav_error_code
* returns TAV_ERROR_IS_NULL and tav_error_message returns a static
* diagnostic string.
Expand Down Expand Up @@ -63,7 +64,22 @@ TAV_API TavError *tav_verify_snp_attestation(
size_t vcek_pem_len,
TavSnpAttestationReport **out_report);

/* Scalar report accessors. Invalid report pointers are undefined behavior. */
/*
* Parse an SNP attestation report without cryptographic verification.
*
* This checks only that the input has the fixed SNP report size. It does not
* validate field values, reserved bytes, signatures, certificates, or TCBs.
* Do not make trust decisions from the returned report.
*
* out_report must point to a writable report-handle slot. The slot is set to
* NULL before any fallible work and set to an owned handle only on success.
*/
TAV_API TavError *tav_snp_attestation_report_from_unverified_bytes(
const uint8_t *report_bytes,
size_t report_len,
TavSnpAttestationReport **out_report);

/* Report accessors. Invalid report pointers are undefined behavior. */
TAV_API uint32_t tav_snp_attestation_report_version(
const TavSnpAttestationReport *report);
TAV_API uint32_t tav_snp_attestation_report_guest_svn(
Expand Down Expand Up @@ -196,7 +212,7 @@ TAV_API void tav_snp_attestation_report_signature_s(
const uint8_t **data,
size_t *len);

/* Frees a report handle returned by tav_verify_snp_attestation. NULL is a no-op. */
/* Frees a report handle returned by either report constructor. NULL is a no-op. */
TAV_API void tav_snp_attestation_report_free(TavSnpAttestationReport *report);

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
//!
//! This module exports the symbols declared in `ffi/include/tav/snp.h`.
//!
//! [`tav_verify_snp_attestation`] returns a null [`TavError`] pointer on
//! success and an owned [`TavError`] pointer on failure. On success it
//! writes an owned [`TavSnpAttestationReport`] handle to `out_report`.
//! [`tav_verify_snp_attestation`] and
//! [`tav_snp_attestation_report_from_unverified_bytes`] return a null
//! [`TavError`] pointer on success and an owned [`TavError`] pointer on failure.
//! On success they write an owned [`TavSnpAttestationReport`] handle to
//! `out_report`. The latter performs fixed-size decoding only; its handle must
//! not be used where a cryptographically verified report is required.
//! Callers release these handles with [`crate::c_ffi::utils::tav_error_free`] and
//! [`tav_snp_attestation_report_free`].
//!
Expand Down Expand Up @@ -39,11 +42,20 @@ fn tav_error_from_verification_error(error: VerificationError) -> TavError {
TavError::new(code, error.to_string())
}

fn parse_report(report_bytes: &[u8]) -> Result<&AttestationReport, TavError> {
AttestationReport::ref_from_bytes(report_bytes).map_err(|_| {
TavError::invalid_argument(format!(
"Invalid attestation report: expected {} bytes, got {}",
std::mem::size_of::<AttestationReport>(),
report_bytes.len()
))
})
}

impl TavSnpAttestationReport {
pub fn report(&self) -> &AttestationReport {
AttestationReport::ref_from_bytes(&self.bytes).expect(
"TavSnpAttestationReport is only constructed from verified bytes so parsing should not fail",
)
AttestationReport::ref_from_bytes(&self.bytes)
.expect("TavSnpAttestationReport is only constructed from exact-size bytes")
}
}

Expand Down Expand Up @@ -94,13 +106,7 @@ pub unsafe extern "C" fn tav_verify_snp_attestation(

let report_bytes =
unsafe { input_bytes(report_bytes, report_len, "attestation report", false) }?;
let report = AttestationReport::ref_from_bytes(report_bytes).map_err(|_| {
TavError::invalid_argument(format!(
"Invalid attestation report: expected {} bytes, got {}",
std::mem::size_of::<AttestationReport>(),
report_len
))
})?;
let report = parse_report(report_bytes)?;

let ark_pem = unsafe { input_bytes(ark_pem, ark_pem_len, "ARK", false) }?;
let ark = certificate_from_pem(ark_pem).map_err(|error| {
Expand Down Expand Up @@ -137,6 +143,29 @@ pub unsafe extern "C" fn tav_verify_snp_attestation(
})
}

#[no_mangle]
pub unsafe extern "C" fn tav_snp_attestation_report_from_unverified_bytes(
report_bytes: *const u8,
report_len: usize,
out_report: *mut *mut TavSnpAttestationReport,
) -> *mut TavError {
into_result(|| {
unsafe { owned_out_ptr(out_report, "out_report") }?;

let report_bytes =
unsafe { input_bytes(report_bytes, report_len, "attestation report", false) }?;
parse_report(report_bytes)?;

let report = TavSnpAttestationReport {
bytes: report_bytes.to_vec(),
};
unsafe {
*out_report = Box::into_raw(Box::new(report));
}
Ok(())
})
}

scalar_accessor!(tav_snp_attestation_report_version, u32, |report| report
.version
.get());
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed

- SNP attestation reports are now parsed and verified through TAV accessors. The public packed `ccf::pal::snp::Attestation` wire-layout type has been replaced by the move-only `ccf::pal::snp::AttestationReport` accessor API. (#8083)
- TLS handshakes now prefer hybrid post-quantum key exchange groups, in the order `SecP384r1MLKEM1024`, `SecP256r1MLKEM768`, `X25519MLKEM768`, when the linked crypto provider supports them. The `P-521`, `P-384` and `P-256` groups are retained as fallbacks (#8107).
- `ccf.cose.verify_receipt()` has moved and been renamed to `ccf.receipt.verify_cose()`; the old name still works but is deprecated (#8109).

Expand Down
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,11 @@ install(TARGETS http_parser EXPORT ccf DESTINATION lib)
add_ccf_static_library(
ccf_pal
SRCS ${CCF_DIR}/src/pal/attestation.cpp
LINK_LIBS ccfcrypto
LINK_LIBS ccfcrypto ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} m
)
target_include_directories(
ccf_pal
PRIVATE ${CCF_DIR}/3rdparty/internal/tee-attestation-verification/ffi/include
)

# CCF js lib
Expand Down Expand Up @@ -600,6 +604,7 @@ if(BUILD_TESTS)
snp_ioctl_test
${CMAKE_CURRENT_SOURCE_DIR}/src/pal/test/snp_ioctl_test.cpp
)
target_link_libraries(snp_ioctl_test PRIVATE ccf_pal)
set_property(TEST snp_ioctl_test APPEND PROPERTY LABELS snp)
set_property(TEST snp_ioctl_test APPEND PROPERTY CONFIGURATIONS snp)

Expand Down
1 change: 1 addition & 0 deletions cmake/ccf_rs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ add_custom_target(
"${CCF_RS_DIR}/rust-toolchain.toml"
"${CCF_DIR}/src/cose/cose_rs/Cargo.toml"
"${CCF_DIR}/3rdparty/internal/cose-openssl/Cargo.toml"
"${CCF_DIR}/3rdparty/internal/tee-attestation-verification/ffi/Cargo.toml"
COMMENT
"Building ${CCF_RS_PACKAGE} Rust static library (Cargo profile: ${CCF_RS_CARGO_PROFILE_NAME})"
USES_TERMINAL
Expand Down
2 changes: 1 addition & 1 deletion include/ccf/node/quote.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace ccf

static std::optional<HostData> get_host_data(const QuoteInfo& quote_info);

static std::optional<pal::snp::Attestation> get_snp_attestation(
static std::optional<pal::snp::AttestationReport> get_snp_attestation(
const QuoteInfo& quote_info);

static QuoteVerificationResult verify_quote_against_store(
Expand Down
6 changes: 6 additions & 0 deletions include/ccf/pal/attestation.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

#include "ccf/ds/quote_info.h"
#include "ccf/pal/attestation_sev_snp.h"
#include "ccf/pal/attestation_sev_snp_endorsements.h"
#include "ccf/pal/measurement.h"
#include "ccf/pal/report_data.h"
Expand All @@ -28,6 +29,11 @@ namespace ccf::pal
PlatformAttestationMeasurement& measurement,
PlatformAttestationReportData& report_data);

snp::AttestationReport verify_snp_attestation_report_and_get(
const QuoteInfo& quote_info,
PlatformAttestationMeasurement& measurement,
PlatformAttestationReportData& report_data);

void verify_quote(
const QuoteInfo& quote_info,
PlatformAttestationMeasurement& measurement,
Expand Down
Loading
Loading