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