1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use std::io::Result as IoResult;

use super::libc::{RTLD_GLOBAL, RTLD_NOW};
use super::dcap_ql_sys::*;
use sgx_isa::{Report, Targetinfo};
use bindings::sgxs_loaders::sgx_enclave_common::dl;
use bindings::sgxs_loaders::sgx_enclave_common::dl::os::unix::Library as Dl;

struct DcapQl {
    _library: dl::Library,
    get_target_info: GetTargetInfoFn,
    get_quote_size: GetQuoteSizeFn,
    get_quote: GetQuoteFn,
}

lazy_static! {
    static ref DCAP_QL: IoResult<DcapQl> = unsafe {
        // Open globally so that `::enclave_loader` can find what it needs
        let library = Dl::open(Some(LIBRARY), RTLD_NOW | RTLD_GLOBAL)?;
        let get_target_info = *library.get::<GetTargetInfoFn>(SYM_GET_TARGET_INFO)?;
        let get_quote_size = *library.get::<GetQuoteSizeFn>(SYM_GET_QUOTE_SIZE)?;
        let get_quote = *library.get::<GetQuoteFn>(SYM_GET_QUOTE)?;
        Ok(DcapQl { _library: library.into(), get_target_info, get_quote_size, get_quote })
    };
}

pub unsafe fn get_target_info(target_info: &mut Targetinfo) -> u32 {
    match *DCAP_QL {
        Ok(ref ql) => (ql.get_target_info)(target_info),
        Err(_) => Quote3Error::InterfaceUnavailable as _,
    }
}

pub unsafe fn get_quote_size(quote_size: &mut u32) -> u32 {
    match *DCAP_QL {
        Ok(ref ql) => (ql.get_quote_size)(quote_size),
        Err(_) => Quote3Error::InterfaceUnavailable as _,
    }
}

pub unsafe fn get_quote(report: &Report, quote_size: u32, quote: *mut u8) -> u32 {
    match *DCAP_QL {
        Ok(ref ql) => (ql.get_quote)(report, quote_size, quote),
        Err(_) => Quote3Error::InterfaceUnavailable as _,
    }
}

pub fn load() -> Result<(), &'static str> {
    if DCAP_QL.is_err() {
        Err("Failed to load sgx_dcap_ql")
    } else {
        Ok(())
    }
}