From 362c641c1ff0f778226150bd6451b1fcfabdd123 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 6 Mar 2024 09:09:28 +0800 Subject: [PATCH 01/18] Verifier: Add IBM Secure Execution verifier driver framework Signed-off-by: Qi Feng Huo --- Cargo.toml | 2 +- attestation-service/README.md | 3 + .../attestation-service/src/lib.rs | 5 ++ attestation-service/verifier/Cargo.toml | 3 +- attestation-service/verifier/src/lib.rs | 26 +++++++- attestation-service/verifier/src/se/mod.rs | 62 +++++++++++++++++++ .../verifier/src/se/seattest.rs | 50 +++++++++++++++ kbs/README.md | 1 + kbs/src/api/src/attestation/mod.rs | 16 ++++- kbs/src/api/src/http/attest.rs | 16 ++++- kbs/src/api/src/session.rs | 19 +----- 11 files changed, 182 insertions(+), 21 deletions(-) create mode 100644 attestation-service/verifier/src/se/mod.rs create mode 100644 attestation-service/verifier/src/se/seattest.rs diff --git a/Cargo.toml b/Cargo.toml index c9fc7a21c..7e56286c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ clap = { version = "4", features = ["derive"] } config = "0.13.3" env_logger = "0.10.0" hex = "0.4.3" -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 jsonwebtoken = "9" log = "0.4.17" prost = "0.11.0" diff --git a/attestation-service/README.md b/attestation-service/README.md index 54caab037..5a81cb74b 100644 --- a/attestation-service/README.md +++ b/attestation-service/README.md @@ -13,6 +13,7 @@ Today, the AS can validate evidence from the following TEEs: - Hygon CSV - Intel TDX with vTPM on Azure - AMD SEV-SNP with vTPM on Azure +- IBM Secure Execution (SE) # Overview ``` @@ -102,6 +103,7 @@ Please refer to the individual verifiers for the specific format of the evidence - Azure TDX vTPM: [Evidence](./verifier/src/az_tdx_vtpm/mod.rs) - Arm CCA: [CcaEvidence](./verifier/src/cca/mod.rs) - Hygon CSV: [CsvEvidence](./verifier/src/csv/mod.rs) +- IBM Secure Execution (SE) [(SeEvidence)](./verifier/src/se/mod.rs) ## Output @@ -154,6 +156,7 @@ Supported Verifier Drivers: - `azsnpvtpm`: Verifier Driver for Azure vTPM based on SNP (Azure SNP vTPM) - `cca`: Verifier Driver for Confidential Compute Architecture (Arm CCA). - `csv`: Verifier Driver for China Security Virtualization (Hygon CSV). +- `se`: Verifier Driver for IBM Secure Execution (SE). ## Policy Engine diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index 6eff7b5c0..d7daeb739 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -239,6 +239,11 @@ impl AttestationService { pub async fn register_reference_value(&mut self, message: &str) -> Result<()> { self.rvps.verify_and_extract(message).await } + + pub async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + let verifier = verifier::to_verifier(&tee)?; + verifier.generate_challenge(nonce) + } } /// Get the expected init/runtime data and potential claims due to the given input diff --git a/attestation-service/verifier/Cargo.toml b/attestation-service/verifier/Cargo.toml index 17480f34e..14b7b3e0d 100644 --- a/attestation-service/verifier/Cargo.toml +++ b/attestation-service/verifier/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [features] default = [ "all-verifier" ] -all-verifier = [ "tdx-verifier", "sgx-verifier", "snp-verifier", "az-snp-vtpm-verifier", "az-tdx-vtpm-verifier", "csv-verifier", "cca-verifier" ] +all-verifier = [ "tdx-verifier", "sgx-verifier", "snp-verifier", "az-snp-vtpm-verifier", "az-tdx-vtpm-verifier", "csv-verifier", "cca-verifier", "se-verifier" ] tdx-verifier = [ "eventlog-rs", "scroll", "sgx-dcap-quoteverify-rs" ] sgx-verifier = [ "scroll", "sgx-dcap-quoteverify-rs" ] az-snp-vtpm-verifier = [ "az-snp-vtpm", "sev", "snp-verifier" ] @@ -13,6 +13,7 @@ az-tdx-vtpm-verifier = [ "az-tdx-vtpm", "openssl", "tdx-verifier" ] snp-verifier = [ "asn1-rs", "openssl", "sev", "x509-parser" ] csv-verifier = [ "openssl", "csv-rs", "codicon" ] cca-verifier = [ "ear", "jsonwebtoken", "veraison-apiclient" ] +se-verifier = [ "openssl" ] [dependencies] anyhow.workspace = true diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index 20c7291a2..cd22ac336 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use anyhow::*; use async_trait::async_trait; -use kbs_types::Tee; +use kbs_types::{Challenge, Tee}; use log::warn; pub mod sample; @@ -28,6 +28,9 @@ pub mod csv; #[cfg(feature = "cca-verifier")] pub mod cca; +#[cfg(feature = "se-verifier")] +pub mod se; + pub fn to_verifier(tee: &Tee) -> Result> { match tee { Tee::Sev => todo!(), @@ -99,6 +102,17 @@ pub fn to_verifier(tee: &Tee) -> Result> { } } } + + Tee::Se => { + cfg_if::cfg_if! { + if #[cfg(feature = "se-verifier")] { + Ok(Box::::default() as Box) + } else { + bail!("feature `se-verifier` is not enabled for `verifier` crate.") + } + } + } + } } @@ -152,6 +166,16 @@ pub trait Verifier { expected_report_data: &ReportData, expected_init_data_hash: &InitDataHash, ) -> Result; + + async fn generate_challenge( + &self, + nonce: &str) -> Result { + + Result::Ok(Challenge { + nonce, + extra_params: String::new(), + }) + } } /// Padding or truncate the given data slice to the given `len` bytes. diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs new file mode 100644 index 000000000..0e42ca9e2 --- /dev/null +++ b/attestation-service/verifier/src/se/mod.rs @@ -0,0 +1,62 @@ +// Copyright (C) Copyright IBM Corp. 2024 +// +// SPDX-License-Identifier: Apache-2.0 +// + +use async_trait::async_trait; +use anyhow::anyhow; +use base64::prelude::*; +use kbs_types::{Challenge, Tee}; +use crate::{InitDataHash, ReportData}; +use super::{TeeEvidenceParsedClaim, Verifier}; +use crate::se::seattest::FakeSeAttest; +use crate::se::seattest::SeFakeVerifier; + +pub mod seattest; + +#[derive(Debug, Default)] +pub struct SeVerifier {} + +#[async_trait] +impl Verifier for SeVerifier { + async fn evaluate( + &self, + evidence: &[u8], + expected_report_data: &ReportData, + expected_init_data_hash: &InitDataHash, + ) -> Result { + verify_evidence(evidence, expected_report_data, expected_init_data_hash) + .await + .map_err(|e| anyhow!("Se Verifier: {:?}", e)) + } + + async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + /// TODO replace FakeSeAttest with real crate + let attester = FakeSeAttest::default(); + + let hkds: Vec = vec![String::new(); 2]; + let certk = String::new(); + let signk = String::new(); + let arpk = String::new(); + Result::Ok(Challenge { + nonce, + extra_params: BASE64_STANDARD.encode(attester.create(hkds, certk, signk, arpk)), + }) + } +} + +async fn verify_evidence( + evidence: &[u8], + expected_report_data: &ReportData<'_>, + expected_init_data_hash: &InitDataHash<'_>, +) -> Result { + /// TODO replace FakeSeAttest with real crate + let attester = FakeSeAttest::default(); + + let arpk = String::new(); + let hdr = String::new(); + let se = attester.verify(evidence, arpk, hdr); + + let v = serde_json::to_value(se?).context("build json value from the se evidence")?; + Ok(v as TeeEvidenceParsedClaim) +} \ No newline at end of file diff --git a/attestation-service/verifier/src/se/seattest.rs b/attestation-service/verifier/src/se/seattest.rs new file mode 100644 index 000000000..2830f5cd2 --- /dev/null +++ b/attestation-service/verifier/src/se/seattest.rs @@ -0,0 +1,50 @@ +// 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 SeFakeVerifier { + async fn create( + &self, + hkdFiles: Vec, + certFile: &String, + signingFile: &String, + arpkFile: &String + ) -> Result>; + + async fn verify( + &self, + evidence: Vec, + arpkFile: &String, + hdr: Vec + ) -> Result>; +} + +#[async_trait::async_trait] +impl SeFakeVerifier for FakeSeAttest { + async fn create( + &self, + hkdFiles: Vec, + certFile: &String, + signingFile: &String, + arpkFile: &String + ) -> Result> { + Result::Ok(Vec::new()) + } + + async fn verify( + &self, + evidence: Vec, + arpkFile: &String, + hdr: Vec + ) -> Result> { + Result::Ok(Vec::new()) + } +} \ No newline at end of file diff --git a/kbs/README.md b/kbs/README.md index 96b0040a7..dadb2d5dc 100644 --- a/kbs/README.md +++ b/kbs/README.md @@ -13,6 +13,7 @@ In conjunction with the AS or Intel Trust Authority (ITA), the KBS supports the - Intel SGX - ARM CCA - Hygon CSV +- IBM Secure Execution (SE) # Deployment Configurations diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index db7fc4926..c37d3d64c 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -10,7 +10,7 @@ use attestation_service::config::Config as AsConfig; use coco::grpc::*; #[cfg(feature = "intel-trust-authority-as")] use intel_trust_authority::*; -use kbs_types::Tee; +use kbs_types::{Challenge, Request, Tee}; #[cfg(feature = "coco-as")] #[allow(missing_docs)] @@ -32,6 +32,9 @@ pub trait Attest: Send + Sync { /// Verify Attestation Evidence /// Return Attestation Results Token async fn verify(&self, tee: Tee, nonce: &str, attestation: &str) -> Result; + + /// generate the challenge payload to pass to attester based on Tee and nonce + async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result; } /// Attestation Service @@ -89,4 +92,15 @@ impl AttestationService { AttestationService::IntelTA(inner) => inner.set_policy(input).await, } } + + pub async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + match self { + #[cfg(feature = "coco-as-grpc")] + AttestationService::CoCoASgRPC(inner) => inner.generate_challenge(tee, nonce).await, + #[cfg(any(feature = "coco-as-builtin", feature = "coco-as-builtin-no-verifier"))] + AttestationService::CoCoASBuiltIn(inner) => inner.generate_challenge(tee, nonce, attestation).await, + #[cfg(feature = "intel-trust-authority-as")] + AttestationService::IntelTA(inner) => inner.generate_challenge(tee, nonce).await, + } + } } diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index 879595641..b46f3b08c 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -10,17 +10,31 @@ use anyhow::anyhow; use base64::engine::general_purpose::URL_SAFE_NO_PAD; use base64::Engine; use log::{error, info}; +use rand::{thread_rng, Rng}; use serde_json::json; +fn nonce() -> Result { + let mut nonce: Vec = vec![0; 32]; + + thread_rng() + .try_fill(&mut nonce[..]) + .map_err(anyhow::Error::from)?; + + Ok(STANDARD.encode(&nonce)) +} + /// POST /auth pub(crate) async fn auth( request: web::Json, map: web::Data, timeout: web::Data, + attestation_service: web::Data>, ) -> Result { info!("request: {:?}", &request); - let session = SessionStatus::auth(request.0, **timeout) + let challenge = attestation_service.generate_challenge(nonce()?); + + let session = SessionStatus::auth(request.0, **timeout, challenge) .map_err(|e| Error::FailedAuthentication(format!("Session: {e}")))?; let response = HttpResponse::Ok() diff --git a/kbs/src/api/src/session.rs b/kbs/src/api/src/session.rs index 67943a75d..accc59a71 100644 --- a/kbs/src/api/src/session.rs +++ b/kbs/src/api/src/session.rs @@ -11,22 +11,12 @@ use base64::engine::general_purpose::STANDARD; use base64::Engine; use kbs_types::{Challenge, Request}; use log::warn; -use rand::{thread_rng, Rng}; +// use rand::{thread_rng, Rng}; use semver::Version; use uuid::Uuid; pub(crate) static KBS_SESSION_ID: &str = "kbs-session-id"; -fn nonce() -> Result { - let mut nonce: Vec = vec![0; 32]; - - thread_rng() - .try_fill(&mut nonce[..]) - .map_err(anyhow::Error::from)?; - - Ok(STANDARD.encode(&nonce)) -} - /// Finite State Machine model for RCAR handshake pub(crate) enum SessionStatus { Authed { @@ -63,7 +53,7 @@ macro_rules! impl_member { } impl SessionStatus { - pub fn auth(request: Request, timeout: i64) -> Result { + pub fn auth(request: Request, timeout: i64, challenge: &Challenge) -> Result { let version = Version::parse(&request.version).map_err(anyhow::Error::from)?; if !crate::VERSION_REQ.matches(&version) { bail!("Invalid Request version {}", request.version); @@ -74,10 +64,7 @@ impl SessionStatus { Ok(Self::Authed { request, - challenge: Challenge { - nonce: nonce()?, - extra_params: String::new(), - }, + challenge, id, timeout, }) From abdf68f0c2e032611de16fe89f48c05c0827efa2 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 6 Mar 2024 15:23:49 +0800 Subject: [PATCH 02/18] Verifier: IBM SE add generate_challenge_extra_params Signed-off-by: Qi Feng Huo --- Cargo.lock | 21 ++++++--- Cargo.toml | 2 +- .../attestation-service/Cargo.toml | 1 + .../attestation-service/src/bin/grpc/mod.rs | 1 + .../src/bin/restful/mod.rs | 1 + .../attestation-service/src/lib.rs | 4 +- attestation-service/docs/parsed_claims.md | 3 ++ attestation-service/protos/attestation.proto | 1 + attestation-service/verifier/src/lib.rs | 14 +++--- attestation-service/verifier/src/se/mod.rs | 43 +++++++++++-------- .../verifier/src/se/seattest.rs | 36 ++++++++-------- kbs/src/api/src/attestation/coco/builtin.rs | 8 ++++ kbs/src/api/src/attestation/coco/grpc.rs | 5 +++ .../attestation/intel_trust_authority/mod.rs | 4 ++ kbs/src/api/src/attestation/mod.rs | 16 ++++--- kbs/src/api/src/http/attest.rs | 21 +++------ kbs/src/api/src/session.rs | 19 ++++++-- 17 files changed, 123 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4029bcd15..49db2ea53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,7 @@ dependencies = [ "env_logger 0.10.2", "jsonwebtoken", "jwt-simple", - "kbs-types", + "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", "lazy_static", "log", "mobc", @@ -535,7 +535,7 @@ dependencies = [ "env_logger 0.10.2", "futures", "hex", - "kbs-types", + "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", "lazy_static", "log", "openssl", @@ -575,7 +575,7 @@ dependencies = [ "csv-rs", "hyper", "hyper-tls", - "kbs-types", + "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "log", "nix", "occlum_dcap", @@ -1283,7 +1283,7 @@ dependencies = [ "anyhow", "base64 0.21.7", "ctr", - "kbs-types", + "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand", "rsa 0.9.6", "serde", @@ -2429,6 +2429,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kbs-types" +version = "0.5.3" +source = "git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se#681d9ea3bea0e4465d67f004234f628dbced1007" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "kbs_protocol" version = "0.1.0" @@ -2440,7 +2449,7 @@ dependencies = [ "base64 0.21.7", "crypto", "jwt-simple", - "kbs-types", + "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "log", "reqwest", "resource_uri", @@ -5276,7 +5285,7 @@ dependencies = [ "eventlog-rs", "hex", "jsonwebtoken", - "kbs-types", + "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", "log", "openssl", "rstest", diff --git a/Cargo.toml b/Cargo.toml index 7e56286c9..c8d8797e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ clap = { version = "4", features = ["derive"] } config = "0.13.3" env_logger = "0.10.0" hex = "0.4.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 +kbs-types = { git = "https://github.com/huoqifeng/kbs-types.git", branch = "s390x-se" } jsonwebtoken = "9" log = "0.4.17" prost = "0.11.0" diff --git a/attestation-service/attestation-service/Cargo.toml b/attestation-service/attestation-service/Cargo.toml index d3bda03d3..9717dc19f 100644 --- a/attestation-service/attestation-service/Cargo.toml +++ b/attestation-service/attestation-service/Cargo.toml @@ -13,6 +13,7 @@ az-tdx-vtpm-verifier = [ "verifier/az-tdx-vtpm-verifier" ] snp-verifier = [ "verifier/snp-verifier" ] csv-verifier = [ "verifier/csv-verifier" ] cca-verifier = [ "verifier/cca-verifier" ] +se-verifier = [ "verifier/se-verifier" ] # Only for testing and CI rvps-builtin = [ "reference-value-provider-service" ] diff --git a/attestation-service/attestation-service/src/bin/grpc/mod.rs b/attestation-service/attestation-service/src/bin/grpc/mod.rs index cd22fa761..722475d98 100644 --- a/attestation-service/attestation-service/src/bin/grpc/mod.rs +++ b/attestation-service/attestation-service/src/bin/grpc/mod.rs @@ -37,6 +37,7 @@ fn to_kbs_tee(tee: GrpcTee) -> Tee { GrpcTee::AzSnpVtpm => Tee::AzSnpVtpm, GrpcTee::Cca => Tee::Cca, GrpcTee::AzTdxVtpm => Tee::AzTdxVtpm, + GrpcTee::Se => Tee::Se, } } diff --git a/attestation-service/attestation-service/src/bin/restful/mod.rs b/attestation-service/attestation-service/src/bin/restful/mod.rs index 20d840ee3..0f25202b7 100644 --- a/attestation-service/attestation-service/src/bin/restful/mod.rs +++ b/attestation-service/attestation-service/src/bin/restful/mod.rs @@ -62,6 +62,7 @@ fn to_tee(tee: &str) -> anyhow::Result { "csv" => Tee::Csv, "sample" => Tee::Sample, "aztdxvtpm" => Tee::AzTdxVtpm, + "se" => Tee::Se, other => bail!("tee `{other} not supported`"), }; diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index d7daeb739..901abed2e 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -240,9 +240,9 @@ impl AttestationService { self.rvps.verify_and_extract(message).await } - pub async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + pub async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { let verifier = verifier::to_verifier(&tee)?; - verifier.generate_challenge(nonce) + verifier.generate_challenge_extra_params().await } } diff --git a/attestation-service/docs/parsed_claims.md b/attestation-service/docs/parsed_claims.md index b783fcfdb..72d7c25b5 100644 --- a/attestation-service/docs/parsed_claims.md +++ b/attestation-service/docs/parsed_claims.md @@ -88,3 +88,6 @@ The claim inherit the fields from the SEV-SNP claim with and additional `tpm` hi - `tpm.pcr{01,..,n}`: SHA256 PCR registers for the TEE's vTPM quote. Note: The TD Report and TD Quote are fetched during early boot in this TEE. Kernel, Initrd and rootfs are measured into the vTPM's registers. + +## IBM Secure Execution (SE) +TBD \ No newline at end of file diff --git a/attestation-service/protos/attestation.proto b/attestation-service/protos/attestation.proto index 405aad923..fb33a057c 100644 --- a/attestation-service/protos/attestation.proto +++ b/attestation-service/protos/attestation.proto @@ -12,6 +12,7 @@ enum Tee { CSV = 6; CCA = 7; AzTdxVtpm = 8; + Se = 9; } message AttestationRequest { diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index cd22ac336..d5618d47a 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use anyhow::*; use async_trait::async_trait; -use kbs_types::{Challenge, Tee}; +use kbs_types::Tee; use log::warn; pub mod sample; @@ -106,7 +106,7 @@ pub fn to_verifier(tee: &Tee) -> Result> { Tee::Se => { cfg_if::cfg_if! { if #[cfg(feature = "se-verifier")] { - Ok(Box::::default() as Box) + Ok(Box::::default() as Box) } else { bail!("feature `se-verifier` is not enabled for `verifier` crate.") } @@ -167,14 +167,10 @@ pub trait Verifier { expected_init_data_hash: &InitDataHash, ) -> Result; - async fn generate_challenge( + async fn generate_challenge_extra_params( &self, - nonce: &str) -> Result { - - Result::Ok(Challenge { - nonce, - extra_params: String::new(), - }) + ) -> Result { + Ok(String::new()) } } diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 0e42ca9e2..87223b9da 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -3,12 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 // +use super::*; use async_trait::async_trait; use anyhow::anyhow; use base64::prelude::*; -use kbs_types::{Challenge, Tee}; use crate::{InitDataHash, ReportData}; -use super::{TeeEvidenceParsedClaim, Verifier}; use crate::se::seattest::FakeSeAttest; use crate::se::seattest::SeFakeVerifier; @@ -25,38 +24,46 @@ impl Verifier for SeVerifier { expected_report_data: &ReportData, expected_init_data_hash: &InitDataHash, ) -> Result { + verify_evidence(evidence, expected_report_data, expected_init_data_hash) .await .map_err(|e| anyhow!("Se Verifier: {:?}", e)) } - async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { - /// TODO replace FakeSeAttest with real crate + async fn generate_challenge_extra_params( + &self, + ) -> Result { + + // TODO replace FakeSeAttest with real crate let attester = FakeSeAttest::default(); let hkds: Vec = vec![String::new(); 2]; - let certk = String::new(); - let signk = String::new(); - let arpk = String::new(); - Result::Ok(Challenge { - nonce, - extra_params: BASE64_STANDARD.encode(attester.create(hkds, certk, signk, arpk)), - }) + let certk = "cert_file_path"; + let signk = "sign_file_path"; + let arpk = "arpk_file_path"; + + let extra_params = attester.create(hkds, certk, signk, arpk) + .await + .context("Create SE attestation request failed: {:?}")?; + + Ok(BASE64_STANDARD.encode(extra_params)) } } async fn verify_evidence( evidence: &[u8], - expected_report_data: &ReportData<'_>, - expected_init_data_hash: &InitDataHash<'_>, + _expected_report_data: &ReportData<'_>, + _expected_init_data_hash: &InitDataHash<'_>, ) -> Result { - /// TODO replace FakeSeAttest with real crate + // TODO replace FakeSeAttest with real crate let attester = FakeSeAttest::default(); - let arpk = String::new(); - let hdr = String::new(); - let se = attester.verify(evidence, arpk, hdr); + let arpk = "arpk_file_path"; + let hdr = "hdr_file_path"; + let se = attester.verify(evidence, arpk, hdr) + .await + .context("Verify SE attestation evidence failed: {:?}")?; - let v = serde_json::to_value(se?).context("build json value from the se evidence")?; + let v = serde_json::to_value(se).context("build json value from the se evidence")?; Ok(v as TeeEvidenceParsedClaim) } \ No newline at end of file diff --git a/attestation-service/verifier/src/se/seattest.rs b/attestation-service/verifier/src/se/seattest.rs index 2830f5cd2..113cd6938 100644 --- a/attestation-service/verifier/src/se/seattest.rs +++ b/attestation-service/verifier/src/se/seattest.rs @@ -11,39 +11,39 @@ pub struct FakeSeAttest {} #[async_trait::async_trait] pub trait SeFakeVerifier { - async fn create( + async fn create<'a, 'b, 'c>( &self, - hkdFiles: Vec, - certFile: &String, - signingFile: &String, - arpkFile: &String + _hkd_files: Vec, + _cert_file: &'a str, + _signing_file: &'b str, + _arpk_file: &'c str, ) -> Result>; - async fn verify( + async fn verify<'a, 'b>( &self, - evidence: Vec, - arpkFile: &String, - hdr: Vec + _evidence: &[u8], + _arpk_file: &'a str, + _hdr_file: &'b str, ) -> Result>; } #[async_trait::async_trait] impl SeFakeVerifier for FakeSeAttest { - async fn create( + async fn create<'a, 'b, 'c>( &self, - hkdFiles: Vec, - certFile: &String, - signingFile: &String, - arpkFile: &String + _hkd_files: Vec, + _cert_file: &'a str, + _signing_file: &'b str, + _arpk_file: &'c str, ) -> Result> { Result::Ok(Vec::new()) } - async fn verify( + async fn verify<'a, 'b>( &self, - evidence: Vec, - arpkFile: &String, - hdr: Vec + _evidence: &[u8], + _arpk_file: &'a str, + _hkd_files: &'b str, ) -> Result> { Result::Ok(Vec::new()) } diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index 3f8eb4bac..b9d017f60 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -45,6 +45,14 @@ impl Attest for BuiltInCoCoAs { ) .await } + + async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { + self.inner + .read() + .await + .generate_challenge_extra_params(tee) + .await + } } impl BuiltInCoCoAs { diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 174d76b49..e478df8d3 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -39,6 +39,7 @@ fn to_grpc_tee(tee: Tee) -> GrpcTee { Tee::Sgx => GrpcTee::Sgx, Tee::Snp => GrpcTee::Snp, Tee::Tdx => GrpcTee::Tdx, + Tee::Se => GrpcTee::Se, } } @@ -125,6 +126,10 @@ impl Attest for GrpcClientPool { Ok(token) } + + async fn generate_challenge_extra_params(&self, _tee: Tee) -> Result { + Ok(String::new()) + } } pub struct GrpcManager { diff --git a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs index f77d51a0a..dc9012419 100644 --- a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs +++ b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs @@ -122,6 +122,10 @@ impl Attest for IntelTrustAuthority { Ok(resp_data.token.clone()) } + + async fn generate_challenge_extra_params(&self, _tee: Tee) -> Result { + Ok(String::new()) + } } impl IntelTrustAuthority { diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index c37d3d64c..e85e21915 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -10,7 +10,7 @@ use attestation_service::config::Config as AsConfig; use coco::grpc::*; #[cfg(feature = "intel-trust-authority-as")] use intel_trust_authority::*; -use kbs_types::{Challenge, Request, Tee}; +use kbs_types::Tee; #[cfg(feature = "coco-as")] #[allow(missing_docs)] @@ -34,7 +34,7 @@ pub trait Attest: Send + Sync { async fn verify(&self, tee: Tee, nonce: &str, attestation: &str) -> Result; /// generate the challenge payload to pass to attester based on Tee and nonce - async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result; + async fn generate_challenge_extra_params(&self, tee: Tee) -> Result; } /// Attestation Service @@ -93,14 +93,18 @@ impl AttestationService { } } - pub async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + pub async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { match self { #[cfg(feature = "coco-as-grpc")] - AttestationService::CoCoASgRPC(inner) => inner.generate_challenge(tee, nonce).await, + AttestationService::CoCoASgRPC(inner) => { + inner.generate_challenge_extra_params(tee).await + } #[cfg(any(feature = "coco-as-builtin", feature = "coco-as-builtin-no-verifier"))] - AttestationService::CoCoASBuiltIn(inner) => inner.generate_challenge(tee, nonce, attestation).await, + AttestationService::CoCoASBuiltIn(inner) => { + inner.generate_challenge_extra_params(tee).await + } #[cfg(feature = "intel-trust-authority-as")] - AttestationService::IntelTA(inner) => inner.generate_challenge(tee, nonce).await, + AttestationService::IntelTA(inner) => inner.generate_challenge_extra_params(tee).await, } } } diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index b46f3b08c..6f2c9b015 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -7,22 +7,12 @@ use crate::{raise_error, session::SessionStatus}; use super::*; use anyhow::anyhow; -use base64::engine::general_purpose::URL_SAFE_NO_PAD; +use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}; use base64::Engine; +use kbs_types::Challenge; use log::{error, info}; -use rand::{thread_rng, Rng}; use serde_json::json; -fn nonce() -> Result { - let mut nonce: Vec = vec![0; 32]; - - thread_rng() - .try_fill(&mut nonce[..]) - .map_err(anyhow::Error::from)?; - - Ok(STANDARD.encode(&nonce)) -} - /// POST /auth pub(crate) async fn auth( request: web::Json, @@ -32,9 +22,12 @@ pub(crate) async fn auth( ) -> Result { info!("request: {:?}", &request); - let challenge = attestation_service.generate_challenge(nonce()?); + let extra_params = attestation_service + .generate_challenge_extra_params(request.tee) + .await + .unwrap(); - let session = SessionStatus::auth(request.0, **timeout, challenge) + let session = SessionStatus::auth(request.0, **timeout, extra_params) .map_err(|e| Error::FailedAuthentication(format!("Session: {e}")))?; let response = HttpResponse::Ok() diff --git a/kbs/src/api/src/session.rs b/kbs/src/api/src/session.rs index accc59a71..41c1997df 100644 --- a/kbs/src/api/src/session.rs +++ b/kbs/src/api/src/session.rs @@ -11,12 +11,22 @@ use base64::engine::general_purpose::STANDARD; use base64::Engine; use kbs_types::{Challenge, Request}; use log::warn; -// use rand::{thread_rng, Rng}; +use rand::{thread_rng, Rng}; use semver::Version; use uuid::Uuid; pub(crate) static KBS_SESSION_ID: &str = "kbs-session-id"; +fn nonce() -> Result { + let mut nonce: Vec = vec![0; 32]; + + thread_rng() + .try_fill(&mut nonce[..]) + .map_err(anyhow::Error::from)?; + + Ok(STANDARD.encode(&nonce)) +} + /// Finite State Machine model for RCAR handshake pub(crate) enum SessionStatus { Authed { @@ -53,7 +63,7 @@ macro_rules! impl_member { } impl SessionStatus { - pub fn auth(request: Request, timeout: i64, challenge: &Challenge) -> Result { + pub fn auth(request: Request, timeout: i64, extra_params: String) -> Result { let version = Version::parse(&request.version).map_err(anyhow::Error::from)?; if !crate::VERSION_REQ.matches(&version) { bail!("Invalid Request version {}", request.version); @@ -64,7 +74,10 @@ impl SessionStatus { Ok(Self::Authed { request, - challenge, + challenge: Challenge { + nonce: nonce()?, + extra_params, + }, id, timeout, }) From 2c44b6f46b0da2fe10715122bdb0d826554c2e4f Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Mon, 11 Mar 2024 14:49:09 +0800 Subject: [PATCH 03/18] Verifier: IBM SE add dummy claims Signed-off-by: Qi Feng Huo --- attestation-service/verifier/src/se/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 87223b9da..9055104f4 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -7,6 +7,7 @@ use super::*; use async_trait::async_trait; use anyhow::anyhow; use base64::prelude::*; +use serde_json::json; use crate::{InitDataHash, ReportData}; use crate::se::seattest::FakeSeAttest; use crate::se::seattest::SeFakeVerifier; @@ -64,6 +65,11 @@ async fn verify_evidence( .await .context("Verify SE attestation evidence failed: {:?}")?; - let v = serde_json::to_value(se).context("build json value from the se evidence")?; - Ok(v as TeeEvidenceParsedClaim) + let claims_map = json!({ + "serial_number": format!("{}", "SE-ID"), + "measurement": format!("{}", BASE64_STANDARD.encode(se.clone())), + "report_data": format!("{}", BASE64_STANDARD.encode(se.clone())), + }); + + Ok(claims_map as TeeEvidenceParsedClaim) } \ No newline at end of file From ada0e756b1d20157b361d15be64e70309778aa25 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 13 Mar 2024 15:50:53 +0800 Subject: [PATCH 04/18] Verifier: add IBM SE create verify dummy code Signed-off-by: Qi Feng Huo --- attestation-service/verifier/src/se/seattest.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/attestation-service/verifier/src/se/seattest.rs b/attestation-service/verifier/src/se/seattest.rs index 113cd6938..3a7f354a9 100644 --- a/attestation-service/verifier/src/se/seattest.rs +++ b/attestation-service/verifier/src/se/seattest.rs @@ -36,7 +36,7 @@ impl SeFakeVerifier for FakeSeAttest { _signing_file: &'b str, _arpk_file: &'c str, ) -> Result> { - Result::Ok(Vec::new()) + Result::Ok("test".as_bytes().to_vec()) } async fn verify<'a, 'b>( @@ -45,6 +45,6 @@ impl SeFakeVerifier for FakeSeAttest { _arpk_file: &'a str, _hkd_files: &'b str, ) -> Result> { - Result::Ok(Vec::new()) + Result::Ok("test".as_bytes().to_vec()) } } \ No newline at end of file From c0b406138e2db0938797d8c9ade14c000140a478 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Fri, 15 Mar 2024 09:36:43 +0800 Subject: [PATCH 05/18] Verifier: IBM SE make both se and sample tee test pass Signed-off-by: Qi Feng Huo --- Cargo.lock | 33 ++++++++------------- kbs/docs/kbs.yaml | 6 ++++ kbs/docs/kbs_attestation_protocol.md | 7 +++++ kbs/src/api/src/attestation/coco/builtin.rs | 2 +- kbs/src/api/src/attestation/coco/grpc.rs | 2 +- kbs/tools/attest.json | 3 +- kbs/tools/client/Cargo.toml | 2 +- 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49db2ea53..0da853d90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,7 @@ dependencies = [ "env_logger 0.10.2", "jsonwebtoken", "jwt-simple", - "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", + "kbs-types", "lazy_static", "log", "mobc", @@ -535,7 +535,7 @@ dependencies = [ "env_logger 0.10.2", "futures", "hex", - "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", + "kbs-types", "lazy_static", "log", "openssl", @@ -564,7 +564,7 @@ dependencies = [ [[package]] name = "attester" version = "0.1.0" -source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" dependencies = [ "anyhow", "async-trait", @@ -575,7 +575,7 @@ dependencies = [ "csv-rs", "hyper", "hyper-tls", - "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "kbs-types", "log", "nix", "occlum_dcap", @@ -583,6 +583,7 @@ dependencies = [ "serde", "serde_json", "sev", + "sha2", "strum", "tdx-attest-rs", "tempfile", @@ -1277,13 +1278,13 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto" version = "0.1.0" -source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" dependencies = [ "aes-gcm", "anyhow", "base64 0.21.7", "ctr", - "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "kbs-types", "rand", "rsa 0.9.6", "serde", @@ -2422,17 +2423,7 @@ dependencies = [ [[package]] name = "kbs-types" version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f4b0642769e12f56cfc646d8be13668ed48d3caed0e99efb161c407f3ec532" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "kbs-types" -version = "0.5.3" -source = "git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se#681d9ea3bea0e4465d67f004234f628dbced1007" +source = "git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se#271ef4bac54035fb25fa44b24e5bbca844cd057c" dependencies = [ "serde", "serde_json", @@ -2441,7 +2432,7 @@ dependencies = [ [[package]] name = "kbs_protocol" version = "0.1.0" -source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" dependencies = [ "anyhow", "async-trait", @@ -2449,7 +2440,7 @@ dependencies = [ "base64 0.21.7", "crypto", "jwt-simple", - "kbs-types 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "kbs-types", "log", "reqwest", "resource_uri", @@ -3702,7 +3693,7 @@ dependencies = [ [[package]] name = "resource_uri" version = "0.1.0" -source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" dependencies = [ "anyhow", "serde", @@ -5285,7 +5276,7 @@ dependencies = [ "eventlog-rs", "hex", "jsonwebtoken", - "kbs-types 0.5.3 (git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se)", + "kbs-types", "log", "openssl", "rstest", diff --git a/kbs/docs/kbs.yaml b/kbs/docs/kbs.yaml index 9a582e4a5..b04b7b2b1 100644 --- a/kbs/docs/kbs.yaml +++ b/kbs/docs/kbs.yaml @@ -212,6 +212,7 @@ components: required: - tee-pubkey - tee-evidence + - extra-params type: object properties: tee-pubkey: @@ -219,6 +220,11 @@ components: tee-evidence: description: HW-TEE specific attestation evidence. type: object + extra-params: + description: + Freely formatted JSON object used for HW-TEE specific attestation + processes. + type: object description: >- KBS attestation challenge, sent in response to the KBC Request. diff --git a/kbs/docs/kbs_attestation_protocol.md b/kbs/docs/kbs_attestation_protocol.md index 797696ee0..4662aacb9 100644 --- a/kbs/docs/kbs_attestation_protocol.md +++ b/kbs/docs/kbs_attestation_protocol.md @@ -147,6 +147,8 @@ evidence from the HW-TEE platform and organizes it into the following payload: /* The attestation evidence. Its format is specified by Attestation-Service. */ "tee-evidence": {} + /* Extra parameters to support some special HW-TEE attestation. */ + "extra-params": {} } ``` > **Note:** the `/*...*/` comments are not valid in JSON, and must not be used. @@ -178,6 +180,11 @@ Attestation-Service. The KBS does not parse or analyze the attestation evidence, it forwards it to the Attestation-Service for verification. +- `extra-params` + +The reserved extra parameter field which is used to pass the additional +information provided by the KBS when some specific HW-TEE needs to be attested. + ## `Response` Upon successful attestation, the KBC can request resources from the KBS, by diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index b9d017f60..75b4cb7d4 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -29,7 +29,7 @@ impl Attest for BuiltInCoCoAs { let attestation: Attestation = serde_json::from_str(attestation)?; // TODO: align with the guest-components/kbs-protocol side. - let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce}); + let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce, "extra-params": attestation.extra_params}); self.inner .read() diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index e478df8d3..78784cf20 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -102,7 +102,7 @@ impl Attest for GrpcClientPool { let attestation: Attestation = serde_json::from_str(attestation)?; // TODO: align with the guest-components/kbs-protocol side. - let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce}); + let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce, "extra-params": attestation.extra_params}); let runtime_data_plaintext = serde_json::to_string(&runtime_data_plaintext) .context("CoCo AS client: serialize runtime data failed")?; diff --git a/kbs/tools/attest.json b/kbs/tools/attest.json index dd768b3eb..6cad33687 100644 --- a/kbs/tools/attest.json +++ b/kbs/tools/attest.json @@ -4,5 +4,6 @@ "k-mod": "my_modulus", "k-exp": "my_exponent" }, - "tee-evidence": "my_evidence" + "tee-evidence": "my_evidence", + "extra-params": "my_extra_params" } diff --git a/kbs/tools/client/Cargo.toml b/kbs/tools/client/Cargo.toml index c706e3573..c2cf4bd4d 100644 --- a/kbs/tools/client/Cargo.toml +++ b/kbs/tools/client/Cargo.toml @@ -18,7 +18,7 @@ base64.workspace = true clap = { version = "4.0.29", features = ["derive"] } env_logger.workspace = true jwt-simple = "0.11.4" -kbs_protocol = { git = "https://github.com/confidential-containers/guest-components.git", rev = "21b2c536b4d6c5c1442b53916c908b54dde136e8", default-features = false } +kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "cca0fcb0bae3ad0259efabbb84f3e33c986e1675", default-features = false } log.workspace = true reqwest = { version = "0.11.18", default-features = false, features = ["cookies", "json"] } serde = { version = "1.0", features = ["derive"] } From 417404b4fee2fed54f48bbd6e834b9507eceba25 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Fri, 22 Mar 2024 13:38:18 +0800 Subject: [PATCH 06/18] Verifier: IBM SE refine for get_evidence Signed-off-by: Qi Feng Huo --- Cargo.lock | 11 +++++------ Cargo.toml | 2 +- kbs/docs/kbs.yaml | 6 ------ kbs/docs/kbs_attestation_protocol.md | 7 ------- kbs/src/api/src/attestation/coco/builtin.rs | 2 +- kbs/src/api/src/attestation/coco/grpc.rs | 2 +- kbs/tools/attest.json | 3 +-- kbs/tools/client/Cargo.toml | 2 +- 8 files changed, 10 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0da853d90..567d77976 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -564,7 +564,7 @@ dependencies = [ [[package]] name = "attester" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" dependencies = [ "anyhow", "async-trait", @@ -583,7 +583,6 @@ dependencies = [ "serde", "serde_json", "sev", - "sha2", "strum", "tdx-attest-rs", "tempfile", @@ -1278,7 +1277,7 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" dependencies = [ "aes-gcm", "anyhow", @@ -2423,7 +2422,7 @@ dependencies = [ [[package]] name = "kbs-types" version = "0.5.3" -source = "git+https://github.com/huoqifeng/kbs-types.git?branch=s390x-se#271ef4bac54035fb25fa44b24e5bbca844cd057c" +source = "git+https://github.com/virtee/kbs-types.git?rev=e28c20c761378b1e8f5b210c839e3c454f2ec3fb#e28c20c761378b1e8f5b210c839e3c454f2ec3fb" dependencies = [ "serde", "serde_json", @@ -2432,7 +2431,7 @@ dependencies = [ [[package]] name = "kbs_protocol" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" dependencies = [ "anyhow", "async-trait", @@ -3693,7 +3692,7 @@ dependencies = [ [[package]] name = "resource_uri" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=cca0fcb0bae3ad0259efabbb84f3e33c986e1675#cca0fcb0bae3ad0259efabbb84f3e33c986e1675" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" dependencies = [ "anyhow", "serde", diff --git a/Cargo.toml b/Cargo.toml index c8d8797e7..accab6912 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ clap = { version = "4", features = ["derive"] } config = "0.13.3" env_logger = "0.10.0" hex = "0.4.3" -kbs-types = { git = "https://github.com/huoqifeng/kbs-types.git", branch = "s390x-se" } +kbs-types = { git = "https://github.com/virtee/kbs-types.git", rev = "e28c20c761378b1e8f5b210c839e3c454f2ec3fb" } jsonwebtoken = "9" log = "0.4.17" prost = "0.11.0" diff --git a/kbs/docs/kbs.yaml b/kbs/docs/kbs.yaml index b04b7b2b1..9a582e4a5 100644 --- a/kbs/docs/kbs.yaml +++ b/kbs/docs/kbs.yaml @@ -212,7 +212,6 @@ components: required: - tee-pubkey - tee-evidence - - extra-params type: object properties: tee-pubkey: @@ -220,11 +219,6 @@ components: tee-evidence: description: HW-TEE specific attestation evidence. type: object - extra-params: - description: - Freely formatted JSON object used for HW-TEE specific attestation - processes. - type: object description: >- KBS attestation challenge, sent in response to the KBC Request. diff --git a/kbs/docs/kbs_attestation_protocol.md b/kbs/docs/kbs_attestation_protocol.md index 4662aacb9..797696ee0 100644 --- a/kbs/docs/kbs_attestation_protocol.md +++ b/kbs/docs/kbs_attestation_protocol.md @@ -147,8 +147,6 @@ evidence from the HW-TEE platform and organizes it into the following payload: /* The attestation evidence. Its format is specified by Attestation-Service. */ "tee-evidence": {} - /* Extra parameters to support some special HW-TEE attestation. */ - "extra-params": {} } ``` > **Note:** the `/*...*/` comments are not valid in JSON, and must not be used. @@ -180,11 +178,6 @@ Attestation-Service. The KBS does not parse or analyze the attestation evidence, it forwards it to the Attestation-Service for verification. -- `extra-params` - -The reserved extra parameter field which is used to pass the additional -information provided by the KBS when some specific HW-TEE needs to be attested. - ## `Response` Upon successful attestation, the KBC can request resources from the KBS, by diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index 75b4cb7d4..b9d017f60 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -29,7 +29,7 @@ impl Attest for BuiltInCoCoAs { let attestation: Attestation = serde_json::from_str(attestation)?; // TODO: align with the guest-components/kbs-protocol side. - let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce, "extra-params": attestation.extra_params}); + let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce}); self.inner .read() diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 78784cf20..e478df8d3 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -102,7 +102,7 @@ impl Attest for GrpcClientPool { let attestation: Attestation = serde_json::from_str(attestation)?; // TODO: align with the guest-components/kbs-protocol side. - let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce, "extra-params": attestation.extra_params}); + let runtime_data_plaintext = json!({"tee-pubkey": attestation.tee_pubkey, "nonce": nonce}); let runtime_data_plaintext = serde_json::to_string(&runtime_data_plaintext) .context("CoCo AS client: serialize runtime data failed")?; diff --git a/kbs/tools/attest.json b/kbs/tools/attest.json index 6cad33687..dd768b3eb 100644 --- a/kbs/tools/attest.json +++ b/kbs/tools/attest.json @@ -4,6 +4,5 @@ "k-mod": "my_modulus", "k-exp": "my_exponent" }, - "tee-evidence": "my_evidence", - "extra-params": "my_extra_params" + "tee-evidence": "my_evidence" } diff --git a/kbs/tools/client/Cargo.toml b/kbs/tools/client/Cargo.toml index c2cf4bd4d..24024bd7a 100644 --- a/kbs/tools/client/Cargo.toml +++ b/kbs/tools/client/Cargo.toml @@ -18,7 +18,7 @@ base64.workspace = true clap = { version = "4.0.29", features = ["derive"] } env_logger.workspace = true jwt-simple = "0.11.4" -kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "cca0fcb0bae3ad0259efabbb84f3e33c986e1675", default-features = false } +kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "f6607ec8ae8209b2448fae24a78565445ac63bf3", default-features = false } log.workspace = true reqwest = { version = "0.11.18", default-features = false, features = ["cookies", "json"] } serde = { version = "1.0", features = ["derive"] } From 05739da4e1a92d0477833b245faf1b3ccf3a9fa9 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Mon, 25 Mar 2024 16:18:14 +0800 Subject: [PATCH 07/18] Verifier: IBM SE update kbs-types Signed-off-by: Qi Feng Huo --- Cargo.lock | 13 +++++++------ Cargo.toml | 2 +- kbs/tools/client/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 567d77976..63280bcc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -564,7 +564,7 @@ dependencies = [ [[package]] name = "attester" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" dependencies = [ "anyhow", "async-trait", @@ -1277,7 +1277,7 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" dependencies = [ "aes-gcm", "anyhow", @@ -2421,8 +2421,9 @@ dependencies = [ [[package]] name = "kbs-types" -version = "0.5.3" -source = "git+https://github.com/virtee/kbs-types.git?rev=e28c20c761378b1e8f5b210c839e3c454f2ec3fb#e28c20c761378b1e8f5b210c839e3c454f2ec3fb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "febd73b2b1df274ea454d81ddf76f596af9754410b7ed6f988f2e1782a175da3" dependencies = [ "serde", "serde_json", @@ -2431,7 +2432,7 @@ dependencies = [ [[package]] name = "kbs_protocol" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" dependencies = [ "anyhow", "async-trait", @@ -3692,7 +3693,7 @@ dependencies = [ [[package]] name = "resource_uri" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=f6607ec8ae8209b2448fae24a78565445ac63bf3#f6607ec8ae8209b2448fae24a78565445ac63bf3" +source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" dependencies = [ "anyhow", "serde", diff --git a/Cargo.toml b/Cargo.toml index accab6912..b5b839142 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ clap = { version = "4", features = ["derive"] } config = "0.13.3" env_logger = "0.10.0" hex = "0.4.3" -kbs-types = { git = "https://github.com/virtee/kbs-types.git", rev = "e28c20c761378b1e8f5b210c839e3c454f2ec3fb" } +kbs-types = "0.6.0" jsonwebtoken = "9" log = "0.4.17" prost = "0.11.0" diff --git a/kbs/tools/client/Cargo.toml b/kbs/tools/client/Cargo.toml index 24024bd7a..f427a599e 100644 --- a/kbs/tools/client/Cargo.toml +++ b/kbs/tools/client/Cargo.toml @@ -18,7 +18,7 @@ base64.workspace = true clap = { version = "4.0.29", features = ["derive"] } env_logger.workspace = true jwt-simple = "0.11.4" -kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "f6607ec8ae8209b2448fae24a78565445ac63bf3", default-features = false } +kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa", default-features = false } log.workspace = true reqwest = { version = "0.11.18", default-features = false, features = ["cookies", "json"] } serde = { version = "1.0", features = ["derive"] } From d89b2a302542cb7c897e9d52c1fe786e77b026e2 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 3 Apr 2024 08:20:58 +0800 Subject: [PATCH 08/18] Verifier: IBM SE change fn to generate_challenge and add tee_parameters Signed-off-by: Qi Feng Huo --- .../attestation-service/src/lib.rs | 8 ++++++-- attestation-service/verifier/src/lib.rs | 3 ++- attestation-service/verifier/src/se/mod.rs | 3 ++- kbs/src/api/src/attestation/coco/builtin.rs | 8 ++++++-- kbs/src/api/src/attestation/coco/grpc.rs | 6 +++++- .../attestation/intel_trust_authority/mod.rs | 6 +++++- kbs/src/api/src/attestation/mod.rs | 17 ++++++++++++----- kbs/src/api/src/http/attest.rs | 2 +- 8 files changed, 39 insertions(+), 14 deletions(-) diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index 901abed2e..c908754e7 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -240,9 +240,13 @@ impl AttestationService { self.rvps.verify_and_extract(message).await } - pub async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { + pub async fn generate_challenge( + &self, + tee: Tee, + tee_parameters: Option>, + ) -> Result { let verifier = verifier::to_verifier(&tee)?; - verifier.generate_challenge_extra_params().await + verifier.generate_challenge(tee_parameters).await } } diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index d5618d47a..7870c1f61 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -167,8 +167,9 @@ pub trait Verifier { expected_init_data_hash: &InitDataHash, ) -> Result; - async fn generate_challenge_extra_params( + async fn generate_challenge( &self, + _tee_parameters: Option>, ) -> Result { Ok(String::new()) } diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 9055104f4..3c107cda5 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -31,8 +31,9 @@ impl Verifier for SeVerifier { .map_err(|e| anyhow!("Se Verifier: {:?}", e)) } - async fn generate_challenge_extra_params( + async fn generate_challenge( &self, + _tee_parameters: Option>, ) -> Result { // TODO replace FakeSeAttest with real crate diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index b9d017f60..400e5a79e 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -46,11 +46,15 @@ impl Attest for BuiltInCoCoAs { .await } - async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { + async fn generate_challenge( + &self, + tee: Tee, + tee_parameters: Option>, + ) -> Result { self.inner .read() .await - .generate_challenge_extra_params(tee) + .generate_challenge(tee, tee_parameters) .await } } diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index e478df8d3..27dc9029d 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -127,7 +127,11 @@ impl Attest for GrpcClientPool { Ok(token) } - async fn generate_challenge_extra_params(&self, _tee: Tee) -> Result { + async fn generate_challenge( + &self, + _tee: Tee, + _tee_parameters: Option>, + ) -> Result { Ok(String::new()) } } diff --git a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs index dc9012419..6d282b9b8 100644 --- a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs +++ b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs @@ -123,7 +123,11 @@ impl Attest for IntelTrustAuthority { Ok(resp_data.token.clone()) } - async fn generate_challenge_extra_params(&self, _tee: Tee) -> Result { + async fn generate_challenge( + &self, + _tee: Tee, + _tee_parameters: Option>, + ) -> Result { Ok(String::new()) } } diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index e85e21915..6a592ad2d 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -34,7 +34,8 @@ pub trait Attest: Send + Sync { async fn verify(&self, tee: Tee, nonce: &str, attestation: &str) -> Result; /// generate the challenge payload to pass to attester based on Tee and nonce - async fn generate_challenge_extra_params(&self, tee: Tee) -> Result; + async fn generate_challenge(&self, tee: Tee, tee_parameters: Option>) + -> Result; } /// Attestation Service @@ -93,18 +94,24 @@ impl AttestationService { } } - pub async fn generate_challenge_extra_params(&self, tee: Tee) -> Result { + pub async fn generate_challenge( + &self, + tee: Tee, + tee_parameters: Option>, + ) -> Result { match self { #[cfg(feature = "coco-as-grpc")] AttestationService::CoCoASgRPC(inner) => { - inner.generate_challenge_extra_params(tee).await + inner.generate_challenge(tee, tee_parameters).await } #[cfg(any(feature = "coco-as-builtin", feature = "coco-as-builtin-no-verifier"))] AttestationService::CoCoASBuiltIn(inner) => { - inner.generate_challenge_extra_params(tee).await + inner.generate_challenge(tee, tee_parameters).await } #[cfg(feature = "intel-trust-authority-as")] - AttestationService::IntelTA(inner) => inner.generate_challenge_extra_params(tee).await, + AttestationService::IntelTA(inner) => { + inner.generate_challenge(tee, tee_parameters).await + } } } } diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index 6f2c9b015..1b112a3cc 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -23,7 +23,7 @@ pub(crate) async fn auth( info!("request: {:?}", &request); let extra_params = attestation_service - .generate_challenge_extra_params(request.tee) + .generate_challenge(request.tee, Some(request.extra_params.clone().into_bytes())) .await .unwrap(); From 3a6b84e8c8f6403a8801f5ed61ffd30d7f1bb3b0 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 3 Apr 2024 14:12:20 +0800 Subject: [PATCH 09/18] Verifier: IBM SE add generate_challenge in grpc and rest Signed-off-by: Qi Feng Huo --- .../attestation-service/src/bin/grpc/mod.rs | 27 ++++++++++++++++++- .../attestation-service/src/bin/restful-as.rs | 6 ++++- .../src/bin/restful/mod.rs | 21 +++++++++++++++ attestation-service/protos/attestation.proto | 9 +++++++ kbs/src/api/src/attestation/coco/grpc.rs | 21 ++++++++++++--- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/attestation-service/attestation-service/src/bin/grpc/mod.rs b/attestation-service/attestation-service/src/bin/grpc/mod.rs index 722475d98..ba24e3da5 100644 --- a/attestation-service/attestation-service/src/bin/grpc/mod.rs +++ b/attestation-service/attestation-service/src/bin/grpc/mod.rs @@ -14,7 +14,8 @@ use tonic::{Request, Response, Status}; use crate::as_api::attestation_service_server::{AttestationService, AttestationServiceServer}; use crate::as_api::{ - AttestationRequest, AttestationResponse, SetPolicyRequest, SetPolicyResponse, Tee as GrpcTee, + AttestationRequest, AttestationResponse, ChallengeRequest, ChallengeResponse, SetPolicyRequest, + SetPolicyResponse, Tee as GrpcTee, }; use crate::rvps_api::reference_value_provider_service_server::{ @@ -187,6 +188,30 @@ impl AttestationService for Arc> { let res = AttestationResponse { attestation_token }; Ok(Response::new(res)) } + + async fn get_attestation_challenge( + &self, + request: Request, + ) -> Result, Status> { + let request: ChallengeRequest = request.into_inner(); + let tee = to_kbs_tee( + GrpcTee::from_i32(request.tee) + .ok_or_else(|| Status::aborted(format!("Invalid TEE {}", request.tee)))?, + ); + + let attestation_challenge = self + .read() + .await + .attestation_service + .generate_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .await + .map_err(|e| Status::aborted(format!("Challenge: {e:?}")))?; + + let res = ChallengeResponse { + attestation_challenge, + }; + Ok(Response::new(res)) + } } #[tonic::async_trait] diff --git a/attestation-service/attestation-service/src/bin/restful-as.rs b/attestation-service/attestation-service/src/bin/restful-as.rs index de797f7e8..33306cd5e 100644 --- a/attestation-service/attestation-service/src/bin/restful-as.rs +++ b/attestation-service/attestation-service/src/bin/restful-as.rs @@ -12,7 +12,7 @@ use openssl::{ use strum::{AsRefStr, EnumString}; use tokio::sync::RwLock; -use crate::restful::{attestation, set_policy}; +use crate::restful::{attestation, get_challenge, set_policy}; mod restful; @@ -47,6 +47,9 @@ enum WebApi { #[strum(serialize = "/policy")] Policy, + + #[strum(serialize = "/challenge")] + Challenge, } #[actix_web::main] @@ -74,6 +77,7 @@ async fn main() -> Result<()> { App::new() .service(web::resource(WebApi::Attestation.as_ref()).route(web::post().to(attestation))) .service(web::resource(WebApi::Policy.as_ref()).route(web::post().to(set_policy))) + .service(web::resource(WebApi::Challenge.as_ref()).route(web::post().to(get_challenge))) .app_data(web::Data::clone(&attestation_service)) }); diff --git a/attestation-service/attestation-service/src/bin/restful/mod.rs b/attestation-service/attestation-service/src/bin/restful/mod.rs index 0f25202b7..72a5ba65e 100644 --- a/attestation-service/attestation-service/src/bin/restful/mod.rs +++ b/attestation-service/attestation-service/src/bin/restful/mod.rs @@ -44,6 +44,12 @@ pub struct AttestationRequest { policy_ids: Vec, } +#[derive(Debug, Serialize, Deserialize)] +pub struct ChallengeRequest { + tee: String, + tee_params: String, +} + #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] enum Data { @@ -173,3 +179,18 @@ pub async fn set_policy( Ok(HttpResponse::Ok().body("")) } + +/// This handler uses json extractor +pub async fn get_challenge( + request: web::Json, + cocoas: web::Data>>, +) -> Result { + let tee = to_tee(&request.tee)?; + let challenge = cocoas + .read() + .await + .generate_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .await + .context("generate challenge")?; + Ok(HttpResponse::Ok().body(challenge)) +} diff --git a/attestation-service/protos/attestation.proto b/attestation-service/protos/attestation.proto index fb33a057c..9c167b348 100644 --- a/attestation-service/protos/attestation.proto +++ b/attestation-service/protos/attestation.proto @@ -89,8 +89,17 @@ message SetPolicyRequest { } message SetPolicyResponse {} +message ChallengeRequest { + Tee tee = 1; + string tee_params = 2; +} +message ChallengeResponse { + string attestation_challenge = 1; +} + service AttestationService { rpc AttestationEvaluate(AttestationRequest) returns (AttestationResponse) {}; rpc SetAttestationPolicy(SetPolicyRequest) returns (SetPolicyResponse) {}; + rpc GetAttestationChallenge(ChallengeRequest) returns (ChallengeResponse) {}; // Get the GetPolicyRequest.user and GetPolicyRequest.tee specified Policy(.rego) } diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 27dc9029d..ed60face3 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -16,7 +16,7 @@ use tonic::transport::Channel; use self::attestation::{ attestation_request::RuntimeData, attestation_service_client::AttestationServiceClient, - AttestationRequest, SetPolicyRequest, Tee as GrpcTee, + AttestationRequest, ChallengeRequest, SetPolicyRequest, Tee as GrpcTee, }; mod attestation { @@ -129,10 +129,23 @@ impl Attest for GrpcClientPool { async fn generate_challenge( &self, - _tee: Tee, - _tee_parameters: Option>, + tee: Tee, + tee_parameters: Option>, ) -> Result { - Ok(String::new()) + let req = tonic::Request::new(ChallengeRequest { + tee: to_grpc_tee(tee).into(), + tee_params: String::from_utf8(tee_parameters.unwrap()).unwrap(), + }); + + let mut client = { self.pool.lock().await.get().await? }; + + let challenge = client + .get_attestation_challenge(req) + .await? + .into_inner() + .attestation_challenge; + + Ok(challenge) } } From c9d7bee1dcbcda95dc6753c322d857d1ab9f3348 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Thu, 18 Apr 2024 16:33:11 +0800 Subject: [PATCH 10/18] Verifier: IBM SE simplify the method Signed-off-by: Qi Feng Huo --- attestation-service/verifier/src/se/mod.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 3c107cda5..89c9e8ec0 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -5,7 +5,6 @@ use super::*; use async_trait::async_trait; -use anyhow::anyhow; use base64::prelude::*; use serde_json::json; use crate::{InitDataHash, ReportData}; @@ -25,10 +24,7 @@ impl Verifier for SeVerifier { expected_report_data: &ReportData, expected_init_data_hash: &InitDataHash, ) -> Result { - - verify_evidence(evidence, expected_report_data, expected_init_data_hash) - .await - .map_err(|e| anyhow!("Se Verifier: {:?}", e)) + verify_evidence(evidence, expected_report_data, expected_init_data_hash).await } async fn generate_challenge( @@ -39,6 +35,7 @@ impl Verifier for SeVerifier { // TODO replace FakeSeAttest with real crate let attester = FakeSeAttest::default(); + // TODO replace the placeholder let hkds: Vec = vec![String::new(); 2]; let certk = "cert_file_path"; let signk = "sign_file_path"; @@ -60,8 +57,10 @@ async fn verify_evidence( // TODO replace FakeSeAttest with real crate let attester = FakeSeAttest::default(); + // TODO replace the placeholder let arpk = "arpk_file_path"; let hdr = "hdr_file_path"; + let se = attester.verify(evidence, arpk, hdr) .await .context("Verify SE attestation evidence failed: {:?}")?; @@ -73,4 +72,4 @@ async fn verify_evidence( }); Ok(claims_map as TeeEvidenceParsedClaim) -} \ No newline at end of file +} From 4fac842f5218201a48bfa612b98265eaa05a0218 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Thu, 18 Apr 2024 17:04:22 +0800 Subject: [PATCH 11/18] Verifier: change fn name from generate_challenge to generate_supplemental_challenge Signed-off-by: Qi Feng Huo --- .../attestation-service/src/bin/grpc/mod.rs | 2 +- .../src/bin/restful/mod.rs | 2 +- .../attestation-service/src/lib.rs | 6 ++++-- attestation-service/verifier/src/lib.rs | 2 +- attestation-service/verifier/src/se/mod.rs | 2 +- kbs/src/api/src/attestation/coco/builtin.rs | 4 ++-- kbs/src/api/src/attestation/coco/grpc.rs | 2 +- .../attestation/intel_trust_authority/mod.rs | 2 +- kbs/src/api/src/attestation/mod.rs | 21 +++++++++++++------ kbs/src/api/src/http/attest.rs | 5 ++++- 10 files changed, 31 insertions(+), 17 deletions(-) diff --git a/attestation-service/attestation-service/src/bin/grpc/mod.rs b/attestation-service/attestation-service/src/bin/grpc/mod.rs index 829735db4..f302a3013 100644 --- a/attestation-service/attestation-service/src/bin/grpc/mod.rs +++ b/attestation-service/attestation-service/src/bin/grpc/mod.rs @@ -216,7 +216,7 @@ impl AttestationService for Arc> { .read() .await .attestation_service - .generate_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .generate_supplemental_challenge(tee, Some(request.tee_params.clone().into_bytes())) .await .map_err(|e| Status::aborted(format!("Challenge: {e:?}")))?; diff --git a/attestation-service/attestation-service/src/bin/restful/mod.rs b/attestation-service/attestation-service/src/bin/restful/mod.rs index 76c33f5ea..23dfccd2c 100644 --- a/attestation-service/attestation-service/src/bin/restful/mod.rs +++ b/attestation-service/attestation-service/src/bin/restful/mod.rs @@ -189,7 +189,7 @@ pub async fn get_challenge( let challenge = cocoas .read() .await - .generate_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .generate_supplemental_challenge(tee, Some(request.tee_params.clone().into_bytes())) .await .context("generate challenge")?; Ok(HttpResponse::Ok().body(challenge)) diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index 73d5a719f..2016a6523 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -259,13 +259,15 @@ impl AttestationService { self.rvps.verify_and_extract(message).await } - pub async fn generate_challenge( + pub async fn generate_supplemental_challenge( &self, tee: Tee, tee_parameters: Option>, ) -> Result { let verifier = verifier::to_verifier(&tee)?; - verifier.generate_challenge(tee_parameters).await + verifier + .generate_supplemental_challenge(tee_parameters) + .await } } diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index cb145b7a5..369b60534 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -167,7 +167,7 @@ pub trait Verifier { expected_init_data_hash: &InitDataHash, ) -> Result; - async fn generate_challenge( + async fn generate_supplemental_challenge( &self, _tee_parameters: Option>, ) -> Result { diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 89c9e8ec0..bd708203a 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -27,7 +27,7 @@ impl Verifier for SeVerifier { verify_evidence(evidence, expected_report_data, expected_init_data_hash).await } - async fn generate_challenge( + async fn generate_supplemental_challenge( &self, _tee_parameters: Option>, ) -> Result { diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index 400e5a79e..8a2cd3a0c 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -46,7 +46,7 @@ impl Attest for BuiltInCoCoAs { .await } - async fn generate_challenge( + async fn generate_supplemental_challenge( &self, tee: Tee, tee_parameters: Option>, @@ -54,7 +54,7 @@ impl Attest for BuiltInCoCoAs { self.inner .read() .await - .generate_challenge(tee, tee_parameters) + .generate_supplemental_challenge(tee, tee_parameters) .await } } diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index ed60face3..dd0333856 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -127,7 +127,7 @@ impl Attest for GrpcClientPool { Ok(token) } - async fn generate_challenge( + async fn generate_supplemental_challenge( &self, tee: Tee, tee_parameters: Option>, diff --git a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs index 6d282b9b8..2de4e1bc7 100644 --- a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs +++ b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs @@ -123,7 +123,7 @@ impl Attest for IntelTrustAuthority { Ok(resp_data.token.clone()) } - async fn generate_challenge( + async fn generate_supplemental_challenge( &self, _tee: Tee, _tee_parameters: Option>, diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index 6a592ad2d..cc6300e4a 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -34,8 +34,11 @@ pub trait Attest: Send + Sync { async fn verify(&self, tee: Tee, nonce: &str, attestation: &str) -> Result; /// generate the challenge payload to pass to attester based on Tee and nonce - async fn generate_challenge(&self, tee: Tee, tee_parameters: Option>) - -> Result; + async fn generate_supplemental_challenge( + &self, + tee: Tee, + tee_parameters: Option>, + ) -> Result; } /// Attestation Service @@ -94,7 +97,7 @@ impl AttestationService { } } - pub async fn generate_challenge( + pub async fn generate_supplemental_challenge( &self, tee: Tee, tee_parameters: Option>, @@ -102,15 +105,21 @@ impl AttestationService { match self { #[cfg(feature = "coco-as-grpc")] AttestationService::CoCoASgRPC(inner) => { - inner.generate_challenge(tee, tee_parameters).await + inner + .generate_supplemental_challenge(tee, tee_parameters) + .await } #[cfg(any(feature = "coco-as-builtin", feature = "coco-as-builtin-no-verifier"))] AttestationService::CoCoASBuiltIn(inner) => { - inner.generate_challenge(tee, tee_parameters).await + inner + .generate_supplemental_challenge(tee, tee_parameters) + .await } #[cfg(feature = "intel-trust-authority-as")] AttestationService::IntelTA(inner) => { - inner.generate_challenge(tee, tee_parameters).await + inner + .generate_supplemental_challenge(tee, tee_parameters) + .await } } } diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index c8caa8506..ba7709ed1 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -24,7 +24,10 @@ pub(crate) async fn auth( debug!("Auth Request: {:?}", &request); let extra_params = attestation_service - .generate_challenge(request.tee, Some(request.extra_params.clone().into_bytes())) + .generate_supplemental_challenge( + request.tee, + Some(request.extra_params.clone().into_bytes()), + ) .await .unwrap(); From e310e7693c10fd09deb9648cb447a6f77a950189 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Fri, 19 Apr 2024 09:02:45 +0800 Subject: [PATCH 12/18] Merge branch 'main' into s390x-verifier fix fmt err Signed-off-by: Qi Feng Huo --- .../attestation-service/src/bin/restful-as.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/attestation-service/attestation-service/src/bin/restful-as.rs b/attestation-service/attestation-service/src/bin/restful-as.rs index 833b0c212..e03fd71f4 100644 --- a/attestation-service/attestation-service/src/bin/restful-as.rs +++ b/attestation-service/attestation-service/src/bin/restful-as.rs @@ -97,19 +97,13 @@ async fn main() -> Result<(), RestfulError> { let attestation_service = web::Data::new(Arc::new(RwLock::new(attestation_service))); let server = HttpServer::new(move || { App::new() - .service( - web::resource(WebApi::Attestation.as_ref()) - .route(web::post().to(attestation)), - ) + .service(web::resource(WebApi::Attestation.as_ref()).route(web::post().to(attestation))) .service( web::resource(WebApi::Policy.as_ref()) .route(web::post().to(set_policy)) .route(web::get().to(get_policies)), ) - .service( - web::resource(WebApi::Challenge.as_ref()) - .route(web::post().to(get_challenge)), - ) + .service(web::resource(WebApi::Challenge.as_ref()).route(web::post().to(get_challenge))) .app_data(web::Data::clone(&attestation_service)) }); From 302186aecb9b42880e305af1d06fbed9dfd758d3 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Fri, 19 Apr 2024 09:45:30 +0800 Subject: [PATCH 13/18] Verifier: IBM SE refine fake trait Signed-off-by: Qi Feng Huo --- .../verifier/src/se/{seattest.rs => ibmse.rs} | 0 attestation-service/verifier/src/se/mod.rs | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) rename attestation-service/verifier/src/se/{seattest.rs => ibmse.rs} (100%) diff --git a/attestation-service/verifier/src/se/seattest.rs b/attestation-service/verifier/src/se/ibmse.rs similarity index 100% rename from attestation-service/verifier/src/se/seattest.rs rename to attestation-service/verifier/src/se/ibmse.rs diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index bd708203a..6e652a649 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -8,10 +8,10 @@ use async_trait::async_trait; use base64::prelude::*; use serde_json::json; use crate::{InitDataHash, ReportData}; -use crate::se::seattest::FakeSeAttest; -use crate::se::seattest::SeFakeVerifier; +use crate::se::ibmse::FakeSeAttest; +use crate::se::ibmse::SeFakeVerifier; -pub mod seattest; +pub mod ibmse; #[derive(Debug, Default)] pub struct SeVerifier {} @@ -32,7 +32,7 @@ impl Verifier for SeVerifier { _tee_parameters: Option>, ) -> Result { - // TODO replace FakeSeAttest with real crate + // TODO replace FakeSeAttest with real IBM SE crate let attester = FakeSeAttest::default(); // TODO replace the placeholder @@ -54,7 +54,7 @@ async fn verify_evidence( _expected_report_data: &ReportData<'_>, _expected_init_data_hash: &InitDataHash<'_>, ) -> Result { - // TODO replace FakeSeAttest with real crate + // TODO replace FakeSeAttest with real IBM SE crate let attester = FakeSeAttest::default(); // TODO replace the placeholder From d1adc60200f55745c310e598928261a6ec47ebf2 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Fri, 19 Apr 2024 10:42:49 +0800 Subject: [PATCH 14/18] Verifier: IBM SE use string but not Vec for tee_parameters Signed-off-by: Qi Feng Huo --- attestation-service/attestation-service/src/bin/grpc/mod.rs | 2 +- .../attestation-service/src/bin/restful/mod.rs | 2 +- attestation-service/attestation-service/src/lib.rs | 2 +- attestation-service/verifier/src/lib.rs | 2 +- attestation-service/verifier/src/se/mod.rs | 6 +++--- kbs/src/api/src/attestation/coco/builtin.rs | 2 +- kbs/src/api/src/attestation/coco/grpc.rs | 4 ++-- kbs/src/api/src/attestation/intel_trust_authority/mod.rs | 2 +- kbs/src/api/src/attestation/mod.rs | 4 ++-- kbs/src/api/src/http/attest.rs | 5 +---- 10 files changed, 14 insertions(+), 17 deletions(-) diff --git a/attestation-service/attestation-service/src/bin/grpc/mod.rs b/attestation-service/attestation-service/src/bin/grpc/mod.rs index f302a3013..5c77d5d87 100644 --- a/attestation-service/attestation-service/src/bin/grpc/mod.rs +++ b/attestation-service/attestation-service/src/bin/grpc/mod.rs @@ -216,7 +216,7 @@ impl AttestationService for Arc> { .read() .await .attestation_service - .generate_supplemental_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .generate_supplemental_challenge(tee, Some(request.tee_params.clone())) .await .map_err(|e| Status::aborted(format!("Challenge: {e:?}")))?; diff --git a/attestation-service/attestation-service/src/bin/restful/mod.rs b/attestation-service/attestation-service/src/bin/restful/mod.rs index 6ee3133fc..77f2b2b30 100644 --- a/attestation-service/attestation-service/src/bin/restful/mod.rs +++ b/attestation-service/attestation-service/src/bin/restful/mod.rs @@ -189,7 +189,7 @@ pub async fn get_challenge( let challenge = cocoas .read() .await - .generate_supplemental_challenge(tee, Some(request.tee_params.clone().into_bytes())) + .generate_supplemental_challenge(tee, Some(request.tee_params.clone())) .await .context("generate challenge")?; Ok(HttpResponse::Ok().body(challenge)) diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index e921b604b..6cd60eb0a 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -278,7 +278,7 @@ impl AttestationService { pub async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option>, + tee_parameters: Option, ) -> Result { let verifier = verifier::to_verifier(&tee)?; verifier diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index 369b60534..27a501c8b 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -169,7 +169,7 @@ pub trait Verifier { async fn generate_supplemental_challenge( &self, - _tee_parameters: Option>, + _tee_parameters: Option, ) -> Result { Ok(String::new()) } diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 6e652a649..134523a4d 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -29,7 +29,7 @@ impl Verifier for SeVerifier { async fn generate_supplemental_challenge( &self, - _tee_parameters: Option>, + _tee_parameters: Option, ) -> Result { // TODO replace FakeSeAttest with real IBM SE crate @@ -41,11 +41,11 @@ impl Verifier for SeVerifier { let signk = "sign_file_path"; let arpk = "arpk_file_path"; - let extra_params = attester.create(hkds, certk, signk, arpk) + let challenge = attester.create(hkds, certk, signk, arpk) .await .context("Create SE attestation request failed: {:?}")?; - Ok(BASE64_STANDARD.encode(extra_params)) + Ok(BASE64_STANDARD.encode(challenge)) } } diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index 8a2cd3a0c..e5125d1c7 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -49,7 +49,7 @@ impl Attest for BuiltInCoCoAs { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option>, + tee_parameters: Option, ) -> Result { self.inner .read() diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index dd0333856..4d710cd7c 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -130,11 +130,11 @@ impl Attest for GrpcClientPool { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option>, + tee_parameters: Option, ) -> Result { let req = tonic::Request::new(ChallengeRequest { tee: to_grpc_tee(tee).into(), - tee_params: String::from_utf8(tee_parameters.unwrap()).unwrap(), + tee_params: tee_parameters.unwrap(), }); let mut client = { self.pool.lock().await.get().await? }; diff --git a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs index 2de4e1bc7..965a558e3 100644 --- a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs +++ b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs @@ -126,7 +126,7 @@ impl Attest for IntelTrustAuthority { async fn generate_supplemental_challenge( &self, _tee: Tee, - _tee_parameters: Option>, + _tee_parameters: Option, ) -> Result { Ok(String::new()) } diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index cc6300e4a..597b3cd67 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -37,7 +37,7 @@ pub trait Attest: Send + Sync { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option>, + tee_parameters: Option, ) -> Result; } @@ -100,7 +100,7 @@ impl AttestationService { pub async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option>, + tee_parameters: Option, ) -> Result { match self { #[cfg(feature = "coco-as-grpc")] diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index ba7709ed1..4998aa254 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -24,10 +24,7 @@ pub(crate) async fn auth( debug!("Auth Request: {:?}", &request); let extra_params = attestation_service - .generate_supplemental_challenge( - request.tee, - Some(request.extra_params.clone().into_bytes()), - ) + .generate_supplemental_challenge(request.tee, Some(request.extra_params.clone())) .await .unwrap(); From 71332794709ec4a08d7b8f135c66c12f81baec76 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 24 Apr 2024 09:01:00 +0800 Subject: [PATCH 15/18] Verifier: IBM SE use String but not Option for tee_parameters Signed-off-by: Qi Feng Huo --- .../attestation-service/src/bin/grpc/mod.rs | 2 +- .../attestation-service/src/bin/restful/mod.rs | 2 +- attestation-service/attestation-service/src/lib.rs | 2 +- attestation-service/verifier/src/lib.rs | 10 +++++++++- attestation-service/verifier/src/se/mod.rs | 2 +- kbs/src/api/src/attestation/coco/builtin.rs | 2 +- kbs/src/api/src/attestation/coco/grpc.rs | 4 ++-- .../api/src/attestation/intel_trust_authority/mod.rs | 2 +- kbs/src/api/src/attestation/mod.rs | 4 ++-- kbs/src/api/src/http/attest.rs | 2 +- 10 files changed, 20 insertions(+), 12 deletions(-) diff --git a/attestation-service/attestation-service/src/bin/grpc/mod.rs b/attestation-service/attestation-service/src/bin/grpc/mod.rs index 5c77d5d87..200051d6d 100644 --- a/attestation-service/attestation-service/src/bin/grpc/mod.rs +++ b/attestation-service/attestation-service/src/bin/grpc/mod.rs @@ -216,7 +216,7 @@ impl AttestationService for Arc> { .read() .await .attestation_service - .generate_supplemental_challenge(tee, Some(request.tee_params.clone())) + .generate_supplemental_challenge(tee, request.tee_params.clone()) .await .map_err(|e| Status::aborted(format!("Challenge: {e:?}")))?; diff --git a/attestation-service/attestation-service/src/bin/restful/mod.rs b/attestation-service/attestation-service/src/bin/restful/mod.rs index 77f2b2b30..9dcee1d13 100644 --- a/attestation-service/attestation-service/src/bin/restful/mod.rs +++ b/attestation-service/attestation-service/src/bin/restful/mod.rs @@ -189,7 +189,7 @@ pub async fn get_challenge( let challenge = cocoas .read() .await - .generate_supplemental_challenge(tee, Some(request.tee_params.clone())) + .generate_supplemental_challenge(tee, request.tee_params.clone()) .await .context("generate challenge")?; Ok(HttpResponse::Ok().body(challenge)) diff --git a/attestation-service/attestation-service/src/lib.rs b/attestation-service/attestation-service/src/lib.rs index 6cd60eb0a..41d4c0335 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -278,7 +278,7 @@ impl AttestationService { pub async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option, + tee_parameters: String, ) -> Result { let verifier = verifier::to_verifier(&tee)?; verifier diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index 27a501c8b..d0ada3d83 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -167,9 +167,17 @@ pub trait Verifier { expected_init_data_hash: &InitDataHash, ) -> Result; + /// Generate the supplemental challenge + /// + /// Some TEE like IBM SE need a `challenge` generated on verifier side + /// and pass it to attester side. This challenge is used by attester to + /// generate the evidence + /// + /// A optional `tee_parameters` comes from the attester side as the input. + async fn generate_supplemental_challenge( &self, - _tee_parameters: Option, + _tee_parameters: String, ) -> Result { Ok(String::new()) } diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 134523a4d..56aa4ff37 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -29,7 +29,7 @@ impl Verifier for SeVerifier { async fn generate_supplemental_challenge( &self, - _tee_parameters: Option, + _tee_parameters: String, ) -> Result { // TODO replace FakeSeAttest with real IBM SE crate diff --git a/kbs/src/api/src/attestation/coco/builtin.rs b/kbs/src/api/src/attestation/coco/builtin.rs index e5125d1c7..477b06500 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -49,7 +49,7 @@ impl Attest for BuiltInCoCoAs { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option, + tee_parameters: String, ) -> Result { self.inner .read() diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 4d710cd7c..b60b8f7a8 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -130,11 +130,11 @@ impl Attest for GrpcClientPool { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option, + tee_parameters: String, ) -> Result { let req = tonic::Request::new(ChallengeRequest { tee: to_grpc_tee(tee).into(), - tee_params: tee_parameters.unwrap(), + tee_params: tee_parameters, }); let mut client = { self.pool.lock().await.get().await? }; diff --git a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs index 965a558e3..a9664ddaf 100644 --- a/kbs/src/api/src/attestation/intel_trust_authority/mod.rs +++ b/kbs/src/api/src/attestation/intel_trust_authority/mod.rs @@ -126,7 +126,7 @@ impl Attest for IntelTrustAuthority { async fn generate_supplemental_challenge( &self, _tee: Tee, - _tee_parameters: Option, + _tee_parameters: String, ) -> Result { Ok(String::new()) } diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index 597b3cd67..3db42837d 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -37,7 +37,7 @@ pub trait Attest: Send + Sync { async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option, + tee_parameters: String, ) -> Result; } @@ -100,7 +100,7 @@ impl AttestationService { pub async fn generate_supplemental_challenge( &self, tee: Tee, - tee_parameters: Option, + tee_parameters: String, ) -> Result { match self { #[cfg(feature = "coco-as-grpc")] diff --git a/kbs/src/api/src/http/attest.rs b/kbs/src/api/src/http/attest.rs index 4998aa254..95e6aae8e 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -24,7 +24,7 @@ pub(crate) async fn auth( debug!("Auth Request: {:?}", &request); let extra_params = attestation_service - .generate_supplemental_challenge(request.tee, Some(request.extra_params.clone())) + .generate_supplemental_challenge(request.tee, request.extra_params.clone()) .await .unwrap(); From c9487ea87e58bd1c682375fca8f3d88405872854 Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 24 Apr 2024 09:48:58 +0800 Subject: [PATCH 16/18] Verifier: IBM SE rollback kbs_protocol in tools client Signed-off-by: Qi Feng Huo --- Cargo.lock | 30 ++++++++++++++++++++---------- kbs/tools/client/Cargo.toml | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0225b6de9..01e37d953 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ "env_logger 0.10.2", "jsonwebtoken", "jwt-simple", - "kbs-types", + "kbs-types 0.6.0", "lazy_static", "log", "mobc", @@ -539,7 +539,7 @@ dependencies = [ "env_logger 0.10.2", "futures", "hex", - "kbs-types", + "kbs-types 0.6.0", "lazy_static", "log", "openssl", @@ -568,7 +568,7 @@ dependencies = [ [[package]] name = "attester" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" +source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" dependencies = [ "anyhow", "async-trait", @@ -579,7 +579,7 @@ dependencies = [ "csv-rs", "hyper", "hyper-tls", - "kbs-types", + "kbs-types 0.5.3", "log", "nix", "occlum_dcap", @@ -1309,13 +1309,13 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" +source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" dependencies = [ "aes-gcm", "anyhow", "base64 0.21.7", "ctr", - "kbs-types", + "kbs-types 0.5.3", "rand", "rsa 0.9.6", "serde", @@ -2483,6 +2483,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "kbs-types" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f4b0642769e12f56cfc646d8be13668ed48d3caed0e99efb161c407f3ec532" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "kbs-types" version = "0.6.0" @@ -2496,7 +2506,7 @@ dependencies = [ [[package]] name = "kbs_protocol" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" +source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" dependencies = [ "anyhow", "async-trait", @@ -2504,7 +2514,7 @@ dependencies = [ "base64 0.21.7", "crypto", "jwt-simple", - "kbs-types", + "kbs-types 0.5.3", "log", "reqwest", "resource_uri", @@ -3834,7 +3844,7 @@ dependencies = [ [[package]] name = "resource_uri" version = "0.1.0" -source = "git+https://github.com/huoqifeng/guest-components.git?rev=4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa#4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa" +source = "git+https://github.com/confidential-containers/guest-components.git?rev=21b2c536b4d6c5c1442b53916c908b54dde136e8#21b2c536b4d6c5c1442b53916c908b54dde136e8" dependencies = [ "anyhow", "serde", @@ -5438,7 +5448,7 @@ dependencies = [ "hex", "jsonwebkey", "jsonwebtoken", - "kbs-types", + "kbs-types 0.6.0", "log", "openssl", "rstest", diff --git a/kbs/tools/client/Cargo.toml b/kbs/tools/client/Cargo.toml index f427a599e..c706e3573 100644 --- a/kbs/tools/client/Cargo.toml +++ b/kbs/tools/client/Cargo.toml @@ -18,7 +18,7 @@ base64.workspace = true clap = { version = "4.0.29", features = ["derive"] } env_logger.workspace = true jwt-simple = "0.11.4" -kbs_protocol = { git = "https://github.com/huoqifeng/guest-components.git", rev = "4b2333c64d5cabc6f58b741e3ebdd6a477a54bfa", default-features = false } +kbs_protocol = { git = "https://github.com/confidential-containers/guest-components.git", rev = "21b2c536b4d6c5c1442b53916c908b54dde136e8", default-features = false } log.workspace = true reqwest = { version = "0.11.18", default-features = false, features = ["cookies", "json"] } serde = { version = "1.0", features = ["derive"] } From 7c10203490ea13194e63f5adb6e40bfa70dc020c Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Tue, 7 May 2024 16:01:09 +0800 Subject: [PATCH 17/18] Verifier: IBM SE implementation Signed-off-by: Qi Feng Huo --- Cargo.toml | 1 + .../attestation-service/Cargo.toml | 8 +- attestation-service/verifier/Cargo.toml | 8 +- attestation-service/verifier/src/se/ibmse.rs | 195 ++++++++++++++---- attestation-service/verifier/src/se/mod.rs | 39 ++-- 5 files changed, 184 insertions(+), 67 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dc0f63ee3..4ffba909b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,3 +47,4 @@ tokio = { version = "1.23.0", features = ["full"] } tempfile = "3.4.0" tonic = "0.8.1" tonic-build = "0.8.0" + diff --git a/attestation-service/attestation-service/Cargo.toml b/attestation-service/attestation-service/Cargo.toml index 9717dc19f..bbb354e54 100644 --- a/attestation-service/attestation-service/Cargo.toml +++ b/attestation-service/attestation-service/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default = [ "restful-bin", "rvps-grpc", "rvps-builtin", "all-verifier" ] +default = [ "restful-bin", "rvps-grpc", "rvps-builtin" ] all-verifier = [ "verifier/all-verifier" ] tdx-verifier = [ "verifier/tdx-verifier" ] sgx-verifier = [ "verifier/sgx-verifier" ] @@ -63,7 +63,11 @@ thiserror = { workspace = true, optional = true } tokio.workspace = true tonic = { workspace = true, optional = true } uuid = { version = "1.1.2", features = ["v4"] } -verifier = { path = "../verifier", default-features = false } +[target.'cfg(not(target_arch = "s390x"))'.dependencies] +verifier = { path = "../verifier", default-features = false, features = ["all-verifier"] } + +[target.'cfg(target_arch = "s390x")'.dependencies] +verifier = { path = "../verifier", default-features = false, features = ["se-verifier"] } [build-dependencies] shadow-rs.workspace = true diff --git a/attestation-service/verifier/Cargo.toml b/attestation-service/verifier/Cargo.toml index 7deaa5e86..ec33b1350 100644 --- a/attestation-service/verifier/Cargo.toml +++ b/attestation-service/verifier/Cargo.toml @@ -13,7 +13,7 @@ az-tdx-vtpm-verifier = [ "az-tdx-vtpm", "openssl", "tdx-verifier" ] snp-verifier = [ "asn1-rs", "openssl", "sev", "x509-parser" ] csv-verifier = [ "openssl", "csv-rs", "codicon" ] cca-verifier = [ "ear", "jsonwebtoken", "veraison-apiclient" ] -se-verifier = [ "openssl" ] +se-verifier = [ "openssl", "pv" ] [dependencies] anyhow.workspace = true @@ -36,9 +36,11 @@ jsonwebtoken = { workspace = true, default-features = false, optional = true } kbs-types.workspace = true log.workspace = true openssl = { version = "0.10.55", optional = true } +pv = { version = "0.10.0", package = "s390_pv" } scroll = { version = "0.11.0", default-features = false, features = ["derive"], optional = true } serde.workspace = true serde_json.workspace = true +serde_yaml = "0.9.0" sev = { version = "1.2.0", features = ["openssl", "snp"], optional = true } sgx-dcap-quoteverify-rs = { git = "https://github.com/intel/SGXDataCenterAttestationPrimitives", tag = "DCAP_1.16", optional = true } strum.workspace = true @@ -55,3 +57,7 @@ assert-json-diff.workspace = true rstest.workspace = true serial_test.workspace = true tokio.workspace = true + +[patch.crates-io] +s390_pv = { path = "/root/src/tmp_pv_crate/pv" } +s390_pv_core = { path = "/root/src/tmp_pv_crate/pv_core" } diff --git a/attestation-service/verifier/src/se/ibmse.rs b/attestation-service/verifier/src/se/ibmse.rs index 3a7f354a9..dfc31f138 100644 --- a/attestation-service/verifier/src/se/ibmse.rs +++ b/attestation-service/verifier/src/se/ibmse.rs @@ -3,48 +3,163 @@ // SPDX-License-Identifier: Apache-2.0 // -use anyhow::*; -use async_trait; - -#[derive(Default)] -pub struct FakeSeAttest {} - -#[async_trait::async_trait] -pub trait SeFakeVerifier { - async fn create<'a, 'b, 'c>( - &self, - _hkd_files: Vec, - _cert_file: &'a str, - _signing_file: &'b str, - _arpk_file: &'c str, - ) -> Result>; - - async fn verify<'a, 'b>( - &self, - _evidence: &[u8], - _arpk_file: &'a str, - _hdr_file: &'b str, - ) -> Result>; +use anyhow::{anyhow, bail, Context, Result}; +use log::{debug, warn}; +use pv::{ + attest::{ + AdditionalData, AttestationFlags, AttestationItems, AttestationMeasAlg, + AttestationMeasurement, AttestationRequest, AttestationVersion, ExchangeFormatCtx, + ExchangeFormatVersion, + }, + misc::{CertificateOptions, open_file, read_exact_file, write_file, HexSlice}, + request::{openssl::pkey::PKey, BootHdrTags, Confidential, ReqEncrCtx, Request, SymKey, SymKeyType}, +}; +use serde::Serialize; +use serde_yaml; +use std::{fmt::Display, io::Read, process::ExitCode}; + +const EXIT_CODE_ATTESTATION_FAIL: u8 = 2; + +#[derive(Serialize)] +struct VerifyOutput<'a> { + cuid: HexSlice<'a>, + #[serde(skip_serializing_if = "Option::is_none")] + additional_data: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + additional_data_fields: Option>>, + #[serde(skip_serializing_if = "Option::is_none")] + user_data: Option>, +} + +impl<'a> VerifyOutput<'a> { + fn from_exchange(ctx: &'a ExchangeFormatCtx, flags: &AttestationFlags) -> Result { + let additional_data_fields = ctx + .additional() + .map(|a| AdditionalData::from_slice(a, flags)) + .transpose()?; + let user_data = ctx.user().map(|u| u.into()); + + Ok(Self { + cuid: ctx.config_uid()?.into(), + additional_data: ctx.additional().map(|a| a.into()), + additional_data_fields, + user_data, + }) + } } -#[async_trait::async_trait] -impl SeFakeVerifier for FakeSeAttest { - async fn create<'a, 'b, 'c>( - &self, - _hkd_files: Vec, - _cert_file: &'a str, - _signing_file: &'b str, - _arpk_file: &'c str, - ) -> Result> { - Result::Ok("test".as_bytes().to_vec()) +impl<'a> Display for VerifyOutput<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Config UID:")?; + writeln!(f, "{:#}", self.cuid)?; + if let Some(data) = &self.additional_data { + writeln!(f, "Additional-data:")?; + writeln!(f, "{:#}", data)?; + } + if let Some(data) = &self.additional_data_fields { + writeln!(f, "Additional-data content:")?; + writeln!(f, "{:#}", data)?; + } + if let Some(data) = &self.user_data { + writeln!(f, "user-data:")?; + writeln!(f, "{:#}", data)?; + } + Ok(()) } +} + +pub fn verify(input: &mut dyn Read, hdr_file: String, arpk_file: String, output: &mut Vec, user_data: &mut Vec) -> Result { + let mut img = open_file(&hdr_file)?; + let arpk = SymKey::Aes256( + read_exact_file(&arpk_file, "Attestation request protection key").map(Confidential::new)?, + ); + let hdr = BootHdrTags::from_se_image(&mut img)?; + let ctx = ExchangeFormatCtx::read(mut input, true)?; + + let (auth, conf) = AttestationRequest::decrypt_bin(ctx.arcb(), &arpk)?; + let meas_key = PKey::hmac(conf.measurement_key())?; + let items = AttestationItems::from_exchange(&ctx, &hdr, conf.nonce())?; - async fn verify<'a, 'b>( - &self, - _evidence: &[u8], - _arpk_file: &'a str, - _hkd_files: &'b str, - ) -> Result> { - Result::Ok("test".as_bytes().to_vec()) + let measurement = + AttestationMeasurement::calculate(items, AttestationMeasAlg::HmacSha512, &meas_key)?; + + let uv_meas = ctx.measurement().ok_or(anyhow!( + "The input is missing the measurement. It is probably no attestation response" + ))?; + if !measurement.eq_secure(uv_meas) { + debug!("Measurement values:"); + debug!("Recieved: {}", HexSlice::from(uv_meas)); + debug!("Calculated: {}", HexSlice::from(measurement.as_ref())); + warn!("Attestation measurement verification failed. Calculated and received attestation measurement are not equal."); + return Ok(ExitCode::from(EXIT_CODE_ATTESTATION_FAIL)); } -} \ No newline at end of file + warn!("Attestation measurement verified"); + // Error impossible CUID is present Attestation verified + let pr_data = VerifyOutput::from_exchange(&ctx, auth.flags())?; + + warn!("{pr_data}"); + serde_yaml::to_writer(output, &pr_data)?; + + // How to get user_data, what's data here??? + if let Some(user_data) = &user_data { + match ctx.user() { + Some(data) => write_file(user_data, data, "user-data")?, + None => { + warn!("Location for `user-data` specified, but respose does not contain any user-data") + } + } + }; + + Ok(ExitCode::SUCCESS) +} + +pub fn create(host_key_documents: Vec, certs: Vec, crls: Vec, arpk_file: String, root_ca: Option) -> Result> { + let att_version = AttestationVersion::One; + let meas_alg = AttestationMeasAlg::HmacSha512; + + let mut att_flags = AttestationFlags::default(); + att_flags.set_image_phkh(); + + let mut arcb = AttestationRequest::new(att_version, meas_alg, att_flags)?; + debug!("Generated Attestation request"); + + let certificate_args = CertificateOptions { + host_key_documents, + no_verify: true, + certs, + crls, + offline: true, + root_ca, + }; + // Add host-key documents + certificate_args + .get_verified_hkds("attestation request")? + .into_iter() + .for_each(|k| arcb.add_hostkey(k)); + debug!("Added all host-keys"); + + let encr_ctx = + ReqEncrCtx::random(SymKeyType::Aes256).context("Failed to generate random input")?; + let ser_arcb = arcb.encrypt(&encr_ctx)?; + warn!("Successfully generated the request"); + + let output: Vec; + let exch_ctx = ExchangeFormatCtx::new_request( + ser_arcb, + meas_alg.exp_size(), + arcb.flags().expected_additional_size().into(), + )?; + exch_ctx.write(&mut output, ExchangeFormatVersion::One)?; + + let arpk = match encr_ctx.prot_key() { + SymKey::Aes256(k) => k, + _ => bail!("Unexpected key type"), + }; + write_file( + &arpk_file, + arpk.value(), + "Attestation request Protection Key", + )?; + + Result::Ok(output) +} diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 56aa4ff37..b9f99da13 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -7,9 +7,9 @@ use super::*; use async_trait::async_trait; use base64::prelude::*; use serde_json::json; +use std::io::Cursor; +use pv::misc::CertificateOptions; use crate::{InitDataHash, ReportData}; -use crate::se::ibmse::FakeSeAttest; -use crate::se::ibmse::SeFakeVerifier; pub mod ibmse; @@ -31,19 +31,13 @@ impl Verifier for SeVerifier { &self, _tee_parameters: String, ) -> Result { - - // TODO replace FakeSeAttest with real IBM SE crate - let attester = FakeSeAttest::default(); - - // TODO replace the placeholder let hkds: Vec = vec![String::new(); 2]; - let certk = "cert_file_path"; - let signk = "sign_file_path"; - let arpk = "arpk_file_path"; + let certs: Vec = vec![String::new(); 2]; + let crls: Vec = vec![]; + let arpk = String::from("arpk_file_path"); + let root_ca = Option::Some(String::from("root_ca")); - let challenge = attester.create(hkds, certk, signk, arpk) - .await - .context("Create SE attestation request failed: {:?}")?; + let challenge = ibmse::create(hkds, certs, crls, arpk, root_ca)?; Ok(BASE64_STANDARD.encode(challenge)) } @@ -54,21 +48,18 @@ async fn verify_evidence( _expected_report_data: &ReportData<'_>, _expected_init_data_hash: &InitDataHash<'_>, ) -> Result { - // TODO replace FakeSeAttest with real IBM SE crate - let attester = FakeSeAttest::default(); - - // TODO replace the placeholder - let arpk = "arpk_file_path"; - let hdr = "hdr_file_path"; + let arpk = String::from("arpk_file_path"); + let hdr = String::from("hdr_file_path"); - let se = attester.verify(evidence, arpk, hdr) - .await - .context("Verify SE attestation evidence failed: {:?}")?; + let mut cursor = Cursor::new(evidence); + let mut output: Vec = vec![]; + let mut userdata: Vec = vec![]; + let _res = ibmse::verify(&mut cursor, hdr, arpk, &mut output, &mut userdata); let claims_map = json!({ "serial_number": format!("{}", "SE-ID"), - "measurement": format!("{}", BASE64_STANDARD.encode(se.clone())), - "report_data": format!("{}", BASE64_STANDARD.encode(se.clone())), + "measurement": format!("{}", BASE64_STANDARD.encode(output.clone())), + "report_data": format!("{}", BASE64_STANDARD.encode(userdata.clone())), }); Ok(claims_map as TeeEvidenceParsedClaim) From a8b6f4dfab39318d9e013a1fce4e081433cd7f60 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Mon, 13 May 2024 18:36:19 +0200 Subject: [PATCH 18/18] transfer POC Signed-off-by: Steffen Eiden --- attestation-service/verifier/src/se/ibmse.rs | 180 ++++++++++++++----- 1 file changed, 140 insertions(+), 40 deletions(-) diff --git a/attestation-service/verifier/src/se/ibmse.rs b/attestation-service/verifier/src/se/ibmse.rs index dfc31f138..203fb50ff 100644 --- a/attestation-service/verifier/src/se/ibmse.rs +++ b/attestation-service/verifier/src/se/ibmse.rs @@ -17,57 +17,157 @@ use pv::{ use serde::Serialize; use serde_yaml; use std::{fmt::Display, io::Read, process::ExitCode}; +use serde_with::base64::{Base64, Bcrypt, BinHex, Standard}; const EXIT_CODE_ATTESTATION_FAIL: u8 = 2; -#[derive(Serialize)] -struct VerifyOutput<'a> { - cuid: HexSlice<'a>, - #[serde(skip_serializing_if = "Option::is_none")] - additional_data: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - additional_data_fields: Option>>, - #[serde(skip_serializing_if = "Option::is_none")] - user_data: Option>, +//TODO implement getters or an into function to convert into pv::AttestationCmd(better approach) +#[serde_as] +#[derive(Debug, Serialize, Deserialize)] +pub struct S390xAttestationRequest { + #[serde_as(as = "Base64")] + request_blob: Vec, + measurement_size: u32, + additional_size: u32, + //not the arpk but the real measuremtn key pv must provide a getter + #[serde_as(as = "Base64")] + encr_measurement_key: Vec, + //not the arpk but the request nonce pv must provide a getter + #[serde_as(as = "Base64")] + encr_request_nonce: Vec, + // IIRC the thing here should be stateless, therefore the request should contain the se header + // as well, right? To save bytes, only the really required bytes are included here. + // + // For this to work I need to add the AsRef<[u8]> impl for that type to pv crate, but that is + // very easy. as you see here: + // + // impl AsRef<[u8]> for BootHdrTags { + // fn as_ref(&self) -> &[u8] { + // self.as_bytes() + // } + // } + #[serde_as(as = "Base64")] + image_hdr_tags: BootHdrTags, } -impl<'a> VerifyOutput<'a> { - fn from_exchange(ctx: &'a ExchangeFormatCtx, flags: &AttestationFlags) -> Result { - let additional_data_fields = ctx - .additional() - .map(|a| AdditionalData::from_slice(a, flags)) - .transpose()?; - let user_data = ctx.user().map(|u| u.into()); - - Ok(Self { - cuid: ctx.config_uid()?.into(), - additional_data: ctx.additional().map(|a| a.into()), - additional_data_fields, - user_data, - }) - } -} -impl<'a> Display for VerifyOutput<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "Config UID:")?; - writeln!(f, "{:#}", self.cuid)?; - if let Some(data) = &self.additional_data { - writeln!(f, "Additional-data:")?; - writeln!(f, "{:#}", data)?; - } - if let Some(data) = &self.additional_data_fields { - writeln!(f, "Additional-data content:")?; - writeln!(f, "{:#}", data)?; +impl S390xAttestationRequest { + +// the caller of this fun then only has to serielize the request in (using serde-json) e.g. json and send it via the + // network + + +pub fn create(hkds: Vec, certs: Vec, crls: Vec, image_hdr_tags: BootHdrTags) -> Result { + let att_version = AttestationVersion::One; + let meas_alg = AttestationMeasAlg::HmacSha512; + + let mut att_flags = AttestationFlags::default(); + let mut arcb = AttestationRequest::new(att_version, meas_alg, att_flags)?; + + let verifier = CertVerifier::new(certs.as_slice(), crls.as_slice(), None, false)?; + + let mut arcb = AttestationRequest::new(att_version, meas_alg, att_flags)?; + for hkd in hkds { + let hk = read_file(hkd, "host-key document")?; + let certs = read_certs(&hk).map_err(|source| Error::HkdNotPemOrDer { + hkd: hkd.to_string(), + source, + })?; + if certs.is_empty() { + todo!(); + } + if certs.len() != 1 { + todo!(); + } + + // Panic: len is == 1 -> unwrap will succeed/not panic + let c = certs.first().unwrap(); + verifier.verify(c)?; + arcb.add_hostkey(c.public_key()?); } - if let Some(data) = &self.user_data { - writeln!(f, "user-data:")?; - writeln!(f, "{:#}", data)?; + let encr_ctx = + ReqEncrCtx::random(SymKeyType::Aes256)?; + let request_blob = arcb.encrypt(&encr_ctx)?; + + let encr_measurement_key = /* TODO encrypt data I need to provide a getter for this in the pv crate*/; + let encr_request_nonce = /* TODO encrypt data I need to provide a getter for this in the pv crate*/; + +Self{ +request_blob, + measurement_size: meas_alg.expected_size(), +additional_size: arcb.flags().expected_additional_size(), +encr_measurement_key, +encr_request_nonce, +image_hdr_tags } - Ok(()) + + } +} +/// the caller of this fn has to deserialize the request first and serialize the result + + +//TODO insert user data +fn poc_calc_measurement(req: &S390xAttestationRequest) -> Result { + + let mut uvc: AttestationCmd = req.into(); //TODO impl Into in this crate + let uv = Uvdevice::open()?; + uv.send_cmd(&mut uvc)?; + + let res = uvc.into(); //TODO impl Into in this crate +Ok(res) + +} + + + +//TODO implement getters or an into function to convert from pv::AttestationCmd(better approach) +//and into +#[derive(Debug, Serialize, Deserialize)] +pub struct S390xAttestationResponse { + #[serde_as(as = "Base64")] + measurement: Vec, + #[serde_as(as = "Base64")] + additional_data: Vec, + #[serde_as(as = "Base64")] + user_data: Vec, + #[serde_as(as = "Base64")] + cuid: ConfigUid, +#[serde_as(as = "Base64")] + encr_measurement_key: Vec, + #[serde_as(as = "Base64")] + encr_request_nonce: Vec, + + #[serde_as(as = "Base64")] + image_hdr_tags: BootHdrTags, +} + +impl S390xAttestationResponse { +fn verify(&self) -> Result { + let meas_key = ...; + let nonce = ...; + + + let meas_key = PKey::hmac(conf.meas_key())?; +let items = AttestationItems::new(self.image_hdr_tags, ....)? + + + let measurement = + AttestationMeasurement::calculate(items, AttestationMeasAlg::HmacSha512, &meas_key)?; + +//todo check measuremt + // do something with additonal data, user_data, .... + } + + + } + + + + + pub fn verify(input: &mut dyn Read, hdr_file: String, arpk_file: String, output: &mut Vec, user_data: &mut Vec) -> Result { let mut img = open_file(&hdr_file)?; let arpk = SymKey::Aes256(