From 52f0b09051b00ec9cbc8238db8d6c97e64258def Mon Sep 17 00:00:00 2001 From: Qi Feng Huo Date: Wed, 6 Mar 2024 15:23:49 +0800 Subject: [PATCH] Verifier: Add IBM Secure Execution protoc Signed-off-by: Qi Feng Huo --- 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 | 9 +++--- attestation-service/verifier/src/se/mod.rs | 31 +++++++++++++------ .../verifier/src/se/seattest.rs | 12 +++---- kbs/src/api/src/attestation/coco/builtin.rs | 13 +++++++- kbs/src/api/src/attestation/coco/grpc.rs | 7 +++++ kbs/src/api/src/attestation/mod.rs | 2 +- kbs/src/api/src/http/attest.rs | 9 ++++-- kbs/src/api/src/session.rs | 2 +- 15 files changed, 69 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7e56286c9a..c8d8797e7e 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 d3bda03d33..9717dc19f2 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 cd22fa7617..722475d986 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 20d840ee3e..0f25202b78 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 d7daeb739c..b420ddd12e 100644 --- a/attestation-service/attestation-service/src/lib.rs +++ b/attestation-service/attestation-service/src/lib.rs @@ -14,7 +14,7 @@ use crate::token::AttestationTokenBroker; use anyhow::{anyhow, Context, Result}; use config::Config; -pub use kbs_types::{Attestation, Tee}; +pub use kbs_types::{Attestation, Challenge, Tee}; use log::debug; use policy_engine::{PolicyEngine, PolicyEngineType, SetPolicyInput}; use rvps::RvpsApi; @@ -242,7 +242,7 @@ impl AttestationService { pub async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { let verifier = verifier::to_verifier(&tee)?; - verifier.generate_challenge(nonce) + verifier.generate_challenge(nonce).await } } diff --git a/attestation-service/docs/parsed_claims.md b/attestation-service/docs/parsed_claims.md index b783fcfdbe..72d7c25b54 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 405aad923c..fb33a057c6 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 cd22ac3369..1a26e1b8a1 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -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.") } @@ -169,10 +169,11 @@ pub trait Verifier { async fn generate_challenge( &self, - nonce: &str) -> Result { + nonce: &str, + ) -> Result { - Result::Ok(Challenge { - nonce, + Ok(Challenge { + nonce: String::from(nonce), extra_params: String::new(), }) } diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 0e42ca9e2b..5309eade66 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -3,12 +3,12 @@ // 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 kbs_types::Challenge; use crate::{InitDataHash, ReportData}; -use super::{TeeEvidenceParsedClaim, Verifier}; use crate::se::seattest::FakeSeAttest; use crate::se::seattest::SeFakeVerifier; @@ -25,22 +25,31 @@ 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( + &self, + 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)), + + let extra_params = attester.create(hkds, &certk, &signk, &arpk) + .await + .context("Create SE attestation request failed: {:?}")?; + Ok(Challenge { + nonce: String::from(nonce), + extra_params: BASE64_STANDARD.encode(extra_params), }) } } @@ -50,13 +59,15 @@ 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 crate let attester = FakeSeAttest::default(); let arpk = String::new(); let hdr = String::new(); - let se = attester.verify(evidence, arpk, hdr); + 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 2830f5cd28..4084071bb8 100644 --- a/attestation-service/verifier/src/se/seattest.rs +++ b/attestation-service/verifier/src/se/seattest.rs @@ -16,14 +16,14 @@ pub trait SeFakeVerifier { hkdFiles: Vec, certFile: &String, signingFile: &String, - arpkFile: &String + arpkFile: &String, ) -> Result>; async fn verify( &self, - evidence: Vec, + evidence: &[u8], arpkFile: &String, - hdr: Vec + hdr: &String, ) -> Result>; } @@ -34,16 +34,16 @@ impl SeFakeVerifier for FakeSeAttest { hkdFiles: Vec, certFile: &String, signingFile: &String, - arpkFile: &String + arpkFile: &String, ) -> Result> { Result::Ok(Vec::new()) } async fn verify( &self, - evidence: Vec, + evidence: &[u8], arpkFile: &String, - hdr: Vec + hdr: &String, ) -> 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 3f8eb4bac5..3d4bf0309c 100644 --- a/kbs/src/api/src/attestation/coco/builtin.rs +++ b/kbs/src/api/src/attestation/coco/builtin.rs @@ -9,7 +9,7 @@ use attestation_service::{ config::Config as AsConfig, policy_engine::SetPolicyInput, AttestationService, Data, HashAlgorithm, }; -use kbs_types::{Attestation, Tee}; +use kbs_types::{Attestation, Challenge, Tee}; use serde_json::json; use tokio::sync::RwLock; @@ -45,6 +45,17 @@ impl Attest for BuiltInCoCoAs { ) .await } + + async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + self.inner + .read() + .await + .generate_challenge( + tee, + nonce, + ) + .await + } } impl BuiltInCoCoAs { diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 174d76b492..166905d777 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -125,6 +125,13 @@ impl Attest for GrpcClientPool { Ok(token) } + + async fn generate_challenge(&self, tee: Tee, nonce: &str) -> Result { + Ok(Challenge { + nonce: String::from(nonce), + extra_params: String::new(), + }) + } } pub struct GrpcManager { diff --git a/kbs/src/api/src/attestation/mod.rs b/kbs/src/api/src/attestation/mod.rs index c37d3d64ca..d229119352 100644 --- a/kbs/src/api/src/attestation/mod.rs +++ b/kbs/src/api/src/attestation/mod.rs @@ -98,7 +98,7 @@ impl AttestationService { #[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, + AttestationService::CoCoASBuiltIn(inner) => inner.generate_challenge(tee, nonce).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 b46f3b08c8..122da410c9 100644 --- a/kbs/src/api/src/http/attest.rs +++ b/kbs/src/api/src/http/attest.rs @@ -7,7 +7,7 @@ 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 log::{error, info}; use rand::{thread_rng, Rng}; @@ -32,9 +32,12 @@ pub(crate) async fn auth( ) -> Result { info!("request: {:?}", &request); - let challenge = attestation_service.generate_challenge(nonce()?); + let nonce = nonce()?; + let challenge = attestation_service.generate_challenge(request.tee, nonce.as_str()) + .await + .unwrap(); - let session = SessionStatus::auth(request.0, **timeout, challenge) + 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 accc59a71e..44b8cc5436 100644 --- a/kbs/src/api/src/session.rs +++ b/kbs/src/api/src/session.rs @@ -64,7 +64,7 @@ impl SessionStatus { Ok(Self::Authed { request, - challenge, + *challenge, id, timeout, })