Skip to content

Commit

Permalink
Merge pull request #343 from 0xbillw/refactor/ceseal-measurement
Browse files Browse the repository at this point in the history
refactor: change the `measurement` of `ceseal` to its corresponding hash value (H256 type) and improve the display of version information
  • Loading branch information
0xbillw authored May 9, 2024
2 parents 8656637 + 19ef29c commit edcadae
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 80 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions crates/ces-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ edition = "2021"
[dependencies]
chrono = { workspace = true }
hex = { workspace = true, features = ["alloc"] }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, features = ["alloc"] }
log ={ workspace = true }
parity-scale-codec = { workspace = true, features = ["full"] }
scale-info = { workspace = true, features = ["derive"] }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, features = ["alloc"] }
sp-core = { workspace = true }
sp-std = { workspace = true }

Expand Down
64 changes: 51 additions & 13 deletions crates/ces-types/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod ias_quote_consts {
use ias_quote_consts::*;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_core::H256;
use sp_std::vec::Vec;

#[cfg(feature = "enable_serde")]
Expand Down Expand Up @@ -49,7 +50,45 @@ pub enum Error {
pub struct ConfidentialReport {
pub confidence_level: u8,
pub provider: Option<AttestationProvider>,
pub runtime_hash: Vec<u8>,
pub measurement_hash: H256,
}

fn fixed_measurement(mr_enclave: &[u8], isv_prod_id: &[u8], isv_svn: &[u8], mr_signer: &[u8]) -> Vec<u8> {
let mut data = Vec::new();
data.extend_from_slice(mr_enclave);
data.extend_from_slice(isv_prod_id);
data.extend_from_slice(isv_svn);
data.extend_from_slice(mr_signer);
data
}

#[cfg(feature = "full_crypto")]
fn fixed_measurement_hash(data: &[u8]) -> H256 {
H256(sp_core::blake2_256(data))
}

#[cfg(not(feature = "full_crypto"))]
fn fixed_measurement_hash(data: &[u8]) -> H256 {
log::error!("The measurement hash must be in SGX enviroment with \"full_crypto\" feature, now return zero");
H256::default()
}

#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq)]
pub struct ExtendMeasurement {
pub mr_enclave: [u8; 32],
pub mr_signer: [u8; 32],
pub isv_prod_id: [u8; 2],
pub isv_svn: [u8; 2],
}

impl ExtendMeasurement {
pub fn measurement(&self) -> Vec<u8> {
fixed_measurement(&self.mr_enclave, &self.isv_prod_id, &self.isv_svn, &self.mr_signer)
}

pub fn measurement_hash(&self) -> H256 {
fixed_measurement_hash(&self.measurement()[..])
}
}

#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -121,13 +160,12 @@ impl IasFields {
))
}

pub fn extend_mrenclave(&self) -> Vec<u8> {
let mut t_mrenclave = Vec::new();
t_mrenclave.extend_from_slice(&self.mr_enclave);
t_mrenclave.extend_from_slice(&self.isv_prod_id);
t_mrenclave.extend_from_slice(&self.isv_svn);
t_mrenclave.extend_from_slice(&self.mr_signer);
t_mrenclave
pub fn measurement(&self) -> Vec<u8> {
fixed_measurement(&self.mr_enclave, &self.isv_prod_id, &self.isv_svn, &self.mr_signer)
}

pub fn measurement_hash(&self) -> H256 {
fixed_measurement_hash(&self.measurement()[..])
}
}

