Skip to content

Commit

Permalink
attester: rename check_init_data => bind_init_data
Browse files Browse the repository at this point in the history
This change generalizes the concept of binding init_data to the TEE
evidence. In SNP and TDX attesters this currently happens via equality
checks on the HW report's HOSTDATA/MRCONFIGID fields.

On vTPM attester modules or other attesters which do not allow
setting similar fields, the binding can be performed by extending the
HW evidence.

Signed-off-by: Magnus Kulke <[email protected]>
  • Loading branch information
mkulke committed Oct 28, 2024
1 parent 1a6bb93 commit 87df6be
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 35 deletions.
17 changes: 9 additions & 8 deletions attestation-agent/attestation-agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ use crate::config::Config;
/// current hardware runtime measurement register (if any) or PCR for (v)TPM (under
/// development) platforms
/// with a runtime event.
/// - `check_init_data`: check if the given data slice matches the current confidential
/// computing environment's host data field, e.g. MRCONFIGID for TDX, HOSTDATA for SNP.
/// - `bind_init_data`: bind the given data slice to the current confidential
/// computing environment. This can be a verify operation or an extension of the TEE
/// evidence
///
/// # Example
///
Expand Down Expand Up @@ -69,8 +70,8 @@ pub trait AttestationAPIs {
register_index: Option<u64>,
) -> Result<()>;

/// Check the initdata binding
async fn check_init_data(&self, init_data: &[u8]) -> Result<InitdataResult>;
/// Bind initdata
async fn bind_init_data(&self, init_data: &[u8]) -> Result<InitdataResult>;

fn get_tee_type(&self) -> Tee;
}
Expand Down Expand Up @@ -233,10 +234,10 @@ impl AttestationAPIs for AttestationAgent {
Ok(())
}

