Skip to content

Commit

Permalink
AS-verifier: Add PCR verification to Azure vTPM
Browse files Browse the repository at this point in the history
The new update of the library now allows the user to verify if the
digest of PCRs matches the digest in Quote.

Signed-off-by: Suraj Deshmukh <[email protected]>
  • Loading branch information
surajssd committed Feb 2, 2024
1 parent c36b036 commit 05039ea
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
39 changes: 36 additions & 3 deletions attestation-service/verifier/src/az_snp_vtpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ impl Verifier for AzSnpVtpm {
/// The following verification steps are performed:
/// 1. TPM Quote has been signed by AK included in the HCL variable data
/// 2. Attestation report_data matches TPM Quote nonce
/// 3. SNP report's report_data field matches hashed HCL variable data
/// 4. SNP Report is genuine
/// 5. SNP Report has been issued in VMPL 0
/// 3. TPM PCRs' digest matches the digest in the Quote
/// 4. SNP report's report_data field matches hashed HCL variable data
/// 5. SNP Report is genuine
/// 6. SNP Report has been issued in VMPL 0
async fn evaluate(
&self,
evidence: &[u8],
Expand All @@ -73,6 +74,8 @@ impl Verifier for AzSnpVtpm {

verify_nonce(&evidence.quote, expected_report_data)?;

verify_pcrs(&evidence.quote)?;

let var_data_hash = hcl_report.var_data_sha256();
let snp_report = hcl_report.try_into()?;
verify_report_data(&var_data_hash, &snp_report)?;
Expand Down Expand Up @@ -106,6 +109,14 @@ fn verify_signature(quote: &Quote, hcl_report: &HclReport) -> Result<()> {
Ok(())
}

fn verify_pcrs(quote: &Quote) -> Result<()> {
quote
.verify_pcrs()
.context("Digest of PCRs does not match digest in Quote")?;
debug!("PCR verification completed successfully");
Ok(())
}

fn verify_report_data(var_data_hash: &[u8; 32], snp_report: &AttestationReport) -> Result<()> {
if *var_data_hash != snp_report.report_data[..32] {
bail!("SNP report report_data mismatch");
Expand Down Expand Up @@ -240,4 +251,26 @@ mod tests {
wrong_report_data.reverse();
verify_nonce(&quote, &wrong_report_data).unwrap_err();
}

#[test]
fn test_verify_pcrs() {
let quote: Quote = bincode::deserialize(QUOTE).unwrap();
verify_pcrs(&quote).unwrap();
}

#[test]
fn test_verify_pcrs_failure() {
let mut quote = QUOTE.clone();
quote[0x0169] = 0;
let wrong_quote: Quote = bincode::deserialize(&quote).unwrap();

assert_eq!(
verify_pcrs(&wrong_quote)
.unwrap_err()
.downcast_ref::<VerifyError>()
.unwrap()
.to_string(),
VerifyError::PcrMismatch.to_string()
);
}
}
37 changes: 35 additions & 2 deletions attestation-service/verifier/src/az_tdx_vtpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ impl Verifier for AzTdxVtpm {
/// The following verification steps are performed:
/// 1. TPM Quote has been signed by AK included in the HCL variable data
/// 2. Attestation nonce matches TPM Quote nonce
/// 3. TD Quote is genuine
/// 4. TD Report's report_data field matches hashed HCL variable data
/// 3. TPM PCRs' digest matches the digest in the Quote
/// 4. TD Quote is genuine
/// 5. TD Report's report_data field matches hashed HCL variable data
async fn evaluate(
&self,
evidence: &[u8],
Expand All @@ -54,6 +55,8 @@ impl Verifier for AzTdxVtpm {

verify_tpm_nonce(&evidence.tpm_quote, expected_report_data)?;

verify_pcrs(&evidence.tpm_quote)?;

ecdsa_quote_verification(&evidence.td_quote).await?;
let td_quote = parse_tdx_quote(&evidence.td_quote)?;

Expand Down Expand Up @@ -84,6 +87,14 @@ fn verify_tpm_signature(quote: &TpmQuote, hcl_report: &HclReport) -> Result<()>
Ok(())
}

fn verify_pcrs(quote: &TpmQuote) -> Result<()> {
quote
.verify_pcrs()
.context("Digest of PCRs does not match digest in Quote")?;
debug!("PCR verification completed successfully");
Ok(())
}

fn verify_tpm_nonce(quote: &TpmQuote, report_data: &[u8]) -> Result<()> {
let nonce = quote.nonce()?;
if nonce != report_data[..] {
Expand Down Expand Up @@ -161,4 +172,26 @@ mod tests {
let wrong_nonce = "wrong".as_bytes();
verify_tpm_nonce(&quote, wrong_nonce).unwrap_err();
}

#[test]
fn test_verify_pcrs() {
let quote: Quote = bincode::deserialize(QUOTE).unwrap();
verify_pcrs(&quote).unwrap();
}

#[test]
fn test_verify_pcrs_failure() {
let mut quote = QUOTE.clone();
quote[0x0169] = 0;
let wrong_quote: Quote = bincode::deserialize(&quote).unwrap();

assert_eq!(
verify_pcrs(&wrong_quote)
.unwrap_err()
.downcast_ref::<VerifyError>()
.unwrap()
.to_string(),
VerifyError::PcrMismatch.to_string()
);
}
}

0 comments on commit 05039ea

Please sign in to comment.