diff --git a/Cargo.toml b/Cargo.toml index d29c317b5..9da496370 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ env_logger = "0.10.0" hex = "0.4.3" hmac = "0.12.1" jwt-simple = "0.11" -kbs-types = "0.5.3" +kbs-types = "0.5.3" // TODO, update to pick new TEE type for IBM Secure Eexcution (SE) in https://github.com/virtee/kbs-types/blob/main/src/lib.rs#L24 lazy_static = "1.4.0" log = "0.4.14" openssl = "0.10" diff --git a/Makefile b/Makefile index 66ca66fe6..8e231b2bd 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,8 @@ else ifeq ($(TEE_PLATFORM), snp) KBC = cc_kbc_snp else ifeq ($(TEE_PLATFORM), az-snp-vtpm) KBC = cc_kbc_az_snp_vtpm +else ifeq ($(TEE_PLATFORM), se) + KBC = cc_kbc_se else ifeq ($(TEE_PLATFORM), all) LIBC = gnu KBC = cc_kbc_all_attesters diff --git a/README.md b/README.md index 1320ec93a..25a5db909 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ The `TEE_PLATFORM` parameter can be - `snp`: for AMD SEV-SNP - `amd`: for both AMD SEV(-ES) and AMD SEV-SNP - `az-snp-vtpm`: for AMD SEV-SNP with Azure vTPM +- `se`: for IBM Secure Execution (SE) by default, `kbs`/`sev` as a resource provider will be built in Confidential Data Hub. If you do not want enable any default except for only builtin `offline-fs-kbc`, you can build with `NO_RESOURCE_PROVIDER` flag set to `true`. diff --git a/attestation-agent/README.md b/attestation-agent/README.md index 3a016c2ba..b769351e4 100644 --- a/attestation-agent/README.md +++ b/attestation-agent/README.md @@ -126,6 +126,7 @@ CC KBC supports different kinds of hardware TEE attesters, now | az-snp-vtpm-attester| Azure SEV-SNP CVM | | az-tdx-vtpm-attester| Azure TDX CVM | | cca-attester | Arm Confidential Compute Architecture (CCA) | +| se-attester | IBM Secure Execution (SE) | To build cc kbc with all available attesters and install, use ```shell diff --git a/attestation-agent/app/Cargo.toml b/attestation-agent/app/Cargo.toml index 852aa62d8..bfc87d7c9 100644 --- a/attestation-agent/app/Cargo.toml +++ b/attestation-agent/app/Cargo.toml @@ -42,6 +42,7 @@ cc_kbc_sgx = ["cc_kbc", "attestation_agent/sgx-attester"] cc_kbc_az_snp_vtpm = ["cc_kbc", "attestation_agent/az-snp-vtpm-attester"] cc_kbc_az_tdx_vtpm = ["cc_kbc", "attestation_agent/az-tdx-vtpm-attester"] cc_kbc_snp = ["cc_kbc", "attestation_agent/snp-attester"] +cc_kbc_se = ["cc_kbc", "attestation_agent/se-attester"] eaa_kbc = ["attestation_agent/eaa_kbc"] offline_fs_kbc = ["attestation_agent/offline_fs_kbc"] diff --git a/attestation-agent/attester/Cargo.toml b/attestation-agent/attester/Cargo.toml index 592c1e88b..872170d02 100644 --- a/attestation-agent/attester/Cargo.toml +++ b/attestation-agent/attester/Cargo.toml @@ -54,6 +54,7 @@ all-attesters = [ "snp-attester", "csv-attester", "cca-attester", + "se-attester", ] # tsm-report enables a module that helps attesters to use Linux TSM_REPORTS for generating @@ -67,5 +68,6 @@ az-tdx-vtpm-attester = ["az-tdx-vtpm"] snp-attester = ["sev"] csv-attester = ["csv-rs", "codicon", "hyper", "hyper-tls", "tokio"] cca-attester = ["nix"] +se-attester = ["tempfile"] bin = ["tokio/rt", "tokio/macros", "all-attesters"] diff --git a/attestation-agent/attester/src/lib.rs b/attestation-agent/attester/src/lib.rs index 43eb7dfbc..7fa4afc82 100644 --- a/attestation-agent/attester/src/lib.rs +++ b/attestation-agent/attester/src/lib.rs @@ -30,6 +30,9 @@ pub mod snp; #[cfg(feature = "csv-attester")] pub mod csv; +#[cfg(feature = "se-attester")] +pub mod se; + #[cfg(feature = "tsm-report")] pub mod tsm_report; @@ -55,6 +58,8 @@ impl TryFrom for BoxedAttester { Tee::Snp => Box::::default(), #[cfg(feature = "csv-attester")] Tee::Csv => Box::::default(), + #[cfg(feature = "se-attester")] + Tee::Se => Box::::default(), _ => bail!("TEE is not supported!"), }; @@ -121,6 +126,11 @@ pub fn detect_tee_type() -> Tee { return Tee::Cca; } + #[cfg(feature = "se-attester")] + if se::detect_platform() { + return Some(Tee::Se); + } + log::warn!("No TEE platform detected. Sample Attester will be used."); Tee::Sample } diff --git a/attestation-agent/attester/src/se/mod.rs b/attestation-agent/attester/src/se/mod.rs new file mode 100644 index 000000000..e92b78570 --- /dev/null +++ b/attestation-agent/attester/src/se/mod.rs @@ -0,0 +1,73 @@ +// Copyright (C) Copyright IBM Corp. 2024 +// +// SPDX-License-Identifier: Apache-2.0 +// + +use super::Attester; +use anyhow::*; +use base64::prelude::*; +use serde::{Deserialize, Serialize}; +use crate::se::seattest::FakeSeAttest; +use crate::se::seattest::SeAttester; + +pub mod seattest; + +pub fn detect_platform() -> bool { + // TODO replace FakeSeAttest with real crate + let attester = FakeSeAttest::default(); + attester.is_se_guest() +} + +#[derive(Serialize, Deserialize)] +struct SeEvidence { + quote: Vec, +} + +#[derive(Debug, Default)] +pub struct SeAttester {} + +#[async_trait::async_trait] +impl Attester for SeAttester { + async fn get_evidence(&self, mut challenge: Vec) -> Result { + /// TODO replace FakeSeAttest with real crate + let attester = FakeSeAttest::default(); + + /// TODO, append attesttaion request in KBS payload + /// We want get challenge.extra_params from the input challenge, hashed string is not good. + let attestation-request-bin = Vec::new(); + let userdata = Vec::new(); + let evidence = attester.perform( + attestation-request-bin, + userdata + ).await?; + + Ok(BASE64_STANDARD.encode(evidence)) + } + + async fn extend_runtime_measurement( + &self, + _events: Vec>, + _register_index: Option, + ) -> Result<()> { + bail!("Unimplemented") + } + + async fn check_init_data(&self, _init_data: &[u8]) -> Result<()> { + bail!("Unimplemented"); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[ignore] + #[tokio::test] + async fn test_se_get_evidence() { + let attester = SeAttester::default(); + let report_data: Vec = vec![0; 64]; + + let evidence = attester.get_evidence(report_data).await; + assert!(evidence.is_ok()); + } +} diff --git a/attestation-agent/attester/src/se/seattest.rs b/attestation-agent/attester/src/se/seattest.rs new file mode 100644 index 000000000..da8c5d4dc --- /dev/null +++ b/attestation-agent/attester/src/se/seattest.rs @@ -0,0 +1,36 @@ +// Copyright (C) Copyright IBM Corp. 2024 +// +// SPDX-License-Identifier: Apache-2.0 +// + +use anyhow::*; +use async_trait; + +#[derive(Default)] +pub struct FakeSeAttest {} + +#[async_trait::async_trait] +pub trait SeAttester { + fn is_se_guest(&self) -> bool; + + async fn perform( + &self, + request: Vec, + userdata: Vec + ) -> Result>; +} + +#[async_trait::async_trait] +impl SeAttester for FakeSeAttest { + fn is_se_guest(&self) -> bool { + true + } + + async fn perform( + &self, + request: Vec, + userdata: Vec + ) -> Result> { + Result::Ok(Vec::new()) + } +} diff --git a/attestation-agent/kbc/Cargo.toml b/attestation-agent/kbc/Cargo.toml index 870196fb3..c53aebf9e 100644 --- a/attestation-agent/kbc/Cargo.toml +++ b/attestation-agent/kbc/Cargo.toml @@ -44,6 +44,7 @@ az-snp-vtpm-attester= ["kbs_protocol/az-snp-vtpm-attester"] az-tdx-vtpm-attester= ["kbs_protocol/az-tdx-vtpm-attester"] snp-attester = ["kbs_protocol/snp-attester"] cca-attester = ["kbs_protocol/cca-attester"] +se-attester = ["kbs_protocol/se-attester"] sample_kbc = [] eaa_kbc = ["foreign-types"] diff --git a/attestation-agent/kbs_protocol/Cargo.toml b/attestation-agent/kbs_protocol/Cargo.toml index eb2761d7f..5c7cc1ff1 100644 --- a/attestation-agent/kbs_protocol/Cargo.toml +++ b/attestation-agent/kbs_protocol/Cargo.toml @@ -52,6 +52,7 @@ az-tdx-vtpm-attester = ["attester/az-tdx-vtpm-attester"] snp-attester = ["attester/snp-attester"] csv-attester = ["attester/csv-attester"] cca-attester = ["attester/cca-attester"] +se-attester = ["attester/se-attester"] rust-crypto = ["reqwest/rustls-tls", "crypto/rust-crypto"] openssl = ["reqwest/native-tls-vendored", "crypto/openssl"] diff --git a/attestation-agent/kbs_protocol/src/client/rcar_client.rs b/attestation-agent/kbs_protocol/src/client/rcar_client.rs index e68076b0e..96bded86c 100644 --- a/attestation-agent/kbs_protocol/src/client/rcar_client.rs +++ b/attestation-agent/kbs_protocol/src/client/rcar_client.rs @@ -137,7 +137,9 @@ impl KbsClient> { let runtime_data = json!({ "tee-pubkey": tee_pubkey, "nonce": challenge.nonce, + "extra-params": challenge.extra_params, }); + // we want use challenge.extra_params in attester.get_evidence, so we can not hash runtime_data in generate_evidence(runtime_data) let runtime_data = serde_json::to_string(&runtime_data).context("serialize runtime data failed")?; let evidence = self.generate_evidence(runtime_data).await?; @@ -183,6 +185,7 @@ impl KbsClient> { let mut hasher = Sha384::new(); hasher.update(runtime_data); + // TODO, we don't want pass a hash sting but a json string here. let ehd = hasher.finalize().to_vec(); let tee_evidence = self diff --git a/attestation-agent/lib/Cargo.toml b/attestation-agent/lib/Cargo.toml index f3b5146a0..6e68607a7 100644 --- a/attestation-agent/lib/Cargo.toml +++ b/attestation-agent/lib/Cargo.toml @@ -41,6 +41,7 @@ sgx-attester = ["kbc/sgx-attester", "kbs_protocol/sgx-attester", "attester/sgx-a az-snp-vtpm-attester = ["kbc/az-snp-vtpm-attester", "kbs_protocol/az-snp-vtpm-attester", "attester/az-snp-vtpm-attester"] az-tdx-vtpm-attester = ["kbc/az-tdx-vtpm-attester", "kbs_protocol/az-tdx-vtpm-attester", "attester/az-tdx-vtpm-attester"] snp-attester = ["kbc/snp-attester", "kbs_protocol/snp-attester", "attester/snp-attester"] +se-attester = ["kbc/se-attester", "kbs_protocol/se-attester", "attester/se-attester"] sample_kbc = ["kbc/sample_kbc"] eaa_kbc = ["kbc/eaa_kbc"]