/// Check the initdata binding. If current platform does not support initdata
/// injection, return `InitdataResult::Unsupported`.
async fn check_init_data(&self, init_data: &[u8]) -> Result<InitdataResult> {
self.attester.check_init_data(init_data).await
/// Perform the initdata binding. If current platform does not support initdata
/// binding, return `InitdataResult::Unsupported`.
async fn bind_init_data(&self, init_data: &[u8]) -> Result<InitdataResult> {
self.attester.bind_init_data(init_data).await
}

/// Get the tee type of current platform. If no platform is detected,
Expand Down
2 changes: 1 addition & 1 deletion attestation-agent/attester/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ tsm-report = ["tempfile"]
tdx-attester = ["scroll", "tsm-report", "tdx-attest-rs"]
sgx-attester = ["occlum_dcap"]
az-snp-vtpm-attester = ["az-snp-vtpm"]
az-tdx-vtpm-attester = ["az-tdx-vtpm"]
az-tdx-vtpm-attester = ["az-snp-vtpm-attester", "az-tdx-vtpm"]
snp-attester = ["sev"]
csv-attester = ["csv-rs", "codicon", "hyper", "hyper-tls", "tokio"]
cca-attester = ["tsm-report"]
Expand Down
28 changes: 20 additions & 8 deletions attestation-agent/attester/src/az_snp_vtpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//

use super::Attester;
use super::{Attester, InitdataResult};
use anyhow::{bail, Context, Result};
use az_snp_vtpm::{imds, is_snp_cvm, vtpm};
use log::{debug, info};
Expand Down Expand Up @@ -46,19 +46,31 @@ impl Attester for AzSnpVtpmAttester {
Ok(serde_json::to_string(&evidence)?)
}

async fn bind_init_data(&self, init_data_digest: &[u8]) -> anyhow::Result<InitdataResult> {
utils::extend_pcr(init_data_digest, utils::INIT_DATA_PCR)?;
Ok(InitdataResult::Ok)
}

async fn extend_runtime_measurement(
&self,
event_digest: Vec<u8>,
register_index: u64,
) -> Result<()> {
let sha256_digest: [u8; 32] = event_digest
.as_slice()
.try_into()
.context("expected sha256 digest")?;
if register_index > 23 {
bail!("Invalid PCR index: {}", register_index);
utils::extend_pcr(&event_digest, register_index as u8)?;
Ok(())
}
}

pub(crate) mod utils {
use super::*;

pub const INIT_DATA_PCR: u8 = 8;

pub fn extend_pcr(digest: &[u8], pcr: u8) -> Result<()> {
let sha256_digest: [u8; 32] = digest.try_into().context("expected sha256 digest")?;
if pcr > 23 {
bail!("Invalid PCR index: {pcr}");
}
let pcr: u8 = register_index as u8;
info!("Extending PCR {} with {}", pcr, hex::encode(sha256_digest));
vtpm::extend_pcr(pcr, &sha256_digest)?;

Expand Down
22 changes: 9 additions & 13 deletions attestation-agent/attester/src/az_tdx_vtpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
// SPDX-License-Identifier: Apache-2.0
//

use super::Attester;
use super::{Attester, InitdataResult};
use crate::az_snp_vtpm::utils;
use anyhow::*;
use az_tdx_vtpm::vtpm::Quote as TpmQuote;
use az_tdx_vtpm::{hcl, imds, is_tdx_cvm, vtpm};
use log::{debug, info};
use log::debug;
use serde::{Deserialize, Serialize};
use std::result::Result::Ok;

Expand Down Expand Up @@ -49,22 +50,17 @@ impl Attester for AzTdxVtpmAttester {
Ok(serde_json::to_string(&evidence)?)
}

async fn bind_init_data(&self, init_data_digest: &[u8]) -> anyhow::Result<InitdataResult> {
utils::extend_pcr(init_data_digest, utils::INIT_DATA_PCR)?;
Ok(InitdataResult::Ok)
}

async fn extend_runtime_measurement(
&self,
event_digest: Vec<u8>,
register_index: u64,
) -> Result<()> {
let sha256_digest: [u8; 32] = event_digest
.as_slice()
.try_into()
.context("expected sha256 digest")?;
if register_index > 23 {
bail!("Invalid PCR index: {}", register_index);
}
let pcr: u8 = register_index as u8;
info!("Extending PCR {} with {}", pcr, hex::encode(sha256_digest));
vtpm::extend_pcr(pcr, &sha256_digest)?;

utils::extend_pcr(&event_digest, register_index as u8)?;
Ok(())
}
}
2 changes: 1 addition & 1 deletion attestation-agent/attester/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub trait Attester {
bail!("Unimplemented")
}

async fn check_init_data(&self, _init_data: &[u8]) -> Result<InitdataResult> {
async fn bind_init_data(&self, _init_data_digest: &[u8]) -> Result<InitdataResult> {
Ok(InitdataResult::Unsupported)
}
}
Expand Down
4 changes: 2 additions & 2 deletions attestation-agent/attester/src/snp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ impl Attester for SnpAttester {
serde_json::to_string(&evidence).context("Serialize SNP evidence failed")
}

async fn check_init_data(&self, init_data: &[u8]) -> Result<InitdataResult> {
async fn bind_init_data(&self, init_data_digest: &[u8]) -> Result<InitdataResult> {
let hostdata = hostdata::get_snp_host_data().context("Get HOSTDATA failed")?;
let init_data: [u8; 32] = pad(init_data);
let init_data: [u8; 32] = pad(init_data_digest);
if init_data != hostdata {
bail!("HOSTDATA does not match.");
}
Expand Down
4 changes: 2 additions & 2 deletions attestation-agent/attester/src/tdx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl Attester for TdxAttester {
Ok(())
}

async fn check_init_data(&self, init_data: &[u8]) -> Result<InitdataResult> {
async fn bind_init_data(&self, init_data_digest: &[u8]) -> Result<InitdataResult> {
let mut report = tdx_report_t { d: [0; 1024] };
match tdx_attest_rs::tdx_att_get_report(None, &mut report) {
tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS => {
Expand All @@ -176,7 +176,7 @@ impl Attester for TdxAttester {
.pread::<report::TdReport>(0)
.context("Parse TD report failed")?;

let init_data: [u8; 48] = pad(init_data);
let init_data: [u8; 48] = pad(init_data_digest);
if init_data != td_report.tdinfo.mrconfigid {
bail!("Init data does not match!");
}
Expand Down

0 comments on commit 87df6be

Please sign in to comment.