Skip to content

Commit

Permalink
attester: tdx: use TSM reports to generate quotes
Browse files Browse the repository at this point in the history
Move tdx attester to primarily use TSM reports to get
the quotes generated.

The ioctl() based get-quote mechanisms have never been
upstreamed so they can be considered 'deprecated'. However,
a feature switch is added to keep the old functionality available
for now.

Signed-off-by: Mikko Ylinen <[email protected]>
  • Loading branch information
mythi committed Jan 26, 2024
1 parent b162780 commit c03ac3c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion attestation-agent/attester/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ base64.workspace = true
kbs-types.workspace = true
log.workspace = true
nix = { version = "0.26.2", optional = true }
cfg-if.workspace = true
occlum_dcap = { git = "https://github.com/occlum/occlum", tag = "v0.29.7", optional = true }
serde.workspace = true
serde_json.workspace = true
Expand Down Expand Up @@ -58,7 +59,8 @@ all-attesters = [
# quotes. It's an unconditional dependency for tdx-attester since that is the only way to
# generate TDX quotes with upstream kernels.
tsm-report = ["tempfile"]
tdx-attester = ["tdx-attest-rs"]
tdx-attester = ["tsm-report", "tdx-getquote-ioctl"]
tdx-getquote-ioctl = ["tdx-attest-rs"]
sgx-attester = ["occlum_dcap"]
az-snp-vtpm-attester = ["az-snp-vtpm"]
az-tdx-vtpm-attester = ["az-tdx-vtpm"]
Expand Down
59 changes: 44 additions & 15 deletions attestation-agent/attester/src/tdx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,50 @@
// SPDX-License-Identifier: Apache-2.0
//

use super::tsm_report::*;
use super::Attester;
use anyhow::*;
use base64::Engine;
use serde::{Deserialize, Serialize};
use std::path::Path;

#[cfg(feature = "tdx-getquote-ioctl")]
use tdx_attest_rs;

const TDX_REPORT_DATA_SIZE: usize = 64;
const CCEL_PATH: &str = "/sys/firmware/acpi/tables/data/CCEL";

fn tdx_getquote_ioctl_is_available() -> bool {
if cfg!(feature = "tdx-getquote-ioctl") {
Path::new("/dev/tdx-attest").exists() || Path::new("/dev/tdx-guest").exists()
} else {
false
}
}

#[allow(unused_variables)]
fn get_quote_ioctl(report_data: &Vec<u8>) -> Result<Vec<u8>> {
cfg_if::cfg_if! {
if #[cfg(feature = "tdx-getquote-ioctl")] {
let tdx_report_data = tdx_attest_rs::tdx_report_data_t {
// report_data.resize() ensures copying report_data to
// tdx_attest_rs::tdx_report_data_t cannot panic.
d: report_data.as_slice().try_into().unwrap(),
};

match tdx_attest_rs::tdx_att_get_quote(Some(&tdx_report_data), None, None, 0) {
(tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS, Some(q)) => Ok(q),
(error_code, _) => Err(anyhow!("TDX getquote ioctl also failed (error code: {:?}) after:", error_code)),
}
} else {
// return empty error
Err(anyhow!(""))
}
}
}

pub fn detect_platform() -> bool {
Path::new("/dev/tdx-attest").exists() || Path::new("/dev/tdx-guest").exists()
tsm_report_provider_is(TsmReportProvider::Tdx) || tdx_getquote_ioctl_is_available()
}

#[derive(Serialize, Deserialize)]
Expand All @@ -38,22 +70,18 @@ impl Attester for TdxAttester {

report_data.resize(TDX_REPORT_DATA_SIZE, 0);

let tdx_report_data = tdx_attest_rs::tdx_report_data_t {
// report_data.resize() ensures copying report_data to
// tdx_attest_rs::tdx_report_data_t cannot panic.
d: report_data.as_slice().try_into().unwrap(),
};
let quote_bytes = TsmReportPath::new().map_or_else(
|notsm| {
get_quote_ioctl(&report_data).map_err(|e| anyhow!("TDX Attester: {}{}", e, notsm))
},
|tsm| {
tsm.attestation_report(TsmReportData::Tdx(report_data.clone()))
.map_err(|e| anyhow!("TDX Attester: {}", e))
},
)?;

let engine = base64::engine::general_purpose::STANDARD;
let quote = match tdx_attest_rs::tdx_att_get_quote(Some(&tdx_report_data), None, None, 0) {
(tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS, Some(q)) => engine.encode(q),
(error_code, _) => {
return Err(anyhow!(
"TDX Attester: Failed to get TD quote. Error code: {:?}",
error_code
));
}
};
let quote = engine.encode(quote_bytes);

let cc_eventlog = match std::fs::read(CCEL_PATH) {
Result::Ok(el) => Some(engine.encode(el)),
Expand All @@ -69,6 +97,7 @@ impl Attester for TdxAttester {
.map_err(|e| anyhow!("Serialize TDX evidence failed: {:?}", e))
}

#[cfg(feature = "tdx-getquote-ioctl")]
async fn extend_runtime_measurement(
&self,
events: Vec<Vec<u8>>,
Expand Down

0 comments on commit c03ac3c

Please sign in to comment.