Skip to main content

std/os/fortanix_sgx/
arch.rs

1//! SGX-specific access to architectural features.
2//!
3//! The functionality in this module is further documented in the Intel
4//! Software Developer's Manual, Volume 3, Chapter 40.
5#![unstable(feature = "sgx_platform", issue = "56975")]
6
7use core::arch::asm;
8
9use crate::mem::MaybeUninit;
10
11/// Wrapper struct to force 16-byte alignment.
12#[repr(align(16))]
13#[unstable(feature = "sgx_platform", issue = "56975")]
14pub struct Align16<T>(pub T);
15
16/// Wrapper struct to force 128-byte alignment.
17#[repr(align(128))]
18#[unstable(feature = "sgx_platform", issue = "56975")]
19pub struct Align128<T>(pub T);
20
21/// Wrapper struct to force 512-byte alignment.
22#[repr(align(512))]
23#[unstable(feature = "sgx_platform", issue = "56975")]
24pub struct Align512<T>(pub T);
25
26const ENCLU_EREPORT: u32 = 0;
27const ENCLU_EGETKEY: u32 = 1;
28
29/// Call the `EGETKEY` instruction to obtain a 128-bit secret key.
30#[unstable(feature = "sgx_platform", issue = "56975")]
31pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32> {
32    unsafe {
33        let mut out = MaybeUninit::uninit();
34        let error;
35
36        asm!(
37            // rbx is reserved by LLVM
38            "xchg %rbx, {0}",
39            "enclu",
40            "mov {0}, %rbx",
41            inout(reg) request => _,
42            inlateout("eax") ENCLU_EGETKEY => error,
43            in("rcx") out.as_mut_ptr(),
44            options(att_syntax, nostack),
45        );
46
47        match error {
48            0 => Ok(out.assume_init()),
49            err => Err(err),
50        }
51    }
52}
53
54/// Call the `EREPORT` instruction.
55///
56/// This creates a cryptographic report describing the contents of the current
57/// enclave. The report may be verified by the enclave described in
58/// `targetinfo`.
59#[unstable(feature = "sgx_platform", issue = "56975")]
60pub fn ereport(
61    targetinfo: &Align512<[u8; 512]>,
62    reportdata: &Align128<[u8; 64]>,
63) -> Align512<[u8; 432]> {
64    unsafe {
65        let mut report = MaybeUninit::uninit();
66
67        asm!(
68            // rbx is reserved by LLVM
69            "xchg %rbx, {0}",
70            "enclu",
71            "mov {0}, %rbx",
72            inout(reg) targetinfo => _,
73            in("eax") ENCLU_EREPORT,
74            in("rcx") reportdata,
75            in("rdx") report.as_mut_ptr(),
76            options(att_syntax, preserves_flags, nostack),
77        );
78
79        report.assume_init()
80    }
81}