Expand All @@ -136,7 +174,7 @@ pub fn validate(
user_data_hash: &[u8; 32],
now: u64,
verify_ceseal_hash: bool,
ceseal_bin_allowlist: Vec<Vec<u8>>,
ceseal_bin_allowlist: Vec<H256>,
opt_out_enabled: bool,
) -> Result<ConfidentialReport, Error> {
match attestation {
Expand All @@ -151,7 +189,7 @@ pub fn validate(
),
None =>
if opt_out_enabled {
Ok(ConfidentialReport { provider: None, runtime_hash: Vec::new(), confidence_level: 128u8 })
Ok(ConfidentialReport { provider: None, measurement_hash: Default::default(), confidence_level: 128u8 })
} else {
Err(Error::NoneAttestationDisabled)
},
Expand All @@ -165,7 +203,7 @@ pub fn validate_ias_report(
raw_signing_cert: &[u8],
now: u64,
verify_ceseal_hash: bool,
ceseal_bin_allowlist: Vec<Vec<u8>>,
ceseal_bin_allowlist: Vec<H256>,
) -> Result<ConfidentialReport, Error> {
// Validate report
sgx_attestation::ias::verify_signature(report, signature, raw_signing_cert, core::time::Duration::from_secs(now))
Expand All @@ -174,7 +212,7 @@ pub fn validate_ias_report(
let (ias_fields, report_timestamp) = IasFields::from_ias_report(report)?;

// Validate Ceseal
let ceseal_hash = ias_fields.extend_mrenclave();
let ceseal_hash = ias_fields.measurement_hash();
if verify_ceseal_hash && !ceseal_bin_allowlist.contains(&ceseal_hash) {
return Err(Error::CesealRejected)
}
Expand All @@ -192,7 +230,7 @@ pub fn validate_ias_report(
// Check the following fields
Ok(ConfidentialReport {
provider: Some(AttestationProvider::Ias),
runtime_hash: ceseal_hash,
measurement_hash: ceseal_hash,
confidence_level: ias_fields.confidence_level,
})
}
Expand Down
22 changes: 11 additions & 11 deletions crates/ces-types/src/attestation/legacy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{ias_quote_consts::*, Error};
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_core::H256;
use sp_std::vec::Vec;

#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq)]
Expand All @@ -15,7 +16,7 @@ pub trait AttestationValidator {
user_data_hash: &[u8; 32],
now: u64,
verify_ceseal_hash: bool,
ceseal_bin_allowlist: Vec<Vec<u8>>,
ceseal_bin_allowlist: Vec<H256>,
) -> Result<IasFields, Error>;
}

Expand Down Expand Up @@ -86,13 +87,12 @@ impl IasFields {
))
}

pub fn extend_mrenclave(&self) -> Vec<u8> {
let mut t_mrenclave = Vec::new();
t_mrenclave.extend_from_slice(&self.mr_enclave);
t_mrenclave.extend_from_slice(&self.isv_prod_id);
t_mrenclave.extend_from_slice(&self.isv_svn);
t_mrenclave.extend_from_slice(&self.mr_signer);
t_mrenclave
pub fn measurement(&self) -> Vec<u8> {
super::fixed_measurement(&self.mr_enclave, &self.isv_prod_id, &self.isv_svn, &self.mr_signer)
}

pub fn measurement_hash(&self) -> H256 {
super::fixed_measurement_hash(&self.measurement()[..])
}
}

Expand All @@ -104,7 +104,7 @@ impl AttestationValidator for IasValidator {
user_data_hash: &[u8; 32],
now: u64,
verify_ceseal: bool,
ceseal_bin_allowlist: Vec<Vec<u8>>,
ceseal_bin_allowlist: Vec<H256>,
) -> Result<IasFields, Error> {
let fields = match attestation {
Attestation::SgxIas { ra_report, signature, raw_signing_cert } =>
Expand All @@ -125,7 +125,7 @@ pub fn validate_ias_report(
raw_signing_cert: &[u8],
now: u64,
verify_ceseal: bool,
ceseal_bin_allowlist: Vec<Vec<u8>>,
ceseal_bin_allowlist: Vec<H256>,
) -> Result<IasFields, Error> {
// Validate report
sgx_attestation::ias::verify_signature(report, signature, raw_signing_cert, core::time::Duration::from_secs(now))
Expand All @@ -135,7 +135,7 @@ pub fn validate_ias_report(

// Validate Ceseal
if verify_ceseal {
let t_mrenclave = ias_fields.extend_mrenclave();
let t_mrenclave = ias_fields.measurement_hash();
if !ceseal_bin_allowlist.contains(&t_mrenclave) {
return Err(Error::CesealRejected)
}
Expand Down
15 changes: 6 additions & 9 deletions crates/cestory/pal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! Platform abstraction layer for Trusted Execution Environments

use std::fmt::Debug;
use std::path::Path;
use core::time::Duration;

use ces_types::AttestationProvider;
use core::time::Duration;
use std::{fmt::Debug, path::Path};

pub use ces_types::attestation::ExtendMeasurement;
pub use cestory_api::crpc::MemoryUsage;

pub trait ErrorType: Debug + Into<anyhow::Error> {}
Expand All @@ -28,7 +27,8 @@ pub trait RA {
timeout: Duration,
) -> Result<Vec<u8>, Self::Error>;
fn quote_test(&self, provider: Option<AttestationProvider>) -> Result<(), Self::Error>;
fn measurement(&self) -> Option<Vec<u8>>;
fn mr_enclave(&self) -> Option<Vec<u8>>;
fn extend_measurement(&self) -> Result<ExtendMeasurement, Self::Error>;
}

pub trait MemoryStats {
Expand All @@ -51,8 +51,5 @@ pub trait AppInfo {
fn app_version() -> AppVersion;
}

pub trait Platform:
Sealing + RA + Machine + MemoryStats + AppInfo + Clone + Send + 'static
{
}
pub trait Platform: Sealing + RA + Machine + MemoryStats + AppInfo + Clone + Send + 'static {}
impl<T: Sealing + RA + Machine + MemoryStats + AppInfo + Clone + Send + 'static> Platform for T {}
23 changes: 21 additions & 2 deletions crates/cestory/src/ceseal_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ impl<Platform: pal::Platform + Serialize + DeserializeOwned> CesealApi for RpcSe
report_data: [0; 64],
confidence_level: 0,
};
ias_fields.extend_mrenclave()
ias_fields.measurement_hash()
};
let runtime_state = cestory.runtime_state()?;
let my_runtime_timestamp = runtime_state
Expand All @@ -358,7 +358,7 @@ impl<Platform: pal::Platform + Serialize + DeserializeOwned> CesealApi for RpcSe
AttestationReport::SgxIas { ra_report, signature: _, raw_signing_cert: _ } => {
let (ias_fields, _) =
IasFields::from_ias_report(&ra_report).map_err(|_| from_display("Invalid client RA report"))?;
ias_fields.extend_mrenclave()
ias_fields.measurement_hash()
},
};
let req_runtime_timestamp = runtime_state
Expand Down Expand Up @@ -877,6 +877,25 @@ impl<Platform: pal::Platform + Serialize + DeserializeOwned> Ceseal<Platform> {
self.args.ra_timeout,
self.args.ra_max_retries,
)?;
{
let mut encoded_report = &report.encoded_report[..];
let report: Option<AttestationReport> = Decode::decode(&mut encoded_report)?;
if let Some(report) = report {
match report {
AttestationReport::SgxIas { ra_report, .. } => {
match IasFields::from_ias_report(&ra_report[..]) {
Ok((ias_fields, _)) => {
info!("measurement :{}", hex::encode(ias_fields.measurement()));
info!("measurement hash :{}", ias_fields.measurement_hash());
},
Err(e) => {
error!("deserial ias report to IasFields failed: {:?}", e);
},
}
},
}
}
}
cached_resp.attestation = Some(report);
}

Expand Down
14 changes: 12 additions & 2 deletions crates/cestory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,18 @@ impl<P: pal::Platform> Ceseal<P> {
let chain_storage = &self.runtime_state.as_ref().expect("BUG: no runtime state").chain_storage.read();
let min_version = chain_storage.minimum_ceseal_version();

let measurement = self.platform.measurement().unwrap_or_else(|| vec![0; 32]);
let in_whitelist = chain_storage.is_ceseal_bin_in_whitelist(&measurement);
let in_whitelist: bool;
if cfg!(feature = "verify-cesealbin") {
in_whitelist = match self.platform.extend_measurement() {
Ok(em) => chain_storage.is_ceseal_bin_in_whitelist(&em.measurement_hash()),
Err(_) => {
warn!("The verify-cesealbin feature enabled, but not in SGX enviroment, ignore whitelist check");
true
},
};
} else {
in_whitelist = true;
}

if (ver.major, ver.minor, ver.patch) < min_version && !in_whitelist {
error!("This ceseal is outdated. Please update to the latest version.");
Expand Down
12 changes: 4 additions & 8 deletions crates/cestory/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mod storage_ext {
use log::error;
use parity_scale_codec::{Decode, Error};
use serde::{Deserialize, Serialize};
use sp_core::H256;
use sp_state_machine::{Ext, OverlayedChanges};

#[derive(Serialize, Deserialize, Default)]
Expand Down Expand Up @@ -141,7 +142,7 @@ mod storage_ext {
}

/// Return `None` if given ceseal hash is not allowed on-chain
pub(crate) fn get_ceseal_bin_added_at(&self, runtime_hash: &[u8]) -> Option<chain::BlockNumber> {
pub(crate) fn get_ceseal_bin_added_at(&self, runtime_hash: &H256) -> Option<chain::BlockNumber> {
self.execute_with(|| pallet_tee_worker::CesealBinAddedAt::<chain::Runtime>::get(runtime_hash))
}

Expand All @@ -165,14 +166,9 @@ mod storage_ext {
self.execute_with(pallet_tee_worker::MinimumCesealVersion::<chain::Runtime>::get)
}

pub(crate) fn is_ceseal_bin_in_whitelist(&self, measurement: &[u8]) -> bool {
pub(crate) fn is_ceseal_bin_in_whitelist(&self, measurement: &H256) -> bool {
let list = self.execute_with(pallet_tee_worker::CesealBinAllowList::<chain::Runtime>::get);
for hash in list.iter() {
if hash.starts_with(measurement) {
return true
}
}
false
list.contains(measurement)
}
}
}
9 changes: 5 additions & 4 deletions pallets/tee-worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub mod pallet {
use codec::{Decode, Encode};
use frame_support::dispatch::DispatchResult;
use scale_info::TypeInfo;
use sp_core::H256;

use ces_pallet_mq::MessageOriginInfo;
use ces_types::{
Expand Down Expand Up @@ -238,11 +239,11 @@ pub mod pallet {
/// Only ceseal within the list can register.
#[pallet::storage]
#[pallet::getter(fn ceseal_bin_allowlist)]
pub type CesealBinAllowList<T: Config> = StorageValue<_, Vec<Vec<u8>>, ValueQuery>;
pub type CesealBinAllowList<T: Config> = StorageValue<_, Vec<H256>, ValueQuery>;

/// The effective height of ceseal binary
#[pallet::storage]
pub type CesealBinAddedAt<T: Config> = StorageMap<_, Twox64Concat, Vec<u8>, BlockNumberFor<T>>;
pub type CesealBinAddedAt<T: Config> = StorageMap<_, Twox64Concat, H256, BlockNumberFor<T>>;

/// Mapping from worker pubkey to CESS Network identity
#[pallet::storage]
Expand Down Expand Up @@ -673,7 +674,7 @@ pub mod pallet {
/// Can only be called by `GovernanceOrigin`.
#[pallet::call_index(19)]
#[pallet::weight({0})]
pub fn add_ceseal(origin: OriginFor<T>, ceseal_hash: Vec<u8>) -> DispatchResult {
pub fn add_ceseal(origin: OriginFor<T>, ceseal_hash: H256) -> DispatchResult {
T::GovernanceOrigin::ensure_origin(origin)?;

let mut allowlist = CesealBinAllowList::<T>::get();
Expand All @@ -693,7 +694,7 @@ pub mod pallet {
/// Can only be called by `GovernanceOrigin`.
#[pallet::call_index(110)]
#[pallet::weight({0})]
pub fn remove_ceseal(origin: OriginFor<T>, ceseal_hash: Vec<u8>) -> DispatchResult {
pub fn remove_ceseal(origin: OriginFor<T>, ceseal_hash: H256) -> DispatchResult {
T::GovernanceOrigin::ensure_origin(origin)?;

let mut allowlist = CesealBinAllowList::<T>::get();
Expand Down
1 change: 1 addition & 0 deletions standalone/teeworker/ceseal/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit edcadae

Please sign in to comment.