From c3adfd8814e84ad57bd9d6efc7fc0365e1e4c75d Mon Sep 17 00:00:00 2001 From: valdok Date: Tue, 14 May 2024 07:31:24 +0000 Subject: [PATCH 1/3] check-hw: more info. Saving DCAP quote if it can't be validated --- .../execute/src/registration/attestation.rs | 42 +++++++- .../src/registration/check_patch_level.rs | 99 +++++++++++++------ 2 files changed, 108 insertions(+), 33 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/registration/attestation.rs b/cosmwasm/enclaves/execute/src/registration/attestation.rs index 71747c757..4b0433e7c 100644 --- a/cosmwasm/enclaves/execute/src/registration/attestation.rs +++ b/cosmwasm/enclaves/execute/src/registration/attestation.rs @@ -46,8 +46,8 @@ use std::{ #[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] use crate::registration::cert::verify_ra_cert; -#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] -use crate::registration::offchain::get_attestation_report_dcap; +//#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] +//use crate::registration::offchain::get_attestation_report_dcap; #[cfg(feature = "SGX_MODE_HW")] use enclave_crypto::consts::SIGNING_METHOD; @@ -132,6 +132,32 @@ pub fn create_attestation_certificate( Ok((key_der, cert_der)) } +#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] +pub fn validate_enclave_version_dcap(kp: &KeyPair) -> Result<(), sgx_status_t> { + let (vec_quote, vec_coll) = get_quote_ecdsa_untested(kp)?; + + // test self + match verify_quote_ecdsa(&vec_quote, &vec_coll, 0) { + Ok(r) => { + trace!("Self quote verified ok"); + if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { + // TODO: strict policy wrt own quote verification + trace!("WARNING: {}", r.1); + } + } + Err(e) => { + trace!("Self quote verification failed: {}", e); + + write_to_untrusted(&vec_quote, ATTESTATION_DCAP_PATH.as_str())?; + write_to_untrusted(&vec_coll, COLLATERAL_DCAP_PATH.as_str())?; + + return Err(e); + } + }; + + Ok(()) +} + #[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] pub fn validate_enclave_version( kp: &KeyPair, @@ -139,8 +165,7 @@ pub fn validate_enclave_version( api_key: &[u8], challenge: Option<&[u8]>, ) -> Result<(), sgx_status_t> { - let res_dcap = unsafe { get_attestation_report_dcap(&kp) }; - if res_dcap.is_ok() { + if validate_enclave_version_dcap(kp).is_ok() { return Ok(()); } @@ -438,7 +463,7 @@ pub fn get_quote_ecdsa(_pub_k: &[u8; 32]) -> Result<(Vec, Vec), sgx_stat } #[cfg(feature = "SGX_MODE_HW")] -pub fn get_quote_ecdsa(pub_k: &[u8; 32]) -> Result<(Vec, Vec), sgx_status_t> { +pub fn get_quote_ecdsa_untested(pub_k: &[u8; 32]) -> Result<(Vec, Vec), sgx_status_t> { let mut qe_target_info = sgx_target_info_t::default(); let mut quote_size: u32 = 0; let mut rt: sgx_status_t = sgx_status_t::default(); @@ -527,6 +552,13 @@ pub fn get_quote_ecdsa(pub_k: &[u8; 32]) -> Result<(Vec, Vec), sgx_statu } } + Ok((vec_quote, vec_coll)) +} + +#[cfg(feature = "SGX_MODE_HW")] +pub fn get_quote_ecdsa(pub_k: &[u8; 32]) -> Result<(Vec, Vec), sgx_status_t> { + let (vec_quote, vec_coll) = get_quote_ecdsa_untested(pub_k)?; + // test self match verify_quote_ecdsa(&vec_quote, &vec_coll, 0) { Ok(r) => { diff --git a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs index 83d0a4a46..c69e004bd 100644 --- a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs +++ b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs @@ -15,7 +15,16 @@ use crate::registration::attestation::create_attestation_report; use crate::registration::cert::verify_quote_status; #[cfg(feature = "SGX_MODE_HW")] -use crate::registration::offchain::get_attestation_report_dcap; +use crate::registration::attestation::get_quote_ecdsa_untested; + +#[cfg(feature = "SGX_MODE_HW")] +use crate::registration::attestation::verify_quote_ecdsa; + +#[cfg(feature = "SGX_MODE_HW")] +use enclave_utils::storage::write_to_untrusted; + +#[cfg(feature = "SGX_MODE_HW")] +use crate::sgx_types::sgx_ql_qv_result_t; #[cfg(not(feature = "epid_whitelist_disabled"))] use crate::registration::cert::check_epid_gid_is_whitelisted; @@ -35,11 +44,37 @@ pub unsafe extern "C" fn ecall_check_patch_level( panic!("unimplemented") } -/// # Safety -/// Don't forget to check the input length of api_key_len -#[no_mangle] #[cfg(feature = "SGX_MODE_HW")] -pub unsafe extern "C" fn ecall_check_patch_level( +unsafe fn check_patch_level_dcap(pub_k: &[u8; 32]) -> NodeAuthResult { + match get_quote_ecdsa_untested(pub_k) { + Ok((vec_quote, vec_coll)) => { + match verify_quote_ecdsa(&vec_quote, &vec_coll, 0) { + Ok(r) => { + if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { + println!("WARNING: {}", r.1); + } + + println!("DCAP attestation obtained and verified ok"); + return NodeAuthResult::Success; + } + Err(e) => { + println!("DCAP quote obtained, but failed to verify it: {}", e); + + let _ = write_to_untrusted(&vec_quote, "dcap_quote.bin"); + let _ = write_to_untrusted(&vec_coll, "dcap_collateral.bin"); + } + }; + } + Err(e) => { + println!("Failed to obtain DCAP attestation: {}", e); + } + } + return NodeAuthResult::InvalidCert; +} + +#[cfg(feature = "SGX_MODE_HW")] +unsafe fn check_patch_level_epid( + pub_k: &[u8; 32], api_key: *const u8, api_key_len: u32, ) -> NodeAuthResult { @@ -51,29 +86,14 @@ pub unsafe extern "C" fn ecall_check_patch_level( let api_key_slice = slice::from_raw_parts(api_key, api_key_len as usize); - // CREATE THE ATTESTATION REPORT - // generate temporary key for attestation - let temp_key_result = enclave_crypto::KeyPair::new().unwrap(); - - let res_dcap = unsafe { get_attestation_report_dcap(&temp_key_result) }; - if res_dcap.is_ok() { - println!("DCAP attestation ok"); - return NodeAuthResult::Success; - } - - let signed_report = match create_attestation_report( - &temp_key_result.get_pubkey(), - SIGNATURE_TYPE, - api_key_slice, - None, - true, - ) { - Ok(r) => r, - Err(_e) => { - error!("Error creating attestation report"); - return NodeAuthResult::InvalidCert; - } - }; + let signed_report = + match create_attestation_report(pub_k, SIGNATURE_TYPE, api_key_slice, None, true) { + Ok(r) => r, + Err(_e) => { + error!("Error creating attestation report"); + return NodeAuthResult::InvalidCert; + } + }; let payload: String = serde_json::to_string(&signed_report) .map_err(|_| { @@ -151,3 +171,26 @@ pub unsafe extern "C" fn ecall_check_patch_level( _ => NodeAuthResult::Success, } } + +/// # Safety +/// Don't forget to check the input length of api_key_len +#[no_mangle] +#[cfg(feature = "SGX_MODE_HW")] +pub unsafe extern "C" fn ecall_check_patch_level( + api_key: *const u8, + api_key_len: u32, +) -> NodeAuthResult { + let temp_key_result = enclave_crypto::KeyPair::new().unwrap(); + + let res1 = check_patch_level_dcap(&temp_key_result.get_pubkey()); + let res2 = check_patch_level_epid(&temp_key_result.get_pubkey(), api_key, api_key_len); + + println!("DCAP attestation: {}", res1); + println!("EPID attestation: {}", res2); + + if NodeAuthResult::Success == res1 { + return res1; + } + + return res2; +} From 38bd434cbd44108662d81711b51018a96b7418ab Mon Sep 17 00:00:00 2001 From: valdok Date: Tue, 14 May 2024 07:36:07 +0000 Subject: [PATCH 2/3] build fix --- .../execute/src/registration/attestation.rs | 33 +++---------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/registration/attestation.rs b/cosmwasm/enclaves/execute/src/registration/attestation.rs index 4b0433e7c..7ee79ed52 100644 --- a/cosmwasm/enclaves/execute/src/registration/attestation.rs +++ b/cosmwasm/enclaves/execute/src/registration/attestation.rs @@ -46,8 +46,8 @@ use std::{ #[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] use crate::registration::cert::verify_ra_cert; -//#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] -//use crate::registration::offchain::get_attestation_report_dcap; +#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] +use crate::registration::offchain::get_attestation_report_dcap; #[cfg(feature = "SGX_MODE_HW")] use enclave_crypto::consts::SIGNING_METHOD; @@ -132,32 +132,6 @@ pub fn create_attestation_certificate( Ok((key_der, cert_der)) } -#[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] -pub fn validate_enclave_version_dcap(kp: &KeyPair) -> Result<(), sgx_status_t> { - let (vec_quote, vec_coll) = get_quote_ecdsa_untested(kp)?; - - // test self - match verify_quote_ecdsa(&vec_quote, &vec_coll, 0) { - Ok(r) => { - trace!("Self quote verified ok"); - if r.1 != sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK { - // TODO: strict policy wrt own quote verification - trace!("WARNING: {}", r.1); - } - } - Err(e) => { - trace!("Self quote verification failed: {}", e); - - write_to_untrusted(&vec_quote, ATTESTATION_DCAP_PATH.as_str())?; - write_to_untrusted(&vec_coll, COLLATERAL_DCAP_PATH.as_str())?; - - return Err(e); - } - }; - - Ok(()) -} - #[cfg(all(feature = "SGX_MODE_HW", feature = "production"))] pub fn validate_enclave_version( kp: &KeyPair, @@ -165,7 +139,8 @@ pub fn validate_enclave_version( api_key: &[u8], challenge: Option<&[u8]>, ) -> Result<(), sgx_status_t> { - if validate_enclave_version_dcap(kp).is_ok() { + let res_dcap = unsafe { get_attestation_report_dcap(&kp) }; + if res_dcap.is_ok() { return Ok(()); } From 99145a34b8099a3e9b9b54a821d98b0599512106 Mon Sep 17 00:00:00 2001 From: valdok Date: Tue, 14 May 2024 07:47:44 +0000 Subject: [PATCH 3/3] build fix (2) --- .../enclaves/execute/src/registration/check_patch_level.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs index c69e004bd..4ea2b1d49 100644 --- a/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs +++ b/cosmwasm/enclaves/execute/src/registration/check_patch_level.rs @@ -69,7 +69,7 @@ unsafe fn check_patch_level_dcap(pub_k: &[u8; 32]) -> NodeAuthResult { println!("Failed to obtain DCAP attestation: {}", e); } } - return NodeAuthResult::InvalidCert; + NodeAuthResult::InvalidCert } #[cfg(feature = "SGX_MODE_HW")] @@ -192,5 +192,5 @@ pub unsafe extern "C" fn ecall_check_patch_level( return res1; } - return res2; + res2 }