Skip to content

Commit

Permalink
Add LoadPolicyInitializer to mc-sgx-dcap-quoteverify (#175)
Browse files Browse the repository at this point in the history
Previously the load policy for the quote verification enclave was set
via `mc-sgx-dcap-quoteverify::load_policy`. Now the
`mc-sgx-dcap-quoteverify::LoadPolicyInitializer` is used to set the load
policy.
  • Loading branch information
nick-mobilecoin authored Oct 20, 2022
2 parents 59abeea + 90554c7 commit 05ac4ee
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `mc-sgx-dcap-ql::set_path` and `mc-sgx-dcap-ql::load_policy` have been
replaced with `mc-sgx-dcap-ql::PathInitializer` and
`mc-sgx-dcap-ql::LoadPolicyInitializer`
- `mc-sgx-dcap-quoteverify::set_path` and
`mc-sgx-dcap-quoteverify::load_policy` have been replaced
with `mc-sgx-dcap-quoteverify::PathInitializer` and
`mc-sgx-dcap-quoteverify::LoadPolicyInitializer`

## [0.2.1] - 2022-10-14

Expand Down
17 changes: 8 additions & 9 deletions dcap/ql/src/quote3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! This functionality requires HW SGX to work correctly otherwise all
//! functionality will return errors.

use crate::Error;
use crate::{Error, LoadPolicyInitializer, PathInitializer};
use mc_sgx_core_types::Report;
use mc_sgx_dcap_types::Quote3;
use mc_sgx_util::ResultInto;
Expand All @@ -14,21 +14,20 @@ use mc_sgx_util::ResultInto;
pub trait TryFromReport {
/// Try to create a [`Quote3`] from the provided [`Report`]
///
/// Note: This will initialize the
/// [`PathInitializer`](crate::PathInitializer) to the defaults if the
/// [`PathInitializer`](crate::PathInitializer) has not been initialized
/// yet. Calling
/// [`PathInitializer::with_paths()`](crate::PathInitializer::with_paths)
/// after calling this function will result in an error.
/// Note: This will initialize the [`PathInitializer`] and
/// [`LoadPolicyInitializer`] to the defaults if they have not been
/// initialized yet. Attempts to initialize [`PathInitializer`] or
/// [`LoadPolicyInitializer`] after calling this function will result in
/// an error.
///
/// # Arguments
/// * `report` - The report to build the quote from
///
/// # Errors
/// Will return an [`Error::Sgx`] if there is a failure from the SGX SDK
fn try_from_report(report: Report) -> Result<Quote3<Vec<u8>>, Error> {
crate::PathInitializer::ensure_initialized()?;
crate::LoadPolicyInitializer::ensure_initialized()?;
PathInitializer::ensure_initialized()?;
LoadPolicyInitializer::ensure_initialized()?;

let mut size = 0;
unsafe { mc_sgx_dcap_ql_sys::sgx_qe_get_quote_size(&mut size) }.into_result()?;
Expand Down
9 changes: 5 additions & 4 deletions dcap/ql/src/quote_enclave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,11 @@ impl PathInitializer {
pub trait QeTargetInfo {
/// The target info of the QE(Quoting Enclave)
///
/// Note: This will initialized the [`PathInitializer`] to the
/// defaults if the [`PathInitializer`] has not been initialized yet.
/// Calling [`PathInitializer::with_paths()`] after calling this function
/// will result in an error.
/// Note: This will initialize the [`PathInitializer`] and
/// [`LoadPolicyInitializer`] to the defaults if they have not been
/// initialized yet. Attempts to initialize [`PathInitializer`] or
/// [`LoadPolicyInitializer`] after calling this function will result in
/// an error.
///
/// # Errors
/// Will return an error if there is a failure from the SGX SDK
Expand Down
4 changes: 2 additions & 2 deletions dcap/quoteverify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod quote_enclave;
mod verify;

use mc_sgx_dcap_types::Quote3Error;
pub use quote_enclave::{load_policy, PathInitializer};
pub use quote_enclave::{LoadPolicyInitializer, PathInitializer};
pub use verify::supplemental_data_size;

/// Errors interacting with quote verification library functions
Expand All @@ -24,7 +24,7 @@ pub enum Error {
PathDoesNotExist(String),
/// Path length is longer than the 259 character bytes allowed
PathLengthTooLong(String),
/// The quoting enclave load policy has already been initialized
/// The quote verification enclave load policy has already been initialized
LoadPolicyInitialized,
}

Expand Down
105 changes: 97 additions & 8 deletions dcap/quoteverify/src/quote_enclave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,71 @@ impl PathInitializer {
}
}

/// Set the load policy
/// Initialization of the load policy for the quote verification enclave
///
/// # Arguments
/// * `policy` - The policy to use for loading quoting enclaves
pub fn load_policy(policy: RequestPolicy) -> Result<()> {
unsafe { mc_sgx_dcap_quoteverify_sys::sgx_qv_set_enclave_load_policy(policy.into()) }
.into_result()?;
Ok(())
/// This should only be called once during process start up utilizing
/// [`LoadPolicyInitializer::policy()`] or
/// [`LoadPolicyInitializer::try_default()`]. If a consumer of this crate does
/// not explicitly initialize the policy, then it will be the default SGX policy
/// of [`RequestPolicy::Persistent`].
#[derive(Debug)]
pub struct LoadPolicyInitializer;
static LOAD_POLICY_INITIALIZER: Lazy<Mutex<Option<LoadPolicyInitializer>>> =
Lazy::new(|| Mutex::new(None));

impl LoadPolicyInitializer {
/// Try to initialize the quote verification enclave load policy to the
/// default
///
/// The default is [`RequestPolicy::Persistent`].
///
/// # Errors
/// * [`Error::LoadPolicyInitialized`] if the policy has been previously
/// initialized.
/// * [`Error::Sgx`] for any errors setting the policy in the SGX SDK.
pub fn try_default() -> Result<()> {
Self::policy(RequestPolicy::Persistent)
}

/// Set the load policy to use for the quote verification enclave
///
/// # Arguments
/// * `policy` - The policy to use for loading the quote verification
/// enclave
///
/// # Errors
/// * [`Error::LoadPolicyInitialized`] if the policy has been previously
/// initialized.
/// * [`Error::Sgx`] for any errors setting the policy in the SGX SDK.
pub fn policy(policy: RequestPolicy) -> Result<()> {
let mut value = LOAD_POLICY_INITIALIZER
.lock()
.expect("Mutex has been poisoned");
if value.is_none() {
unsafe { mc_sgx_dcap_quoteverify_sys::sgx_qv_set_enclave_load_policy(policy.into()) }
.into_result()?;
*value = Some(LoadPolicyInitializer);
Ok(())
} else {
Err(Error::LoadPolicyInitialized)
}
}

/// Will ensure the load policy has been explicity set
///
/// If the load policy has already been set does nothing
///
/// # Errors
/// Will return [`Error::Sgx`] if the load policy has not been initialized
/// and there is an error setting the policy
///
/// Will *not* return an error if the load policy as previously initialized.
pub(crate) fn ensure_initialized() -> Result<()> {
match Self::try_default() {
Ok(_) | Err(Error::LoadPolicyInitialized) => Ok(()),
Err(e) => Err(e),
}
}
}

#[cfg(test)]
Expand All @@ -177,6 +234,17 @@ mod test {
*value = None;
}

/// Resets the [`LOAD_POLICY_INITIALIZER`] to being uninitialized.
/// Since there is *one* [`LOAD_POLICY_INITIALIZER`] for the entire test
/// process any tests focusing on the functionality of the
/// [`LOAD_POLICY_INITIALIZER`] should be utilizing the `#[serial]` macro.
fn reset_load_policy_initializer() {
let mut value = LOAD_POLICY_INITIALIZER
.lock()
.expect("Mutex has been poisoned");
*value = None;
}

#[test]
fn qve_path_succeeds() {
let dir = tempdir().unwrap();
Expand Down Expand Up @@ -348,7 +416,28 @@ mod test {
persistent = { RequestPolicy::Persistent },
ephemeral = { RequestPolicy::Ephemeral },
)]
#[serial]
fn load_policy_succeeds(policy: RequestPolicy) {
assert!(load_policy(policy).is_ok());
reset_load_policy_initializer();
assert_eq!(LoadPolicyInitializer::policy(policy), Ok(()));
}

#[test]
#[serial]
fn load_policy_fails_when_already_initialized() {
reset_load_policy_initializer();
LoadPolicyInitializer::try_default().unwrap();
assert_eq!(
LoadPolicyInitializer::try_default(),
Err(Error::LoadPolicyInitialized)
);
}

#[test]
#[serial]
fn ensuring_the_policy_is_set_is_ok_when_already_set() {
reset_load_policy_initializer();
LoadPolicyInitializer::policy(RequestPolicy::Ephemeral).unwrap();
assert_eq!(LoadPolicyInitializer::ensure_initialized(), Ok(()));
}
}
14 changes: 13 additions & 1 deletion dcap/quoteverify/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@

//! This module contains logic to assist in verifying a DCAP quote

use crate::{Error, PathInitializer};
use crate::{quote_enclave::LoadPolicyInitializer, Error, PathInitializer};
use mc_sgx_util::ResultInto;

/// Get the supplemental data size
///
/// Note: This will initialize the [`PathInitializer`] and
/// [`LoadPolicyInitializer`] to the defaults if they have not been
/// initialized yet. Attempts to initialize [`PathInitializer`] or
/// [`LoadPolicyInitializer`] after calling this function will result in
/// an error.
///
/// # Errors
///
/// [`Error::Sgx`] if there is any error retrieving the supplemental size from
/// SGX.
pub fn supplemental_data_size() -> Result<usize, Error> {
PathInitializer::ensure_initialized()?;
LoadPolicyInitializer::ensure_initialized()?;
let mut size: u32 = 0;
unsafe { mc_sgx_dcap_quoteverify_sys::sgx_qv_get_quote_supplemental_data_size(&mut size) }
.into_result()?;
Expand Down

0 comments on commit 05ac4ee

Please sign in to comment.