mc_sgx_dcap_types/
request_policy.rs

1// Copyright (c) 2022-2024 The MobileCoin Foundation
2
3// ! This module provides types related to request policy
4
5use mc_sgx_core_types::FfiError;
6use mc_sgx_dcap_sys_types::sgx_ql_request_policy_t;
7
8/// Policy used for loading enclaves
9#[non_exhaustive]
10#[derive(Default, Eq, PartialEq, Debug)]
11pub enum RequestPolicy {
12    /// Quoting Enclave is initialized on first use and reused until process
13    /// ends
14    #[default] // Per sgx_pce.h
15    Persistent,
16    /// Quoting Enclave is initialized and terminated on every quote.  if a
17    /// previous quoting enclave exists, it is stopped and restarted before
18    /// quoting.
19    Ephemeral,
20    /// Only used for quote verification, QvE is loaded per thread and be
21    /// unloaded before thread exit.
22    PersistentQveMultiThread,
23    /// Only used for quote verification, QvE is loaded per thread and be
24    /// unloaded before function exit.
25    EphemeralQveMultiThread,
26}
27
28impl TryFrom<sgx_ql_request_policy_t> for RequestPolicy {
29    type Error = FfiError;
30
31    fn try_from(p: sgx_ql_request_policy_t) -> Result<Self, Self::Error> {
32        match p {
33            sgx_ql_request_policy_t::SGX_QL_PERSISTENT => Ok(Self::Persistent),
34            sgx_ql_request_policy_t::SGX_QL_EPHEMERAL => Ok(Self::Ephemeral),
35            sgx_ql_request_policy_t::SGX_QL_PERSISTENT_QVE_MULTI_THREAD => {
36                Ok(Self::PersistentQveMultiThread)
37            }
38            sgx_ql_request_policy_t::SGX_QL_EPHEMERAL_QVE_MULTI_THREAD => {
39                Ok(Self::EphemeralQveMultiThread)
40            }
41            p => Err(FfiError::UnknownEnumValue(p.0.into())),
42        }
43    }
44}
45
46impl From<RequestPolicy> for sgx_ql_request_policy_t {
47    fn from(p: RequestPolicy) -> sgx_ql_request_policy_t {
48        match p {
49            RequestPolicy::Persistent => sgx_ql_request_policy_t::SGX_QL_PERSISTENT,
50            RequestPolicy::Ephemeral => sgx_ql_request_policy_t::SGX_QL_EPHEMERAL,
51            RequestPolicy::PersistentQveMultiThread => {
52                sgx_ql_request_policy_t::SGX_QL_PERSISTENT_QVE_MULTI_THREAD
53            }
54            RequestPolicy::EphemeralQveMultiThread => {
55                sgx_ql_request_policy_t::SGX_QL_EPHEMERAL_QVE_MULTI_THREAD
56            }
57        }
58    }
59}
60
61#[cfg(test)]
62mod test {
63    use super::*;
64    use yare::parameterized;
65
66    #[parameterized(
67    persistent = { sgx_ql_request_policy_t::SGX_QL_PERSISTENT, RequestPolicy::Persistent },
68    ephemeral = { sgx_ql_request_policy_t::SGX_QL_EPHEMERAL, RequestPolicy::Ephemeral },
69    persistent_qve_multi_thread = { sgx_ql_request_policy_t::SGX_QL_PERSISTENT_QVE_MULTI_THREAD, RequestPolicy::PersistentQveMultiThread },
70    ephemeral_qve_multi_thread = { sgx_ql_request_policy_t::SGX_QL_EPHEMERAL_QVE_MULTI_THREAD, RequestPolicy::EphemeralQveMultiThread },
71    defualt = { sgx_ql_request_policy_t::SGX_QL_DEFAULT, RequestPolicy::Persistent },
72    )]
73    fn from_sgx_to_policy(sgx_policy: sgx_ql_request_policy_t, expected: RequestPolicy) {
74        let policy: RequestPolicy = sgx_policy.try_into().unwrap();
75        assert_eq!(policy, expected);
76    }
77
78    #[parameterized(
79    persistent = { RequestPolicy::Persistent, sgx_ql_request_policy_t::SGX_QL_PERSISTENT },
80    ephemeral = { RequestPolicy::Ephemeral, sgx_ql_request_policy_t::SGX_QL_EPHEMERAL },
81    persistent_qve_multi_thread = { RequestPolicy::PersistentQveMultiThread, sgx_ql_request_policy_t::SGX_QL_PERSISTENT_QVE_MULTI_THREAD },
82    ephemeral_qve_multi_thread = { RequestPolicy::EphemeralQveMultiThread, sgx_ql_request_policy_t::SGX_QL_EPHEMERAL_QVE_MULTI_THREAD },
83    )]
84    fn from_policy_to_sgx(policy: RequestPolicy, expected: sgx_ql_request_policy_t) {
85        let sgx_policy: sgx_ql_request_policy_t = policy.into();
86        assert_eq!(sgx_policy, expected);
87    }
88    #[test]
89    fn sgx_policy_out_of_bounds_panics() {
90        let result = RequestPolicy::try_from(sgx_ql_request_policy_t(4));
91        assert!(result.is_err());
92    }
93}