Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LoadPolicyInitializer to mc-sgx-dcap-quoteverify #175

Merged
merged 2 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -188,10 +188,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 @@ -148,14 +148,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 @@ -176,6 +233,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 @@ -347,7 +415,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