1#![doc(html_logo_url = "https://edp.fortanix.com/img/docs/edp-logo.svg",
8 html_favicon_url = "https://edp.fortanix.com/favicon.ico",
9 html_root_url = "https://edp.fortanix.com/docs/api/")]
10
11extern crate enclave_runner;
12extern crate enclave_runner_sgx;
13extern crate anyhow;
14extern crate sgx_isa;
15extern crate sgxs;
16
17use anyhow::Context;
18use enclave_runner::EnclaveBuilder;
19use enclave_runner_sgx::EnclaveBuilder as EnclaveBuilderSgx;
20use sgx_isa::{PageType, Report, SecinfoFlags, Targetinfo, Attributes, AttributesFlags, Miscselect};
21use sgxs::loader::Load;
22use sgxs::sgxs::{PageChunk, SecinfoTruncated, SgxsWrite};
23
24pub struct ReportBuilder {
25 enclave_bytes: Vec<u8>,
26 attributes: Option<Attributes>,
27 miscselect: Option<Miscselect>,
28}
29
30impl ReportBuilder {
31 pub fn new(targetinfo: &Targetinfo) -> ReportBuilder {
32 let mut report_enclave = include_bytes!("../enclave/report.sgxs").to_vec();
33 let mut targetinfo: &[u8] = targetinfo.as_ref();
34 let secinfo = SecinfoTruncated {
35 flags: SecinfoFlags::R | SecinfoFlags::W | PageType::Reg.into(),
36 };
37 report_enclave
38 .write_page(
39 (&mut targetinfo, [PageChunk::Included; 16]),
40 0x3000,
41 secinfo,
42 )
43 .unwrap();
44
45 ReportBuilder {
46 enclave_bytes: report_enclave,
47 attributes: None,
48 miscselect: None
49 }
50 }
51
52 pub fn attributes(mut self, mut attributes: Attributes) -> Self {
53 attributes.flags |= AttributesFlags::MODE64BIT;
54 self.attributes = Some(attributes);
55 self
56 }
57
58 pub fn miscselect(mut self, miscselect: Miscselect) -> Self {
59 self.miscselect = Some(miscselect);
60 self
61 }
62
63 pub fn build<L: Load>(self, enclave_loader: &mut L) -> Result<Report, anyhow::Error> {
64 let mut builder = EnclaveBuilderSgx::new_from_memory(&self.enclave_bytes);
65
66 if let Some(attributes) = self.attributes {
67 builder.attributes(attributes);
68 }
69
70 if let Some(miscselect) = self.miscselect {
71 builder.miscselect(miscselect);
72 }
73
74 unsafe {
75 let mut report = Report::default();
76
77 EnclaveBuilder::<_, enclave_runner::Library>::new(builder)
78 .build(enclave_loader)
79 .context("failed to load report enclave")?
80 .call(&mut report as *mut _ as _, 0, 0, 0, 0)
81 .context("failed to call report enclave")?;
82 Ok(report)
83 }
84 }
85}
86
87pub fn report<L: Load>(targetinfo: &Targetinfo, enclave_loader: &mut L) -> Result<Report, anyhow::Error> {
88 ReportBuilder::new(targetinfo).build(enclave_loader)
89}