-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add experimental TDX attester/verifier crate (#35)
The az-snp-vtpm crate has been generalized into an az-cvm-vtpm workspace and extended to support attestation workflows on Azure TDX CVMs, which are in limited preview at the moment. The attestation workflow on TDX CVMs has a lot in common with the equivalent process on SEV-SNP CVMs, so in the future we'll probably want to consolidate both into a common az-cvm-vtpm crate. Until TDX CVMs on are generally available on Azure, we'll want to keep both crates seperate, as the offering is still subject to change. Signed-off-by: Magnus Kulke <[email protected]>
- Loading branch information
Showing
34 changed files
with
312 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
name: e2e | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
target | ||
arm/*.json | ||
Cargo.lock | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[workspace] | ||
members = [ | ||
"az-snp-vtpm", | ||
"az-tdx-vtpm", | ||
"az-snp-vtpm/example", | ||
] | ||
resolver = "2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# az-cvm-vtpm | ||
|
||
Attestation for Azure Confidential Virtual Machines | ||
|
||
## az-snp-vtpm | ||
|
||
Attestation Library for Azure AMD SEV-SNP Confidential Virtual Machines. | ||
|
||
## az-tdx-vtpm | ||
|
||
Attestation Library for Azure Intel TDX Confidential Virtual Machines (Limited Preview). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
az-snp-vtpm/example/Cargo.toml → az-cvm-vtpm/az-snp-vtpm/example/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[package] | ||
name = "example" | ||
name = "snp-example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
|
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[package] | ||
name = "az-tdx-vtpm" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[lib] | ||
path = "src/lib.rs" | ||
|
||
[[bin]] | ||
name = "tdx-vtpm" | ||
path = "src/main.rs" | ||
|
||
[dependencies] | ||
anyhow = "1.0.75" | ||
base64-url = "2.0.0" | ||
bincode = "1.3.3" | ||
jsonwebkey = { version = "0.3.5", features = ["pkcs-convert"] } | ||
memoffset = "0.9.0" | ||
serde = { version = "1.0.189", features = ["derive"] } | ||
serde-big-array = "0.5.1" | ||
serde_json = "1.0.107" | ||
sha2 = "0.10.8" | ||
tss-esapi = "7.4" | ||
ureq = { version = "2.6.2", default-features = false, features = ["json"] } | ||
az-snp-vtpm = { path = "../az-snp-vtpm" } | ||
sev = "1.2.0" | ||
thiserror = "1.0.49" | ||
openssl = { version = "0.10", optional = true } | ||
|
||
[features] | ||
default = ["attester", "verifier"] | ||
attester = [] | ||
verifier = ["az-snp-vtpm/verifier", "openssl"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# az-tdx-vtpm | ||
|
||
[![Rust](https://github.com/kinvolk/azure-cvm-tooling/actions/workflows/rust.yml/badge.svg)](https://github.com/kinvolk/azure-cvm-tooling/actions/workflows/rust.yml) | ||
|
||
> [!WARNING] | ||
> This library enables guest attestation and verification for [TDX CVMs on Azure](https://learn.microsoft.com/en-us/azure/confidential-computing/tdx-confidential-vm-overview). TDX CVMs are currently in limited preview and hence the library is considered experimental and subject to change. | ||
## Build & Install | ||
|
||
```bash | ||
cargo b --release -p az-tdx-vtpm | ||
scp ../target/release/tdx-vtpm azureuser@$CONFIDENTIAL_VM: | ||
``` | ||
|
||
## Run Binary | ||
|
||
On the TDX CVM, retrieve a TD Quote and write it to disk: | ||
|
||
```bash | ||
sudo ./tdx-vtpm | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
use serde::Deserialize; | ||
use thiserror::Error; | ||
|
||
const IMDS_QUOTE_URL: &str = "http://169.254.169.254/acc/tdquote"; | ||
|
||
#[derive(Error, Debug)] | ||
pub enum ImdsError { | ||
#[error("http error")] | ||
HttpError(#[from] Box<ureq::Error>), | ||
#[error("base64 error")] | ||
Base64Error(#[from] base64_url::base64::DecodeError), | ||
#[error("io error")] | ||
IoError(#[from] std::io::Error), | ||
} | ||
|
||
pub struct ReportBody { | ||
report: String, | ||
} | ||
|
||
impl ReportBody { | ||
pub fn new(report_bytes: &[u8]) -> Self { | ||
let report = base64_url::encode(report_bytes); | ||
Self { report } | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug, Deserialize)] | ||
struct QuoteResponse { | ||
quote: String, | ||
} | ||
|
||
pub fn get_td_quote(report_body: ReportBody) -> Result<Vec<u8>, ImdsError> { | ||
let response: QuoteResponse = ureq::post(IMDS_QUOTE_URL) | ||
.send_json(ureq::json!({ | ||
"report": report_body.report, | ||
})) | ||
.map_err(Box::new)? | ||
.into_json()?; | ||
let quote = base64_url::decode(&response.quote)?; | ||
Ok(quote) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
//! This library enables guest attestation flows for [TDX CVMs on Azure](https://learn.microsoft.com/en-us/azure/confidential-computing/tdx-confidential-vm-overview). TDX CVMs are currently in limited preview and hence the library is considered experimental and subject to change. | ||
//! # | ||
//! ```no_run | ||
//! use az_tdx_vtpm::{imds, hcl, vtpm}; | ||
//! use std::error::Error; | ||
//! | ||
//! fn main() -> Result<(), Box<dyn Error>> { | ||
//! let bytes = vtpm::get_report()?; | ||
//! let hcl_report = hcl::HclReport::new(bytes)?; | ||
//! let tdx_report_slice = hcl_report.tdx_report_slice(); | ||
//! let report_body = imds::ReportBody::new(tdx_report_slice); | ||
//! let td_quote_bytes = imds::get_td_quote(report_body)?; | ||
//! let hash = hcl_report.var_data_sha256(); | ||
//! println!("var_data hash: {:x?}", hash); | ||
//! std::fs::write("td_quote.bin", td_quote_bytes)?; | ||
//! Ok(()) | ||
//! } | ||
//! ``` | ||
|
||
pub use az_snp_vtpm::vtpm; | ||
|
||
pub mod hcl; | ||
pub mod imds; | ||
pub mod tdx; | ||
#[cfg(feature = "verifier")] | ||
pub mod verify; | ||
|
||
pub fn is_tdx_cvm() -> Result<bool, tss_esapi::Error> { | ||
let bytes = vtpm::get_report()?; | ||
let Ok(hcl_report) = hcl::HclReport::new(bytes) else { | ||
return Ok(false); | ||
}; | ||
let is_tdx = hcl_report.report_type() == hcl::ReportType::Tdx; | ||
Ok(is_tdx) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
use anyhow::Result; | ||
use az_tdx_vtpm::{hcl, imds, vtpm}; | ||
|
||
fn main() -> Result<()> { | ||
let bytes = vtpm::get_report()?; | ||
let hcl_report = hcl::HclReport::new(bytes)?; | ||
|
||
let hash = hcl_report.var_data_sha256(); | ||
println!("var_data hash: {:x?}", hash); | ||
|
||
let tdx_report_slice = hcl_report.tdx_report_slice(); | ||
let report_body = imds::ReportBody::new(tdx_report_slice); | ||
let td_quote_bytes = imds::get_td_quote(report_body)?; | ||
std::fs::write("td_quote.bin", td_quote_bytes)?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
use serde::{Deserialize, Serialize}; | ||
use serde_big_array::BigArray; | ||
|
||
const TDX_REPORT_DATA_LENGTH: usize = 64; | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub struct TdxReportMac { | ||
pub report_type: u8, | ||
pub report_sub_type: u8, | ||
pub report_version: u8, | ||
pub reserved_type_mbz: u8, | ||
pub reserved_mbz1: [u8; 12], | ||
pub cpu_svn: [u8; 16], | ||
#[serde(with = "BigArray")] | ||
pub tee_tcb_info_hash: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub tee_info_hash: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub report_data: [u8; TDX_REPORT_DATA_LENGTH], | ||
pub reserved_mbz2: [u8; 32], | ||
pub mac: [u8; 32], | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub struct TdxTeeTcbInfo { | ||
pub tee_valid: [u8; 8], | ||
pub tee_tcb_svn: [u8; 16], | ||
#[serde(with = "BigArray")] | ||
pub tee_mr_seam: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub tee_mr_seam_signer: [u8; 48], | ||
pub tee_attributes: [u8; 8], | ||
pub tee_tcb_svn2: [u8; 16], | ||
#[serde(with = "BigArray")] | ||
pub tee_reserved: [u8; 95], | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub struct TdxRtmr { | ||
#[serde(with = "BigArray")] | ||
pub register_data: [u8; 48], | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub struct TdxTdInfo { | ||
pub attributes: [u8; 8], | ||
pub xfam: [u8; 8], | ||
#[serde(with = "BigArray")] | ||
pub mrtd: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub mr_config_id: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub mr_owner: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub mr_owner_config: [u8; 48], | ||
pub rtrm: [TdxRtmr; 4], | ||
#[serde(with = "BigArray")] | ||
pub serv_td: [u8; 48], | ||
#[serde(with = "BigArray")] | ||
pub reserved_mbz: [u8; 64], | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub struct TdxVmReport { | ||
pub tdx_report_mac: TdxReportMac, | ||
pub tdx_tee_tcb_info: TdxTeeTcbInfo, | ||
pub tdx_reserved: [u8; 17], | ||
pub tdx_td_info: TdxTdInfo, | ||
} |
Oops, something went wrong.