diff --git a/library/Cargo.lock b/library/Cargo.lock index 97996d5f0b258..82b527a9561ef 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -92,9 +92,8 @@ dependencies = [ [[package]] name = "fortanix-sgx-abi" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5" +version = "0.6.0" +source = "git+https://github.com/fortanix/rust-sgx.git?branch=master#52c797d83b5351376b8561d50ecf9f4af2c84068" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -156,6 +155,16 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "insecure-time" +version = "0.1.0" +source = "git+https://github.com/fortanix/rust-sgx.git?branch=master#52c797d83b5351376b8561d50ecf9f4af2c84068" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + [[package]] name = "libc" version = "0.2.162" @@ -334,6 +343,7 @@ dependencies = [ "fortanix-sgx-abi", "hashbrown", "hermit-abi", + "insecure-time", "libc", "miniz_oxide", "object", diff --git a/library/Cargo.toml b/library/Cargo.toml index e744cfe5e0f57..88027b801f8b5 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -45,3 +45,4 @@ rustc-demangle.debug = 0 rustc-std-workspace-core = { path = 'rustc-std-workspace-core' } rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' } rustc-std-workspace-std = { path = 'rustc-std-workspace-std' } +fortanix-sgx-abi = { git = "https://github.com/fortanix/rust-sgx.git", branch = "master" } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c1ab70b714a4c..4c9e00e651af7 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -67,9 +67,10 @@ rand_xorshift = "0.3.0" dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] } [target.x86_64-fortanix-unknown-sgx.dependencies] -fortanix-sgx-abi = { version = "0.5.0", features = [ +fortanix-sgx-abi = { version = "0.6.0", features = [ 'rustc-dep-of-std', ], public = true } +insecure-time = { version = "0.1", git = "https://github.com/fortanix/rust-sgx.git", branch = "master", default-features = false, features = ["rustc-dep-of-std"] } [target.'cfg(target_os = "hermit")'.dependencies] hermit-abi = { version = "0.4.0", features = [ diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index 5069ab82ccc90..876b42bb01a40 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -59,6 +59,8 @@ unsafe impl UserSafeSized for Return {} unsafe impl UserSafeSized for Cancel {} #[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafeSized for [T; 2] {} +#[unstable(feature = "sgx_platform", issue = "56975")] +unsafe impl UserSafeSized for InsecureTimeInfo {} /// A type that can be represented in memory as one or more `UserSafeSized`s. #[unstable(feature = "sgx_platform", issue = "56975")] diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index 90b9b59471a52..12ced50495ae2 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -1,7 +1,10 @@ use crate::cmp; use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult}; use crate::random::{DefaultRandomSource, Random}; +use crate::sync::OnceLock; use crate::time::{Duration, Instant}; +use crate::ops::Add; +use insecure_time::{Freq, Tsc, TscBuilder, LearningFreqTscBuilder, NativeTime, NoRdtscTscBuilder}; pub(crate) mod alloc; #[macro_use] @@ -10,6 +13,7 @@ pub(crate) mod raw; mod tests; use self::raw::*; +use self::alloc::UserRef; /// Usercall `read`. See the ABI documentation for more information. /// @@ -249,11 +253,79 @@ pub fn send(event_set: u64, tcs: Option) -> IoResult<()> { unsafe { raw::send(event_set, tcs).from_sgx_result() } } +#[derive(Copy, Clone, PartialOrd, PartialEq)] +struct SgxTime(u64); + +impl SgxTime { + const NANOS_PER_SEC: u32 = 1_000_000_000; + + pub fn as_duration(&self) -> Duration { + Duration::new(self.0 / Self::NANOS_PER_SEC as u64, (self.0 % Self::NANOS_PER_SEC as u64) as _) + } +} + +impl Add for SgxTime { + type Output = SgxTime; + + fn add(self, other: Duration) -> Self::Output { + let t = self.0 + other.as_secs() * Self::NANOS_PER_SEC as u64 + other.subsec_nanos() as u64; + SgxTime(t) + } +} + +impl NativeTime for SgxTime { + fn minimum() -> SgxTime { + SgxTime(0) + } + + fn abs_diff(&self, other: &Self) -> Duration { + Duration::from_nanos(self.0.abs_diff(other.0)) + } + + fn now() -> Self { + let (t, _info) = unsafe { raw::insecure_time() }; + SgxTime(t) + } +} + /// Usercall `insecure_time`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn insecure_time() -> Duration { - let t = unsafe { raw::insecure_time() }; - Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _) + static TSC: OnceLock> = OnceLock::new(); + + let tsc = TSC.get_or_init(|| { + let (_t, info) = unsafe { raw::insecure_time() }; + let freq = if !info.is_null() { + let info = unsafe { UserRef::::from_ptr(info).to_enclave() }; + if info.frequency != 0 { + Some(Freq::from_u64(info.frequency)) + } else { + // Enclave runner passed in info, but the host didn't report frequency. In + // the current implementation of the runner, that can't happen, but we may need + // something like that in the future when we pass in additional info. Just being + // very defensive here. + None + } + } else { + // Old enclave runner that doesn't pass in information + None + }; + + if let Some(freq) = freq { + LearningFreqTscBuilder::new() + .set_initial_frequency(freq) + .set_frequency_learning_period(Duration::from_secs(1)) + .set_max_acceptable_drift(Duration::from_millis(1)) + .set_max_sync_interval(Duration::from_secs(60)) + .set_monotonic_time() + .build() + } else { + NoRdtscTscBuilder::new() + .set_monotonic_time() + .build() + } + }); + tsc.now().as_duration() } /// Usercall `alloc`. See the ABI documentation for more information.