diff --git a/attestation-service/docs/parsed_claims.md b/attestation-service/docs/parsed_claims.md index e061004f4..41c8016c2 100644 --- a/attestation-service/docs/parsed_claims.md +++ b/attestation-service/docs/parsed_claims.md @@ -95,11 +95,11 @@ Note: The TD Report and TD Quote are fetched during early boot in this TEE. Kern ## IBM Secure Execution (SE) - `se.version`: The version this quote structure. -- `se.cuid`: The config uid. -- `se.hdr.tag`: SE header tag (seht) +- `se.cuid`: The unique ID of the attested guest (configuration uniqe ID). +- `se.hdr.tag`: SE header tag. - `se.image.phkh`: SE image public host key hash - `se.attestation.phkh`: SE attestation public host key hash -- `se.user_data`: Custom attestation key owner data. +- `se.user_data`: Optional custom attestation owner data, could be key:value pairs collected on guest. ## AMD SEV-SNP diff --git a/attestation-service/verifier/Cargo.toml b/attestation-service/verifier/Cargo.toml index 8dc16e0a7..774b10d51 100644 --- a/attestation-service/verifier/Cargo.toml +++ b/attestation-service/verifier/Cargo.toml @@ -58,4 +58,3 @@ assert-json-diff.workspace = true rstest.workspace = true serial_test.workspace = true tokio.workspace = true - diff --git a/attestation-service/verifier/src/se/ibmse.rs b/attestation-service/verifier/src/se/ibmse.rs index 43fa28d44..53df1f68a 100644 --- a/attestation-service/verifier/src/se/ibmse.rs +++ b/attestation-service/verifier/src/se/ibmse.rs @@ -51,9 +51,7 @@ fn list_files_in_folder(dir: &str) -> Result> { let mut file_paths = Vec::new(); for entry in fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); - + let path = entry?.path(); if path.is_file() { if let Some(path_str) = path.to_str() { file_paths.push(path_str.to_string()); @@ -64,6 +62,7 @@ fn list_files_in_folder(dir: &str) -> Result> { Ok(file_paths) } +#[repr(C)] #[serde_as] #[derive(Debug, Serialize, Deserialize)] pub struct SeAttestationResponse { @@ -100,6 +99,7 @@ pub struct SeAttestationClaims { tag: [u8; 16], } +#[repr(C)] #[serde_as] #[derive(Debug, Serialize, Deserialize)] pub struct SeAttestationRequest { @@ -116,12 +116,12 @@ pub struct SeAttestationRequest { } #[derive(Debug)] -pub struct RealSeVerifier { +pub struct VERIFIER { rsa_private_key: PKey, rsa_public_key: PKey, } -impl RealSeVerifier { +impl VERIFIER { pub fn new() -> Result { let pri_key_file = env_or_default!( "SE_MEASUREMENT_ENCR_KEY_PRIVATE", @@ -150,11 +150,11 @@ impl RealSeVerifier { decrypter.set_rsa_padding(Padding::PKCS1)?; let buffer_len = decrypter.decrypt_len(ciphertext)?; - let mut decrypted_hmac_key = vec![0; buffer_len]; - let decrypted_len = decrypter.decrypt(ciphertext, &mut decrypted_hmac_key)?; - decrypted_hmac_key.truncate(decrypted_len); + let mut decrypted = vec![0; buffer_len]; + let decrypted_len = decrypter.decrypt(ciphertext, &mut decrypted)?; + decrypted.truncate(decrypted_len); - Ok(decrypted_hmac_key) + Ok(decrypted) } fn encrypt(&self, text: &[u8]) -> Result> { @@ -162,11 +162,11 @@ impl RealSeVerifier { encrypter.set_rsa_padding(Padding::PKCS1)?; let buffer_len = encrypter.encrypt_len(text)?; - let mut encrypted_hmac_key = vec![0; buffer_len]; - let len = encrypter.encrypt(text, &mut encrypted_hmac_key)?; - encrypted_hmac_key.truncate(len); + let mut encrypted = vec![0; buffer_len]; + let len = encrypter.encrypt(text, &mut encrypted)?; + encrypted.truncate(len); - Ok(encrypted_hmac_key) + Ok(encrypted) } pub fn evaluate(&self, evidence: &[u8]) -> Result { @@ -182,13 +182,9 @@ impl RealSeVerifier { .decrypt(&se_response.encr_request_nonce) .context("decrypt Request Nonce")?; - if nonce.len() != 16 { - bail!("The nonce vector must have exactly 16 elements."); - } - let nonce_array: [u8; 16] = nonce .try_into() - .map_err(|_| anyhow!("Failed to convert nonce from Vec to [u8; 16]."))?; + .map_err(|_| anyhow!("Failed to convert nonce from Vec to [u8; 16], It must have exactly 16 elements."))?; let meas_key = PKey::hmac(&meas_key)?; let items = AttestationItems::new( @@ -205,12 +201,9 @@ impl RealSeVerifier { if !measurement.eq_secure(&se_response.measurement) { debug!("Recieved: {:?}", se_response.measurement); debug!("Calculated: {:?}", measurement.as_ref()); - warn!("Attestation measurement verification failed. Calculated and received attestation measurement are not equal."); bail!("Failed to verify the measurement!"); } - // TODO check self.user_data.image_btph with previous saved value - let mut att_flags = AttestationFlags::default(); att_flags.set_image_phkh(); att_flags.set_attest_phkh(); @@ -223,8 +216,6 @@ impl RealSeVerifier { .attestation_public_host_key_hash() .ok_or(anyhow!("Failed to get attestation_public_host_key_hash."))?; - // TODO image_phkh and attestation_phkh with previous saved value - let claims = SeAttestationClaims { cuid: se_response.cuid, user_data: se_response.user_data.clone(), @@ -253,10 +244,13 @@ impl RealSeVerifier { let verifier = CertVerifier::new(certs.as_slice(), crls.as_slice(), Some(root_ca_path), false)?; + let mut attestation_flags = AttestationFlags::default(); + attestation_flags.set_image_phkh(); + attestation_flags.set_attest_phkh(); let mut arcb = AttestationRequest::new( AttestationVersion::One, AttestationMeasAlg::HmacSha512, - AttestationFlags::default(), + attestation_flags, )?; let hkds_root = env_or_default!( diff --git a/attestation-service/verifier/src/se/mod.rs b/attestation-service/verifier/src/se/mod.rs index 8704c8fbd..5a0fe6368 100644 --- a/attestation-service/verifier/src/se/mod.rs +++ b/attestation-service/verifier/src/se/mod.rs @@ -5,15 +5,14 @@ use anyhow::Result; use async_trait::async_trait; -use ibmse::RealSeVerifier; -use log::warn; +use ibmse::VERIFIER; use tokio::sync::OnceCell; use crate::{InitDataHash, ReportData, TeeEvidenceParsedClaim, Verifier}; pub mod ibmse; -static ONCE: OnceCell = OnceCell::const_new(); +static ONCE: OnceCell = OnceCell::const_new(); #[derive(Debug, Default)] pub struct SeVerifier; @@ -27,9 +26,9 @@ impl Verifier for SeVerifier { _expected_init_data_hash: &InitDataHash, ) -> Result { let se_verifier = ONCE - .get_or_try_init(|| async { RealSeVerifier::new() }) + .get_or_try_init(|| async { VERIFIER::new() }) .await?; - warn!("IBM SE does not support initdata."); + // IBM SE does not support ReportData and InitDataHash so far. se_verifier.evaluate(evidence) } @@ -38,7 +37,7 @@ impl Verifier for SeVerifier { _tee_parameters: String, ) -> Result { let se_verifier = ONCE - .get_or_try_init(|| async { RealSeVerifier::new() }) + .get_or_try_init(|| async { VERIFIER::new() }) .await?; se_verifier.generate_supplemental_challenge(_tee_parameters).await } diff --git a/kbs/src/api/src/attestation/coco/grpc.rs b/kbs/src/api/src/attestation/coco/grpc.rs index 46b925486..93fefe3f2 100644 --- a/kbs/src/api/src/attestation/coco/grpc.rs +++ b/kbs/src/api/src/attestation/coco/grpc.rs @@ -127,13 +127,8 @@ impl Attest for GrpcClientPool { async fn generate_challenge(&self, tee: Tee, tee_parameters: String) -> Result { let nonce = match tee { Tee::Se => { - let tee = serde_json::to_string(&tee) - .context("CoCo AS client: serialize tee type failed.")? - .trim_end_matches('"') - .trim_start_matches('"') - .to_string(); let mut inner = HashMap::new(); - inner.insert(String::from("tee"), tee); + inner.insert(String::from("tee"), String::from("se")); inner.insert(String::from("tee_params"), tee_parameters); let req = tonic::Request::new(ChallengeRequest { inner });