az_snp_vtpm/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//!  This library enables guest attestation flows for [SEV-SNP CVMs on Azure](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview). Please refer to the documentation in [this repository](https://github.com/Azure/confidential-computing-cvm-guest-attestation) for details on the attestation procedure.
5//!
6//!  # SNP Report Validation
7//!
8//!  The following code will retrieve an SNP report from the vTPM device, parse it, and validate it against the AMD certificate chain. Finally it will verify that a hash of a raw HCL report's Variable Data is equal to the `report_data` field in an embedded [Attestation Report](sev::firmware::guest::AttestationReport) structure.
9//!
10//!  #
11//!  ```no_run
12//!  use az_snp_vtpm::{amd_kds, hcl, vtpm};
13//!  use az_snp_vtpm::report::{AttestationReport, Validateable};
14//!  use std::error::Error;
15//!
16//!  fn main() -> Result<(), Box<dyn Error>> {
17//!    let bytes = vtpm::get_report()?;
18//!    let hcl_report = hcl::HclReport::new(bytes)?;
19//!    let var_data_hash = hcl_report.var_data_sha256();
20//!    let snp_report: AttestationReport = hcl_report.try_into()?;
21//!
22//!    let vcek = amd_kds::get_vcek(&snp_report)?;
23//!    let cert_chain = amd_kds::get_cert_chain()?;
24//!
25//!    cert_chain.validate()?;
26//!    vcek.validate(&cert_chain)?;
27//!    snp_report.validate(&vcek)?;
28//!
29//!    if var_data_hash != snp_report.report_data[..32] {
30//!      return Err("var_data_hash mismatch".into());
31//!    }
32//!
33//!    Ok(())
34//!  }
35//!  ```
36
37pub use az_cvm_vtpm::{hcl, vtpm};
38use thiserror::Error;
39
40#[derive(Error, Debug)]
41pub enum HttpError {
42    #[error("HTTP error")]
43    Http(#[from] Box<ureq::Error>),
44    #[error("failed to read HTTP response")]
45    Io(#[from] std::io::Error),
46}
47
48/// Determines if the current VM is an SEV-SNP CVM.
49/// Returns `Ok(true)` if the VM is an SEV-SNP CVM, `Ok(false)` if it is not,
50/// and `Err` if an error occurs.
51pub fn is_snp_cvm() -> Result<bool, vtpm::ReportError> {
52    let bytes = vtpm::get_report()?;
53    let Ok(hcl_report) = hcl::HclReport::new(bytes) else {
54        return Ok(false);
55    };
56    let is_snp = hcl_report.report_type() == hcl::ReportType::Snp;
57    Ok(is_snp)
58}
59
60#[cfg(feature = "verifier")]
61pub mod amd_kds;
62#[cfg(feature = "verifier")]
63pub mod certs;
64#[cfg(feature = "attester")]
65pub mod imds;
66pub mod report;