From 22700d3ce9ae61ce983d0e73e601b8448c6e7e14 Mon Sep 17 00:00:00 2001 From: Mathias Brossard Date: Mon, 22 Apr 2024 11:27:24 -0500 Subject: [PATCH 1/2] AA: Update CcaAttester to use TSM Report ABI Signed-off-by: Mathias Brossard --- Cargo.lock | 1 - Makefile | 4 +- .../attestation-agent/Cargo.toml | 11 ++- attestation-agent/attester/Cargo.toml | 3 +- attestation-agent/attester/src/cca/mod.rs | 87 ++++--------------- attestation-agent/attester/src/lib.rs | 2 +- .../attester/src/tsm_report/mod.rs | 4 + 7 files changed, 38 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 987a5d68e..51385b931 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,7 +331,6 @@ dependencies = [ "hyper-tls 0.5.0", "kbs-types", "log", - "nix 0.29.0", "occlum_dcap", "rstest", "s390_pv", diff --git a/Makefile b/Makefile index 38e204972..b6bd23eb1 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,10 @@ else ifeq ($(TEE_PLATFORM), amd) else RESOURCE_PROVIDER = sev,kbs endif +else ifeq ($(TEE_PLATFORM), cca) + ATTESTER = cca-attester endif -# TODO: Add support for CCA and CSV +# TODO: Add support for CSV ifeq ($(ARCH), $(filter $(ARCH), s390x powerpc64le)) $(info s390x/powerpc64le only supports gnu) diff --git a/attestation-agent/attestation-agent/Cargo.toml b/attestation-agent/attestation-agent/Cargo.toml index 2836a2c1e..59b563d86 100644 --- a/attestation-agent/attestation-agent/Cargo.toml +++ b/attestation-agent/attestation-agent/Cargo.toml @@ -60,13 +60,22 @@ kbs = ["kbs_protocol/background_check", "token"] # CoCoAS Attestation Token coco_as = ["reqwest", "token"] -all-attesters = ["tdx-attester", "sgx-attester", "az-snp-vtpm-attester", "az-tdx-vtpm-attester", "snp-attester", "se-attester"] +all-attesters = [ + "tdx-attester", + "sgx-attester", + "az-snp-vtpm-attester", + "az-tdx-vtpm-attester", + "snp-attester", + "se-attester", + "cca-attester", +] tdx-attester = ["kbs_protocol?/tdx-attester", "attester/tdx-attester"] sgx-attester = ["kbs_protocol?/sgx-attester", "attester/sgx-attester"] az-snp-vtpm-attester = ["kbs_protocol?/az-snp-vtpm-attester", "attester/az-snp-vtpm-attester"] az-tdx-vtpm-attester = ["kbs_protocol?/az-tdx-vtpm-attester", "attester/az-tdx-vtpm-attester"] snp-attester = ["kbs_protocol?/snp-attester", "attester/snp-attester"] se-attester = ["kbs_protocol?/se-attester", "attester/se-attester"] +cca-attester = ["kbs_protocol?/cca-attester", "attester/cca-attester"] # Either `rust-crypto` or `openssl` should be enabled to work as underlying crypto module rust-crypto = ["kbs_protocol?/rust-crypto"] diff --git a/attestation-agent/attester/Cargo.toml b/attestation-agent/attester/Cargo.toml index 7e58a4290..173ba800c 100644 --- a/attestation-agent/attester/Cargo.toml +++ b/attestation-agent/attester/Cargo.toml @@ -15,7 +15,6 @@ clap = { workspace = true, features = ["derive"], optional = true } hex.workspace = true kbs-types.workspace = true log.workspace = true -nix = { workspace = true, optional = true, features = ["ioctl", "fs"] } occlum_dcap = { git = "https://github.com/occlum/occlum", tag = "v0.29.7", optional = true } pv = { version = "0.10.0", package = "s390_pv", optional = true } scroll = { version = "0.12.0", default-features = false, features = ["derive", "std"], optional = true } @@ -68,7 +67,7 @@ az-snp-vtpm-attester = ["az-snp-vtpm"] az-tdx-vtpm-attester = ["az-tdx-vtpm"] snp-attester = ["sev"] csv-attester = ["csv-rs", "codicon", "hyper", "hyper-tls", "tokio"] -cca-attester = ["nix"] +cca-attester = ["tsm-report"] se-attester = ["pv"] bin = ["tokio/rt", "tokio/macros", "clap"] diff --git a/attestation-agent/attester/src/cca/mod.rs b/attestation-agent/attester/src/cca/mod.rs index 289afd3d2..019fd8db0 100644 --- a/attestation-agent/attester/src/cca/mod.rs +++ b/attestation-agent/attester/src/cca/mod.rs @@ -1,26 +1,24 @@ -// Copyright (c) 2023 Arm Ltd. +// Copyright (c) 2023-2024 Arm Ltd. // // SPDX-License-Identifier: Apache-2.0 // +use super::tsm_report::*; use super::Attester; use anyhow::*; -use base64::Engine; -use nix::fcntl::{open, OFlag}; -use nix::sys::stat::Mode; -use nix::unistd::close; use serde::{Deserialize, Serialize}; -use std::path::Path; -const CCA_DEVICE_PATH: &str = "/dev/cca_attestation"; +const CCA_CHALLENGE_SIZE: usize = 64; -// NOTE: The path might be different when the CCA feature is public available, will come back to update the actual path if needed. pub fn detect_platform() -> bool { - Path::new(CCA_DEVICE_PATH).exists() + #[cfg(target_arch = "aarch64")] + return TsmReportPath::new(TsmReportProvider::Cca).is_ok(); + #[cfg(not(target_arch = "aarch64"))] + return false; } #[derive(Debug, Default)] -pub struct CCAAttester {} +pub struct CcaAttester {} #[derive(Serialize, Deserialize)] struct CcaEvidence { @@ -28,70 +26,23 @@ struct CcaEvidence { token: Vec, } -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct cca_ioctl_request { - challenge: [u8; 64], - token: [u8; 4096], - token_length: u64, -} - -nix::ioctl_readwrite!(cca_attestation_request, b'A', 1, cca_ioctl_request); - #[async_trait::async_trait] -impl Attester for CCAAttester { +impl Attester for CcaAttester { async fn get_evidence(&self, mut challenge: Vec) -> Result { - challenge.resize(64, 0); - let token = attestation(challenge)?; + if challenge.len() > CCA_CHALLENGE_SIZE { + bail!("CCA Attester: Challenge size must be {CCA_CHALLENGE_SIZE} or less."); + } + + challenge.resize(CCA_CHALLENGE_SIZE, 0); + let tsm = TsmReportPath::new(TsmReportProvider::Cca)?; + let token = tsm.attestation_report(TsmReportData::Cca(challenge))?; let evidence = CcaEvidence { token }; - let ev = serde_json::to_string(&evidence).context("Serialize CCA evidence failed")?; + let ev = + serde_json::to_string(&evidence).context("Serialization of CCA evidence failed")?; Ok(ev) } } -fn attestation(challenge: Vec) -> Result, Error> { - log::info!("cca_test::attestation started"); - - let challenge = challenge.as_slice().try_into()?; - - match open(CCA_DEVICE_PATH, OFlag::empty(), Mode::empty()) { - Result::Ok(f) => { - log::info!("cca_test::attestation opening attestation succeeded"); - let mut request = cca_ioctl_request { - challenge, - token: [0u8; 4096], - token_length: 0u64, - }; - - // this is unsafe code block since ioctl call `cca_attestation_request` has the unsafe signature. - match unsafe { cca_attestation_request(f, &mut request) } { - Result::Ok(c) => { - log::info!("cca_test::attestation ioctl call succeeded ({})", c); - log::info!( - "cca_test::attestation token is {} bytes long", - request.token_length - ); - let base64 = base64::engine::general_purpose::STANDARD - .encode(&request.token[0..(request.token_length as usize)]); - log::info!("cca_test::attestation token = {:x?}", base64); - let token = request.token[0..(request.token_length as usize)].to_vec(); - close(f)?; - Ok(token) - } - Err(e) => { - log::error!("cca_test::attestation ioctl failed! {}", e); - close(f)?; - bail!(e) - } - } - } - Err(err) => { - log::error!("cca_test::attestation opening attestation failed! {}", err); - bail!(err) - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -99,7 +50,7 @@ mod tests { #[ignore] #[tokio::test] async fn test_cca_get_evidence() { - let attester = CCAAttester::default(); + let attester = CcaAttester::default(); let report_data: Vec = vec![0; 48]; let evidence = attester.get_evidence(report_data).await; assert!(evidence.is_ok()); diff --git a/attestation-agent/attester/src/lib.rs b/attestation-agent/attester/src/lib.rs index 81d6c9d41..0c44e8bd1 100644 --- a/attestation-agent/attester/src/lib.rs +++ b/attestation-agent/attester/src/lib.rs @@ -53,7 +53,7 @@ impl TryFrom for BoxedAttester { #[cfg(feature = "az-tdx-vtpm-attester")] Tee::AzTdxVtpm => Box::::default(), #[cfg(feature = "cca-attester")] - Tee::Cca => Box::::default(), + Tee::Cca => Box::::default(), #[cfg(feature = "snp-attester")] Tee::Snp => Box::::default(), #[cfg(feature = "csv-attester")] diff --git a/attestation-agent/attester/src/tsm_report/mod.rs b/attestation-agent/attester/src/tsm_report/mod.rs index 0306296ff..5b0014965 100644 --- a/attestation-agent/attester/src/tsm_report/mod.rs +++ b/attestation-agent/attester/src/tsm_report/mod.rs @@ -33,6 +33,8 @@ pub enum TsmReportError { #[derive(PartialEq, Debug, EnumString)] pub enum TsmReportProvider { + #[strum(serialize = "arm_cca_guest\n")] + Cca, #[strum(serialize = "tdx_guest\n")] Tdx, #[strum(serialize = "sev_guest\n")] @@ -40,6 +42,7 @@ pub enum TsmReportProvider { } pub enum TsmReportData { + Cca(Vec), Tdx(Vec), Sev(u8, Vec), } @@ -85,6 +88,7 @@ impl TsmReportPath { let report_path = self.path.as_path(); let report_data = match provider_data { + TsmReportData::Cca(inblob) => inblob, TsmReportData::Tdx(inblob) => inblob, TsmReportData::Sev(privlevel, inblob) => { // TODO: untested From 2df059bdef3a2b726c20c85432aedcce28ec9d99 Mon Sep 17 00:00:00 2001 From: Mathias Brossard Date: Tue, 24 Sep 2024 10:48:37 -0500 Subject: [PATCH 2/2] Change error wording Co-authored-by: Xynnn_ Signed-off-by: Mathias Brossard --- attestation-agent/attester/src/cca/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attestation-agent/attester/src/cca/mod.rs b/attestation-agent/attester/src/cca/mod.rs index 019fd8db0..a5236ebaa 100644 --- a/attestation-agent/attester/src/cca/mod.rs +++ b/attestation-agent/attester/src/cca/mod.rs @@ -30,7 +30,7 @@ struct CcaEvidence { impl Attester for CcaAttester { async fn get_evidence(&self, mut challenge: Vec) -> Result { if challenge.len() > CCA_CHALLENGE_SIZE { - bail!("CCA Attester: Challenge size must be {CCA_CHALLENGE_SIZE} or less."); + bail!("CCA Attester: Challenge size must be {CCA_CHALLENGE_SIZE} bytes or less."); } challenge.resize(CCA_CHALLENGE_SIZE, 0);