feat: compat code for non x86_64-linux

- do not build packages, which require `x86_64-linux`
- use Phala `dcap-qvl` crate for remote attestation, if possible
- nix: exclude `nixsgx` on non `x86_64-linux` platforms

Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
This commit is contained in:
Harald Hoyer 2025-03-20 10:25:24 +01:00
parent ed808efd03
commit eb39705ff1
Signed by: harald
GPG key ID: F519A1143B3FBE32
41 changed files with 1531 additions and 519 deletions

View file

@ -12,7 +12,7 @@ use std::{
};
use teepot::{
log::{setup_logging, LogLevelParser},
tdx::rtmr::UEFI_MARKER_DIGEST_BYTES,
tdx::UEFI_MARKER_DIGEST_BYTES,
};
use tracing::{debug, info, level_filters::LevelFilter};

View file

@ -6,53 +6,64 @@
#![deny(missing_docs)]
#![deny(clippy::all)]
use anyhow::{Context, Result};
use clap::Parser;
use teepot::{
log::{setup_logging, LogLevelParser},
tdx::rtmr::TdxRtmrEvent,
util::pad,
};
use tracing::{error, level_filters::LevelFilter};
use tracing::error;
/// Extend a TDX rtmr with a hash digest for measured boot.
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Arguments {
/// digest in hex to extend the rtmr with
#[arg(long)]
digest: String,
/// the number or the rtmr
#[arg(long, default_value = "2")]
rtmr: u64,
/// Log level for the log output.
/// Valid values are: `off`, `error`, `warn`, `info`, `debug`, `trace`
#[clap(long, default_value_t = LevelFilter::WARN, value_parser = LogLevelParser)]
pub log_level: LevelFilter,
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
mod os {
use anyhow::{Context as _, Result};
use clap::Parser;
use teepot::{
log::{setup_logging, LogLevelParser},
tdx::rtmr::TdxRtmrEvent,
util::pad,
};
use tracing::level_filters::LevelFilter;
/// Extend a TDX rtmr with a hash digest for measured boot.
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Arguments {
/// digest in hex to extend the rtmr with
#[arg(long)]
digest: String,
/// the number or the rtmr
#[arg(long, default_value = "2")]
rtmr: u64,
/// Log level for the log output.
/// Valid values are: `off`, `error`, `warn`, `info`, `debug`, `trace`
#[clap(long, default_value_t = LevelFilter::WARN, value_parser = LogLevelParser)]
pub log_level: LevelFilter,
}
pub fn main_with_error() -> Result<()> {
let args = Arguments::parse();
tracing::subscriber::set_global_default(setup_logging(
env!("CARGO_CRATE_NAME"),
&args.log_level,
)?)?;
// Parse the digest string as a hex array
let digest_bytes = hex::decode(&args.digest).context("Invalid digest format")?;
let extend_data: [u8; 48] = pad(&digest_bytes).context("Invalid digest length")?;
// Extend the TDX measurement with the extend data
TdxRtmrEvent::default()
.with_extend_data(extend_data)
.with_rtmr_index(args.rtmr)
.extend()?;
Ok(())
}
}
fn main_with_error() -> Result<()> {
let args = Arguments::parse();
tracing::subscriber::set_global_default(setup_logging(
env!("CARGO_CRATE_NAME"),
&args.log_level,
)?)?;
// Parse the digest string as a hex array
let digest_bytes = hex::decode(&args.digest).context("Invalid digest format")?;
let extend_data: [u8; 48] = pad(&digest_bytes).context("Invalid digest length")?;
// Extend the TDX measurement with the extend data
TdxRtmrEvent::default()
.with_extend_data(extend_data)
.with_rtmr_index(args.rtmr)
.extend()?;
Ok(())
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
mod os {
pub fn main_with_error() -> anyhow::Result<()> {
anyhow::bail!("OS or architecture not supported");
}
}
fn main() -> Result<()> {
let ret = main_with_error();
fn main() -> anyhow::Result<()> {
let ret = os::main_with_error();
if let Err(e) = &ret {
error!(error = %e, "Execution failed");
}

View file

@ -6,21 +6,10 @@
#![deny(missing_docs)]
#![deny(clippy::all)]
use anyhow::{Context, Result};
use anyhow::Result;
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,
tdx::rtmr::{TdxRtmrEvent, UEFI_MARKER_DIGEST_BYTES},
};
use std::ffi::OsString;
use tracing::error;
use tracing_log::LogTracer;
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Registry};
const TEE_QUOTE_FILE: &str = "/tmp/tee_quote";
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
@ -33,7 +22,21 @@ struct Args {
cmd_args: Vec<OsString>,
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
fn main_with_error() -> Result<()> {
use anyhow::Context;
use secp256k1::{rand, Secp256k1};
use std::{os::unix::process::CommandExt, process::Command};
use teepot::tdx::rtmr::TdxRtmrEvent;
use teepot::{
ethereum::public_key_to_ethereum_address, prover::reportdata::ReportDataV1,
quote::get_quote,
};
use tracing_log::LogTracer;
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Registry};
const TEE_QUOTE_FILE: &str = "/tmp/tee_quote";
LogTracer::init().context("Failed to set logger")?;
let subscriber = Registry::default()
@ -54,7 +57,7 @@ fn main_with_error() -> Result<()> {
// 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)
.with_extend_data(teepot::tdx::UEFI_MARKER_DIGEST_BYTES)
.extend()?;
// save quote to file
@ -94,6 +97,11 @@ fn main_with_error() -> Result<()> {
})
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
fn main_with_error() -> Result<()> {
anyhow::bail!("OS or architecture not supported");
}
fn main() -> Result<()> {
let ret = main_with_error();
if let Err(e) = &ret {

View file

@ -7,10 +7,7 @@ use anyhow::{bail, Context, Result};
use clap::Parser;
use std::{fs, io::Read, path::PathBuf, str::FromStr, time::UNIX_EPOCH};
use teepot::quote::{
error, tcblevel::TcbLevel, tee_qv_get_collateral, verify_quote_with_collateral,
QuoteVerificationResult,
};
use teepot::quote::{get_collateral, verify_quote_with_collateral, QuoteVerificationResult};
#[derive(Parser, Debug)]
#[command(author = "Matter Labs", version, about = "SGX attestation and batch signature verifier", long_about = None)]
@ -62,10 +59,7 @@ fn verify_attestation_quote(attestation_quote_bytes: &[u8]) -> Result<QuoteVerif
"Verifying quote ({} bytes)...",
attestation_quote_bytes.len()
);
let collateral = error::QuoteContext::context(
tee_qv_get_collateral(attestation_quote_bytes),
"Failed to get collateral",
)?;
let collateral = get_collateral(attestation_quote_bytes)?;
let unix_time: i64 = std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)?
.as_secs() as _;
@ -76,7 +70,7 @@ fn verify_attestation_quote(attestation_quote_bytes: &[u8]) -> Result<QuoteVerif
fn print_quote_verification_summary(quote_verification_result: &QuoteVerificationResult) {
let QuoteVerificationResult {
collateral_expired,
result,
result: tcblevel,
quote,
advisories,
..
@ -84,7 +78,6 @@ fn print_quote_verification_summary(quote_verification_result: &QuoteVerificatio
if *collateral_expired {
println!("Freshly fetched collateral expired");
}
let tcblevel = TcbLevel::from(*result);
for advisory in advisories {
println!("\tInfo: Advisory ID: {advisory}");
}

View file

@ -1,10 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2023-2025 Matter Labs
use teepot::quote::{
error::QuoteContext, tee_qv_get_collateral, verify_quote_with_collateral,
QuoteVerificationResult,
};
use teepot::quote::{get_collateral, verify_quote_with_collateral, QuoteVerificationResult};
use crate::error;
@ -15,10 +12,7 @@ impl AttestationVerifier {
/// Verify an attestation quote
pub fn verify_quote(attestation_quote_bytes: &[u8]) -> error::Result<QuoteVerificationResult> {
// Get collateral for the quote
let collateral = QuoteContext::context(
tee_qv_get_collateral(attestation_quote_bytes),
"Failed to get collateral!",
)?;
let collateral = get_collateral(attestation_quote_bytes)?;
// Get current time for verification
let unix_time: i64 = std::time::SystemTime::now()

View file

@ -19,7 +19,7 @@ impl PolicyEnforcer {
quote_verification_result: &QuoteVerificationResult,
) -> Result<()> {
let quote = &quote_verification_result.quote;
let tcblevel = TcbLevel::from(quote_verification_result.result);
let tcblevel = quote_verification_result.result;
match &quote.report {
Report::SgxEnclave(report_body) => {

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2023-2025 Matter Labs
use teepot::quote::{tcblevel::TcbLevel, QuoteVerificationResult};
use teepot::quote::QuoteVerificationResult;
/// Handles reporting and logging of verification results
pub struct VerificationReporter;
@ -11,7 +11,7 @@ impl VerificationReporter {
pub fn log_quote_verification_summary(quote_verification_result: &QuoteVerificationResult) {
let QuoteVerificationResult {
collateral_expired,
result,
result: tcblevel,
quote,
advisories,
..
@ -21,7 +21,6 @@ impl VerificationReporter {
tracing::warn!("Freshly fetched collateral expired!");
}
let tcblevel = TcbLevel::from(*result);
let advisories = if advisories.is_empty() {
"None".to_string()
} else {