feat(tdx): add TDX RTMR extension support with UEFI marker

- Added `UEFI_MARKER_DIGEST_BYTES` constant for TDX RTMR extension.
- Implemented RTMR3 extension in `tee-key-preexec` for TDX attestation flow.
- Updated `rtmr-calc` to use `UEFI_MARKER_DIGEST_BYTES` for RTMR1 extension.

Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
This commit is contained in:
Harald Hoyer 2025-02-20 14:16:44 +01:00
parent a430e2f93b
commit 049f1b3de8
Signed by: harald
GPG key ID: F519A1143B3FBE32
3 changed files with 49 additions and 6 deletions

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Matter Labs
// Copyright (c) 2024-2025 Matter Labs
use anyhow::{anyhow, Result};
use clap::Parser;
@ -10,7 +10,10 @@ use std::{
io::{Error, ErrorKind, Read, Seek, SeekFrom},
path::PathBuf,
};
use teepot::log::{setup_logging, LogLevelParser};
use teepot::{
log::{setup_logging, LogLevelParser},
tdx::rtmr::UEFI_MARKER_DIGEST_BYTES,
};
use tracing::{debug, info, level_filters::LevelFilter};
/// Precalculate rtmr1 and rtmr2 values.
@ -98,7 +101,7 @@ fn main() -> Result<()> {
Ok:
validseparator: UEFI
*/
rtmr1.extend(&hex::decode("394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0")?);
rtmr1.extend(&UEFI_MARKER_DIGEST_BYTES);
// Open disk image.
let cfg = gpt::GptConfig::new().writable(false);

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Matter Labs
// Copyright (c) 2024-2025 Matter Labs
//! Pre-exec for binary running in a TEE needing attestation of a secret signing key
@ -11,7 +11,10 @@ use clap::Parser;
use secp256k1::{rand, Secp256k1};
use std::{ffi::OsString, os::unix::process::CommandExt, process::Command};
use teepot::{
ethereum::public_key_to_ethereum_address, prover::reportdata::ReportDataV1, quote::get_quote,
ethereum::public_key_to_ethereum_address,
prover::reportdata::ReportDataV1,
quote::get_quote,
tdx::rtmr::{TdxRtmrEvent, UEFI_MARKER_DIGEST_BYTES},
};
use tracing::error;
use tracing_log::LogTracer;
@ -46,6 +49,18 @@ fn main_with_error() -> Result<()> {
let report_data = ReportDataV1 { ethereum_address };
let report_data_bytes: [u8; 64] = report_data.into();
let tee_type = match get_quote(&report_data_bytes) {
Ok((teepot::quote::TEEType::TDX, quote)) => {
// In the case of TDX, we want to advance RTMR 3 after getting the quote,
// so that any breach can't generate a new attestation with the expected RTMRs
TdxRtmrEvent::default()
.with_rtmr_index(3)
.with_extend_data(UEFI_MARKER_DIGEST_BYTES)
.extend()?;
// save quote to file
std::fs::write(TEE_QUOTE_FILE, quote)?;
teepot::quote::TEEType::TDX.to_string()
}
Ok((tee_type, quote)) => {
// save quote to file
std::fs::write(TEE_QUOTE_FILE, quote)?;

View file

@ -1,10 +1,22 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Matter Labs
// Copyright (c) 2024-2025 Matter Labs
//! rtmr event data
use crate::sgx::QuoteError;
/// The sha384 digest of 0u32, which is used in the UEFI TPM protocol
/// as a marker. Used to advance the PCR.
/// ```shell
/// $ echo -n -e "\000\000\000\000" | sha384sum -b
/// 394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0 *-
/// ```
pub const UEFI_MARKER_DIGEST_BYTES: [u8; 48] = [
0x39, 0x43, 0x41, 0xb7, 0x18, 0x2c, 0xd2, 0x27, 0xc5, 0xc6, 0xb0, 0x7e, 0xf8, 0x00, 0x0c, 0xdf,
0xd8, 0x61, 0x36, 0xc4, 0x29, 0x2b, 0x8e, 0x57, 0x65, 0x73, 0xad, 0x7e, 0xd9, 0xae, 0x41, 0x01,
0x9f, 0x58, 0x18, 0xb4, 0xb9, 0x71, 0xc9, 0xef, 0xfc, 0x60, 0xe1, 0xad, 0x9f, 0x12, 0x89, 0xf0,
];
/// The actual rtmr event data handled in DCAP
#[repr(C, packed)]
pub struct TdxRtmrEvent {
@ -88,3 +100,16 @@ impl From<TdxRtmrEvent> for Vec<u8> {
res
}
}
#[cfg(test)]
mod test {
use super::UEFI_MARKER_DIGEST_BYTES;
#[test]
fn test_uefi_marker_digest() {
assert_eq!(
UEFI_MARKER_DIGEST_BYTES.to_vec(),
hex::decode("394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0").unwrap()
);
}
}