about summary refs log tree commit diff
path: root/library/std/src/os
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/os')
-rw-r--r--library/std/src/os/fortanix_sgx/arch.rs79
-rw-r--r--library/std/src/os/fortanix_sgx/ffi.rs38
-rw-r--r--library/std/src/os/fortanix_sgx/io.rs144
-rw-r--r--library/std/src/os/fortanix_sgx/mod.rs6
4 files changed, 265 insertions, 2 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 00000000000..b0170e67446
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/arch.rs
@@ -0,0 +1,79 @@
+//! 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;
+
+/// 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 {0}, rbx",
+            "enclu",
+            "mov rbx, {0}",
+            inout(reg) request => _,
+            inlateout("eax") ENCLU_EGETKEY => error,
+            in("rcx") out.as_mut_ptr(),
+            options(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 {0}, rbx",
+            "enclu",
+            "mov rbx, {0}",
+            inout(reg) targetinfo => _,
+            in("eax") ENCLU_EREPORT,
+            in("rcx") reportdata,
+            in("rdx") report.as_mut_ptr(),
+            options(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 00000000000..63fc5ff2866
--- /dev/null
+++ b/library/std/src/os/fortanix_sgx/ffi.rs
@@ -0,0 +1,38 @@
+//! 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")]
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub use crate::sys_common::os_str_bytes::*;
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 00000000000..7223ade6815
--- /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
index 69923268e57..a40dabe190a 100644
--- a/library/std/src/os/fortanix_sgx/mod.rs
+++ b/library/std/src/os/fortanix_sgx/mod.rs
@@ -3,7 +3,7 @@
 //! This includes functions to deal with memory isolation, usercalls, and the
 //! SGX instruction set.
 
-#![deny(missing_docs, missing_debug_implementations)]
+#![deny(missing_docs)]
 #![unstable(feature = "sgx_platform", issue = "56975")]
 
 /// Low-level interfaces to usercalls. See the [ABI documentation] for more
@@ -43,7 +43,9 @@ pub mod mem {
     pub use crate::sys::abi::mem::*;
 }
 
-pub use crate::sys::ext::{arch, ffi, io};
+pub mod arch;
+pub mod ffi;
+pub mod io;
 
 /// Functions for querying thread-related information.
 pub mod thread {