summaryrefslogtreecommitdiffstats
path: root/library/std/src/os/fortanix_sgx/arch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/os/fortanix_sgx/arch.rs')
-rw-r--r--library/std/src/os/fortanix_sgx/arch.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/library/std/src/os/fortanix_sgx/arch.rs b/library/std/src/os/fortanix_sgx/arch.rs
new file mode 100644
index 000000000..8358cb9e8
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/arch.rs
@@ -0,0 +1,80 @@
+//! SGX-specific access to architectural features.
+//!
+//! The functionality in this module is further documented in the Intel
+//! Software Developer's Manual, Volume 3, Chapter 40.
+#![unstable(feature = "sgx_platform", issue = "56975")]
+
+use crate::mem::MaybeUninit;
+use core::arch::asm;
+
+/// Wrapper struct to force 16-byte alignment.
+#[repr(align(16))]
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub struct Align16<T>(pub T);
+
+/// Wrapper struct to force 128-byte alignment.
+#[repr(align(128))]
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub struct Align128<T>(pub T);
+
+/// Wrapper struct to force 512-byte alignment.
+#[repr(align(512))]
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub struct Align512<T>(pub T);
+
+const ENCLU_EREPORT: u32 = 0;
+const ENCLU_EGETKEY: u32 = 1;
+
+/// Call the `EGETKEY` instruction to obtain a 128-bit secret key.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32> {
+ unsafe {
+ let mut out = MaybeUninit::uninit();
+ let error;
+
+ asm!(
+ // rbx is reserved by LLVM
+ "xchg %rbx, {0}",
+ "enclu",
+ "mov {0}, %rbx",
+ inout(reg) request => _,
+ inlateout("eax") ENCLU_EGETKEY => error,
+ in("rcx") out.as_mut_ptr(),
+ options(att_syntax, nostack),
+ );
+
+ match error {
+ 0 => Ok(out.assume_init()),
+ err => Err(err),
+ }
+ }
+}
+
+/// Call the `EREPORT` instruction.
+///
+/// This creates a cryptographic report describing the contents of the current
+/// enclave. The report may be verified by the enclave described in
+/// `targetinfo`.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn ereport(
+ targetinfo: &Align512<[u8; 512]>,
+ reportdata: &Align128<[u8; 64]>,
+) -> Align512<[u8; 432]> {
+ unsafe {
+ let mut report = MaybeUninit::uninit();
+
+ asm!(
+ // rbx is reserved by LLVM
+ "xchg %rbx, {0}",
+ "enclu",
+ "mov {0}, %rbx",
+ inout(reg) targetinfo => _,
+ in("eax") ENCLU_EREPORT,
+ in("rcx") reportdata,
+ in("rdx") report.as_mut_ptr(),
+ options(att_syntax, preserves_flags, nostack),
+ );
+
+ report.assume_init()
+ }
+}