summaryrefslogtreecommitdiffstats
path: root/library/std/src/os/fortanix_sgx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/std/src/os/fortanix_sgx/arch.rs80
-rw-r--r--library/std/src/os/fortanix_sgx/ffi.rs41
-rw-r--r--library/std/src/os/fortanix_sgx/io.rs144
-rw-r--r--library/std/src/os/fortanix_sgx/mod.rs53
4 files changed, 318 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()
+ }
+}
diff --git a/library/std/src/os/fortanix_sgx/ffi.rs b/library/std/src/os/fortanix_sgx/ffi.rs
new file mode 100644
index 000000000..ac1db0e5e
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/ffi.rs
@@ -0,0 +1,41 @@
+//! SGX-specific extension to the primitives in the `std::ffi` module
+//!
+//! # Examples
+//!
+//! ```
+//! use std::ffi::OsString;
+//! use std::os::fortanix_sgx::ffi::OsStringExt;
+//!
+//! let bytes = b"foo".to_vec();
+//!
+//! // OsStringExt::from_vec
+//! let os_string = OsString::from_vec(bytes);
+//! assert_eq!(os_string.to_str(), Some("foo"));
+//!
+//! // OsStringExt::into_vec
+//! let bytes = os_string.into_vec();
+//! assert_eq!(bytes, b"foo");
+//! ```
+//!
+//! ```
+//! use std::ffi::OsStr;
+//! use std::os::fortanix_sgx::ffi::OsStrExt;
+//!
+//! let bytes = b"foo";
+//!
+//! // OsStrExt::from_bytes
+//! let os_str = OsStr::from_bytes(bytes);
+//! assert_eq!(os_str.to_str(), Some("foo"));
+//!
+//! // OsStrExt::as_bytes
+//! let bytes = os_str.as_bytes();
+//! assert_eq!(bytes, b"foo");
+//! ```
+
+#![unstable(feature = "sgx_platform", issue = "56975")]
+
+#[path = "../unix/ffi/os_str.rs"]
+mod os_str;
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub use self::os_str::{OsStrExt, OsStringExt};
diff --git a/library/std/src/os/fortanix_sgx/io.rs b/library/std/src/os/fortanix_sgx/io.rs
new file mode 100644
index 000000000..7223ade68
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/io.rs
@@ -0,0 +1,144 @@
+//! SGX-specific extensions to general I/O primitives
+//!
+//! SGX file descriptors behave differently from Unix file descriptors. See the
+//! description of [`TryIntoRawFd`] for more details.
+#![unstable(feature = "sgx_platform", issue = "56975")]
+
+use crate::net;
+pub use crate::sys::abi::usercalls::raw::Fd as RawFd;
+use crate::sys::{self, AsInner, FromInner, IntoInner, TryIntoInner};
+
+/// A trait to extract the raw SGX file descriptor from an underlying
+/// object.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait AsRawFd {
+ /// Extracts the raw file descriptor.
+ ///
+ /// This method does **not** pass ownership of the raw file descriptor
+ /// to the caller. The descriptor is only guaranteed to be valid while
+ /// the original object has not yet been destroyed.
+ #[unstable(feature = "sgx_platform", issue = "56975")]
+ fn as_raw_fd(&self) -> RawFd;
+}
+
+/// A trait to express the ability to construct an object from a raw file
+/// descriptor.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait FromRawFd {
+ /// An associated type that contains relevant metadata for `Self`.
+ type Metadata: Default;
+
+ /// Constructs a new instance of `Self` from the given raw file
+ /// descriptor and metadata.
+ ///
+ /// This function **consumes ownership** of the specified file
+ /// descriptor. The returned object will take responsibility for closing
+ /// it when the object goes out of scope.
+ ///
+ /// This function is also unsafe as the primitives currently returned
+ /// have the contract that they are the sole owner of the file
+ /// descriptor they are wrapping. Usage of this function could
+ /// accidentally allow violating this contract which can cause memory
+ /// unsafety in code that relies on it being true.
+ #[unstable(feature = "sgx_platform", issue = "56975")]
+ unsafe fn from_raw_fd(fd: RawFd, metadata: Self::Metadata) -> Self;
+}
+
+/// A trait to express the ability to consume an object and acquire ownership of
+/// its raw file descriptor.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait TryIntoRawFd: Sized {
+ /// Consumes this object, returning the raw underlying file descriptor, if
+ /// this object is not cloned.
+ ///
+ /// This function **transfers ownership** of the underlying file descriptor
+ /// to the caller. Callers are then the unique owners of the file descriptor
+ /// and must close the descriptor once it's no longer needed.
+ ///
+ /// Unlike other platforms, on SGX, the file descriptor is shared between
+ /// all clones of an object. To avoid race conditions, this function will
+ /// only return `Ok` when called on the final clone.
+ #[unstable(feature = "sgx_platform", issue = "56975")]
+ fn try_into_raw_fd(self) -> Result<RawFd, Self>;
+}
+
+impl AsRawFd for net::TcpStream {
+ #[inline]
+ fn as_raw_fd(&self) -> RawFd {
+ *self.as_inner().as_inner().as_inner().as_inner()
+ }
+}
+
+impl AsRawFd for net::TcpListener {
+ #[inline]
+ fn as_raw_fd(&self) -> RawFd {
+ *self.as_inner().as_inner().as_inner().as_inner()
+ }
+}
+
+/// Metadata for `TcpStream`.
+#[derive(Debug, Clone, Default)]
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub struct TcpStreamMetadata {
+ /// Local address of the TCP stream
+ pub local_addr: Option<String>,
+ /// Peer address of the TCP stream
+ pub peer_addr: Option<String>,
+}
+
+impl FromRawFd for net::TcpStream {
+ type Metadata = TcpStreamMetadata;
+
+ #[inline]
+ unsafe fn from_raw_fd(fd: RawFd, metadata: Self::Metadata) -> net::TcpStream {
+ let fd = sys::fd::FileDesc::from_inner(fd);
+ let socket = sys::net::Socket::from_inner((fd, metadata.local_addr));
+ net::TcpStream::from_inner(sys::net::TcpStream::from_inner((socket, metadata.peer_addr)))
+ }
+}
+
+/// Metadata for `TcpListener`.
+#[derive(Debug, Clone, Default)]
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub struct TcpListenerMetadata {
+ /// Local address of the TCP listener
+ pub local_addr: Option<String>,
+}
+
+impl FromRawFd for net::TcpListener {
+ type Metadata = TcpListenerMetadata;
+
+ #[inline]
+ unsafe fn from_raw_fd(fd: RawFd, metadata: Self::Metadata) -> net::TcpListener {
+ let fd = sys::fd::FileDesc::from_inner(fd);
+ let socket = sys::net::Socket::from_inner((fd, metadata.local_addr));
+ net::TcpListener::from_inner(sys::net::TcpListener::from_inner(socket))
+ }
+}
+
+impl TryIntoRawFd for net::TcpStream {
+ #[inline]
+ fn try_into_raw_fd(self) -> Result<RawFd, Self> {
+ let (socket, peer_addr) = self.into_inner().into_inner();
+ match socket.try_into_inner() {
+ Ok(fd) => Ok(fd.into_inner()),
+ Err(socket) => {
+ let sys = sys::net::TcpStream::from_inner((socket, peer_addr));
+ Err(net::TcpStream::from_inner(sys))
+ }
+ }
+ }
+}
+
+impl TryIntoRawFd for net::TcpListener {
+ #[inline]
+ fn try_into_raw_fd(self) -> Result<RawFd, Self> {
+ match self.into_inner().into_inner().try_into_inner() {
+ Ok(fd) => Ok(fd.into_inner()),
+ Err(socket) => {
+ let sys = sys::net::TcpListener::from_inner(socket);
+ Err(net::TcpListener::from_inner(sys))
+ }
+ }
+ }
+}
diff --git a/library/std/src/os/fortanix_sgx/mod.rs b/library/std/src/os/fortanix_sgx/mod.rs
new file mode 100644
index 000000000..a40dabe19
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/mod.rs
@@ -0,0 +1,53 @@
+//! Functionality specific to the `x86_64-fortanix-unknown-sgx` target.
+//!
+//! This includes functions to deal with memory isolation, usercalls, and the
+//! SGX instruction set.
+
+#![deny(missing_docs)]
+#![unstable(feature = "sgx_platform", issue = "56975")]
+
+/// Low-level interfaces to usercalls. See the [ABI documentation] for more
+/// information.
+///
+/// [ABI documentation]: https://docs.rs/fortanix-sgx-abi/
+pub mod usercalls {
+ pub use crate::sys::abi::usercalls::*;
+
+ /// Primitives for allocating memory in userspace as well as copying data
+ /// to and from user memory.
+ pub mod alloc {
+ pub use crate::sys::abi::usercalls::alloc::*;
+ }
+
+ /// Lowest-level interfaces to usercalls and usercall ABI type definitions.
+ pub mod raw {
+ pub use crate::sys::abi::usercalls::raw::{
+ accept_stream, alloc, async_queues, bind_stream, close, connect_stream, exit, flush,
+ free, insecure_time, launch_thread, read, read_alloc, send, wait, write,
+ };
+ pub use crate::sys::abi::usercalls::raw::{do_usercall, Usercalls as UsercallNrs};
+
+ // fortanix-sgx-abi re-exports
+ pub use crate::sys::abi::usercalls::raw::Error;
+ pub use crate::sys::abi::usercalls::raw::{ByteBuffer, FifoDescriptor, Return, Usercall};
+ pub use crate::sys::abi::usercalls::raw::{Fd, Result, Tcs};
+ pub use crate::sys::abi::usercalls::raw::{
+ EV_RETURNQ_NOT_EMPTY, EV_UNPARK, EV_USERCALLQ_NOT_FULL, FD_STDERR, FD_STDIN, FD_STDOUT,
+ RESULT_SUCCESS, USERCALL_USER_DEFINED, WAIT_INDEFINITE, WAIT_NO,
+ };
+ }
+}
+
+/// Functions for querying mapping information for pointers.
+pub mod mem {
+ pub use crate::sys::abi::mem::*;
+}
+
+pub mod arch;
+pub mod ffi;
+pub mod io;
+
+/// Functions for querying thread-related information.
+pub mod thread {
+ pub use crate::sys::abi::thread::current;
+}