diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index cf611aa28..1aaa34a05 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -248,9 +248,19 @@ enclave { uint32_t nQuote ); + sgx_status_t ocall_get_quote_ecdsa_collateral( + [in, size=nQuote] const uint8_t* pQuote, + uint32_t nQuote, + [out, size=nCol] uint8_t* pCol, + uint32_t nCol, + [out] uint32_t* pColOut + ); + sgx_status_t ocall_verify_quote_ecdsa( [in, size=nQuote] const uint8_t* pQuote, uint32_t nQuote, + [in, size=nCol] const uint8_t* pCol, + uint32_t nCol, [in] const sgx_target_info_t* pTargetInfo, [out] sgx_ql_qe_report_info_t* p_qve_report_info, [out, size=nSuppData] uint8_t* pSuppData, diff --git a/cosmwasm/enclaves/execute/src/registration/attestation.rs b/cosmwasm/enclaves/execute/src/registration/attestation.rs index e30897bb8..1602ba5c2 100644 --- a/cosmwasm/enclaves/execute/src/registration/attestation.rs +++ b/cosmwasm/enclaves/execute/src/registration/attestation.rs @@ -56,7 +56,8 @@ use enclave_crypto::consts::{ use std::sgxfs::remove as SgxFsRemove; #[cfg(feature = "SGX_MODE_HW")] -use super::ocalls::{ocall_get_ias_socket, ocall_get_quote, ocall_sgx_init_quote, ocall_get_quote_ecdsa_params, ocall_get_quote_ecdsa, ocall_verify_quote_ecdsa}; +use super::ocalls::{ocall_get_ias_socket, ocall_get_quote, ocall_sgx_init_quote, + ocall_get_quote_ecdsa_params, ocall_get_quote_ecdsa, ocall_get_quote_ecdsa_collateral, ocall_verify_quote_ecdsa}; #[cfg(feature = "SGX_MODE_HW")] use super::{hex, report::EndorsedAttestationReport}; @@ -293,7 +294,8 @@ pub fn get_mr_enclave() -> [u8; 32] { #[cfg(feature = "SGX_MODE_HW")] pub fn verify_quote_ecdsa( - vQuote : &Vec + vQuote : &Vec, + vCol : &Vec, ) -> Result<(sgx_report_body_t), sgx_status_t> { let mut qe_report: sgx_ql_qe_report_info_t = sgx_ql_qe_report_info_t::default(); @@ -316,6 +318,8 @@ pub fn verify_quote_ecdsa( &mut rt as *mut sgx_status_t, vQuote.as_ptr(), vQuote.len() as u32, + vCol.as_ptr(), + vCol.len() as u32, &ti, &mut qe_report, pSupp.as_mut_ptr(), @@ -421,10 +425,53 @@ pub fn get_quote_ecdsa( trace!("ocall_get_quote_ecdsa res = {}", res); + + let mut vCol : Vec = Vec::new(); + vCol.resize(0x4000, 0); + let mut nCol : u32 = 0; + + let mut res = unsafe { + ocall_get_quote_ecdsa_collateral( + &mut rt as *mut sgx_status_t, + vQuote.as_ptr(), + vQuote.len() as u32, + vCol.as_mut_ptr(), + vCol.len() as u32, + &mut nCol) + }; + + if res != sgx_status_t::SGX_SUCCESS + { + trace!("res = {}", res); + } + + if rt != sgx_status_t::SGX_SUCCESS + { + trace!("rt = {}", rt); + } + + trace!("Collateral size = {}", nCol); + + let bAgain = nCol > vCol.len() as u32; + vCol.resize(nCol as usize, 0); + + //if bAgain + { + unsafe { + ocall_get_quote_ecdsa_collateral( + &mut rt as *mut sgx_status_t, + vQuote.as_ptr(), + vQuote.len() as u32, + vCol.as_mut_ptr(), + vCol.len() as u32, + &mut nCol) + }; + } + if res == sgx_status_t::SGX_SUCCESS { // test self - let res = match verify_quote_ecdsa(&vQuote) { + let res = match verify_quote_ecdsa(&vQuote, &vCol) { Ok(r) => { r } diff --git a/cosmwasm/enclaves/execute/src/registration/ocalls.rs b/cosmwasm/enclaves/execute/src/registration/ocalls.rs index 4fa5a03f4..195fb386d 100644 --- a/cosmwasm/enclaves/execute/src/registration/ocalls.rs +++ b/cosmwasm/enclaves/execute/src/registration/ocalls.rs @@ -36,10 +36,20 @@ extern "C" { pQuote: *mut u8, nQuote: u32, ) -> sgx_status_t; + pub fn ocall_get_quote_ecdsa_collateral( + ret_val: *mut sgx_status_t, + pQuote: *const u8, + nQuote: u32, + pCol: *mut u8, + nCol: u32, + pColOut: *mut u32 + ) -> sgx_status_t; pub fn ocall_verify_quote_ecdsa( ret_val: *mut sgx_status_t, pQuote: *const u8, nQuote:u32, + pCol: *const u8, + nCol:u32, pTargetInfo: *const sgx_target_info_t, p_qve_report_info: *mut sgx_ql_qe_report_info_t, pSuppData: *mut u8, diff --git a/cosmwasm/packages/sgx-vm/src/attestation.rs b/cosmwasm/packages/sgx-vm/src/attestation.rs index 083c43ceb..79978b774 100644 --- a/cosmwasm/packages/sgx-vm/src/attestation.rs +++ b/cosmwasm/packages/sgx-vm/src/attestation.rs @@ -1,13 +1,14 @@ use std::net::{SocketAddr, TcpStream}; use std::os::unix::io::IntoRawFd; +use core::mem; -use std::{self}; -use std::ptr::null; +use std::{self, ptr}; +use std::ptr::{null, null_mut}; use std::time::{SystemTime, UNIX_EPOCH}; use log::*; use sgx_types::*; -use sgx_types::{sgx_status_t, SgxResult}; +use sgx_types::{sgx_status_t, SgxResult, sgx_ql_qve_collateral_t}; use enclave_ffi_types::{NodeAuthResult, OUTPUT_ENCRYPTED_SEED_SIZE, SINGLE_ENCRYPTED_SEED_SIZE}; @@ -195,10 +196,209 @@ pub extern "C" fn ocall_get_quote_ecdsa( sgx_status_t::SGX_SUCCESS } +pub struct QlQveCollateral { + pub tee_type: u32, // 0x00000000: SGX or 0x00000081: TDX + pub pck_crl_issuer_chain_size: u32, + pub root_ca_crl_size: u32, + pub pck_crl_size: u32, + pub tcb_info_issuer_chain_size: u32, + pub tcb_info_size: u32, + pub qe_identity_issuer_chain_size: u32, + pub qe_identity_size: u32 +} + +fn sgx_ql_qve_collateral_Serialize( + pCol: *const u8, + nCol: u32, + pRes: *mut u8, + nRes: u32, +) -> u32 +{ + if nCol < mem::size_of::() as u32 { + return 0; + } + + unsafe { + let pQlCol = pCol as *const sgx_ql_qve_collateral_t; + + let size_extra = + (*pQlCol).pck_crl_issuer_chain_size + + (*pQlCol).root_ca_crl_size + + (*pQlCol).pck_crl_size + + (*pQlCol).tcb_info_issuer_chain_size + + (*pQlCol).tcb_info_size + + (*pQlCol).qe_identity_issuer_chain_size + + (*pQlCol).qe_identity_size + ; + + if nCol < mem::size_of::() as u32 + size_extra { + return 0; + } + + let outSize: u32 = mem::size_of::() as u32 + size_extra; + + if nRes >= outSize { + + let x = QlQveCollateral { + tee_type : (*pQlCol).tee_type, + pck_crl_issuer_chain_size : (*pQlCol).pck_crl_issuer_chain_size, + root_ca_crl_size : (*pQlCol).root_ca_crl_size, + pck_crl_size : (*pQlCol).pck_crl_size, + tcb_info_issuer_chain_size : (*pQlCol).tcb_info_issuer_chain_size, + tcb_info_size : (*pQlCol).tcb_info_size, + qe_identity_issuer_chain_size : (*pQlCol).qe_identity_issuer_chain_size, + qe_identity_size : (*pQlCol).qe_identity_size + }; + + ptr::copy_nonoverlapping(&x as *const QlQveCollateral as *const u8, pRes, mem::size_of::()); + let mut offs = mem::size_of::(); + + ptr::copy_nonoverlapping((*pQlCol).pck_crl_issuer_chain as *const u8, pRes.add(offs), x.pck_crl_issuer_chain_size as usize); + offs += x.pck_crl_issuer_chain_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).root_ca_crl as *const u8, pRes.add(offs), x.root_ca_crl_size as usize); + offs += x.root_ca_crl_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).pck_crl as *const u8, pRes.add(offs), x.pck_crl_size as usize); + offs += x.pck_crl_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).tcb_info_issuer_chain as *const u8, pRes.add(offs), x.tcb_info_issuer_chain_size as usize); + offs += x.tcb_info_issuer_chain_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).tcb_info as *const u8, pRes.add(offs), x.tcb_info_size as usize); + offs += x.tcb_info_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).qe_identity_issuer_chain as *const u8, pRes.add(offs), x.qe_identity_issuer_chain_size as usize); + offs += x.qe_identity_issuer_chain_size as usize; + + ptr::copy_nonoverlapping((*pQlCol).qe_identity as *const u8, pRes.add(offs), x.qe_identity_size as usize); + offs += x.qe_identity_size as usize; + } + + return outSize; + }; + + 0; // unreachable +} + + +fn sgx_ql_qve_collateral_Deserialize( + pSer: *const u8, + nSer: u32, +) -> sgx_ql_qve_collateral_t +{ + let mut res = sgx_ql_qve_collateral_t { + version: 0, + tee_type: 0, + pck_crl_issuer_chain: null_mut(), + pck_crl_issuer_chain_size: 0, + root_ca_crl: null_mut(), + root_ca_crl_size: 0, + pck_crl: null_mut(), + pck_crl_size: 0, + tcb_info_issuer_chain: null_mut(), + tcb_info_issuer_chain_size: 0, + tcb_info: null_mut(), + tcb_info_size: 0, + qe_identity_issuer_chain: null_mut(), + qe_identity_issuer_chain_size: 0, + qe_identity: null_mut(), + qe_identity_size: 0 + }; + + if nSer >= mem::size_of::() as u32 { + + unsafe { + let pQlCol = pSer as *const QlQveCollateral; + let size_extra = + (*pQlCol).pck_crl_issuer_chain_size + + (*pQlCol).root_ca_crl_size + + (*pQlCol).pck_crl_size + + (*pQlCol).tcb_info_issuer_chain_size + + (*pQlCol).tcb_info_size + + (*pQlCol).qe_identity_issuer_chain_size + + (*pQlCol).qe_identity_size + ; + + if nSer >= mem::size_of::() as u32 + size_extra { + + res.version = 1; // PCK Cert chain is in the Quote. + res.tee_type = (*pQlCol).tee_type; + res.pck_crl_issuer_chain_size = (*pQlCol).pck_crl_issuer_chain_size; + res.root_ca_crl_size = (*pQlCol).root_ca_crl_size; + res.pck_crl_size = (*pQlCol).pck_crl_size; + res.tcb_info_issuer_chain_size = (*pQlCol).tcb_info_issuer_chain_size; + res.tcb_info_size = (*pQlCol).tcb_info_size; + res.qe_identity_issuer_chain_size = (*pQlCol).qe_identity_issuer_chain_size; + res.qe_identity_size = (*pQlCol).qe_identity_size; + + let mut offs = mem::size_of::(); + + res.pck_crl_issuer_chain = pSer.add(offs) as *mut i8; + offs += res.pck_crl_issuer_chain_size as usize; + + res.root_ca_crl = pSer.add(offs) as *mut i8; + offs += res.root_ca_crl_size as usize; + + res.pck_crl = pSer.add(offs) as *mut i8; + offs += res.pck_crl_size as usize; + + res.tcb_info_issuer_chain = pSer.add(offs) as *mut i8; + offs += res.tcb_info_issuer_chain_size as usize; + + res.tcb_info = pSer.add(offs) as *mut i8; + offs += res.tcb_info_size as usize; + + res.qe_identity_issuer_chain = pSer.add(offs) as *mut i8; + offs += res.qe_identity_issuer_chain_size as usize; + + res.qe_identity = pSer.add(offs) as *mut i8; + offs += res.qe_identity_size as usize; + } + } + + }; + + + + return res; // unreachable +} + +#[no_mangle] +pub extern "C" fn ocall_get_quote_ecdsa_collateral( + pQuote: *const u8, + nQuote: u32, + pCol: *mut u8, + nCol: u32, + pColOut: *mut u32 +) -> sgx_status_t +{ + let mut pColMy : *mut u8 = 0 as *mut u8; + let mut nColMy : u32 = 0; + + let ret = unsafe { tee_qv_get_collateral(pQuote, nQuote, &mut pColMy, &mut nColMy) }; + + if ret != sgx_quote3_error_t::SGX_QL_SUCCESS { + trace!("tee_qv_get_collateral returned {}", ret); + return sgx_status_t::SGX_ERROR_UNEXPECTED; + } + + unsafe { + + *pColOut = sgx_ql_qve_collateral_Serialize(pColMy, nColMy, pCol, nCol); + + tee_qv_free_collateral(pColMy); + }; + + sgx_status_t::SGX_SUCCESS +} + #[no_mangle] pub extern "C" fn ocall_verify_quote_ecdsa( pQuote: *const u8, nQuote:u32, + pCol: *const u8, + nCol:u32, pTargetInfo: *const sgx_target_info_t, p_qve_report_info: *mut sgx_ql_qe_report_info_t, pSuppData: *mut u8, @@ -222,9 +422,11 @@ pub extern "C" fn ocall_verify_quote_ecdsa( (*p_qve_report_info).app_enclave_target_info = *pTargetInfo; + let myCol = sgx_ql_qve_collateral_Deserialize(pCol, nCol); + sgx_qv_verify_quote( pQuote, nQuote, - null(), + &myCol, current_time, pCollateral_expiration_status, pQvResult,