dcap_ql/bindings/
mod.rs

1extern crate dcap_ql_sys;
2#[cfg(not(feature = "link"))]
3extern crate libc;
4
5extern crate sgxs_loaders;
6
7use anyhow::Error;
8use anyhow::anyhow;
9use num_traits::FromPrimitive;
10
11pub use self::dcap_ql_sys::Quote3Error;
12use sgx_isa::{Report, Targetinfo};
13use self::sgxs_loaders::sgx_enclave_common::dl::os::unix::Library as Dl;
14use self::sgxs_loaders::sgx_enclave_common::Library as EnclaveCommonLibrary;
15
16#[cfg(feature = "link")]
17use self::dcap_ql_sys::{get_quote, get_quote_size, get_target_info};
18#[cfg(not(feature = "link"))]
19use self::dl::{get_quote, get_quote_size, get_target_info};
20
21#[cfg(not(feature = "link"))]
22mod dl;
23
24fn err_code_to_result(err: u32) -> Result<(), Quote3Error> {
25    match Quote3Error::from_u32(err) {
26        Some(Quote3Error::Success) => Ok(()),
27        Some(e) => Err(e),
28        _ => Err(Quote3Error::InvalidParameter),
29    }
30}
31
32/// Obtain the `Targetinfo` for the Quoting Enclave.
33///
34/// Use this `Targetinfo` when calling `EREPORT` in your enclave to generate
35/// the report that will be passed into `quote()`.
36pub fn target_info() -> Result<Targetinfo, Quote3Error> {
37    unsafe {
38        let mut targetinfo = Targetinfo::default();
39        err_code_to_result(get_target_info(&mut targetinfo))?;
40        Ok(targetinfo)
41    }
42}
43
44/// Turn a `Report` into a quote.
45///
46/// Call the quoting enclave to get a quote. The quoting enclave will sign the
47/// `Report` if the `Report` is valid and generated with the right `Targetinfo`.
48pub fn quote(report: &Report) -> Result<Vec<u8>, Quote3Error> {
49    unsafe {
50        let mut quote_size = 0;
51        err_code_to_result(get_quote_size(&mut quote_size))?;
52
53        let mut quote = vec![0; quote_size as _];
54        err_code_to_result(get_quote(&report, quote_size, quote.as_mut_ptr()))?;
55        Ok(quote)
56    }
57}
58
59/// Returns `true` if the DCAP Quoting Library could be loaded.
60///
61/// This doesn't indicate anything else. For example, loading the quoting
62/// enclave might still fail even if this returns `true`.
63pub fn is_loaded() -> bool {
64    #[cfg(not(feature = "link"))]
65    {
66        dl::load().is_ok()
67    }
68    #[cfg(feature = "link")]
69    {
70        true
71    }
72}
73
74/// Get the enclave loader that is available due to linking with the DCAP
75/// Quoting Library.
76///
77/// Since DCAP is being used, assume that no EINITTOKEN provider is necessary.
78pub fn enclave_loader() -> Result<EnclaveCommonLibrary, Error> {
79    #[cfg(not(feature = "link"))]
80    dl::load().map_err(|e| anyhow!(e))?;
81    // NB. libsgx_dcap_ql.so.1 transitively links to libsgx_enclave_common.so.1
82    // so we should be able to find it already loaded.
83    // We can't use the library from `mod dl` if `not(feature = "link")`,
84    // because that is not the right library.
85    let lib = EnclaveCommonLibrary::load(Some(Dl::this().into()))
86        .or(EnclaveCommonLibrary::load(None))?;
87    Ok(lib.build())
88}