Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Letting enclaves keep track of time without usercalls #17

Open
wants to merge 1 commit into
base: dev-2024-11-21-snmalloc_and_insecure_time
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions library/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -334,6 +343,7 @@ dependencies = [
"fortanix-sgx-abi",
"hashbrown",
"hermit-abi",
"insecure-time",
"libc",
"miniz_oxide",
"object",
Expand Down
1 change: 1 addition & 0 deletions library/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
3 changes: 2 additions & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to update this finally after all rust-sgx side PRs are all merged and crate published


[target.'cfg(target_os = "hermit")'.dependencies]
hermit-abi = { version = "0.4.0", features = [
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ unsafe impl UserSafeSized for Return {}
unsafe impl UserSafeSized for Cancel {}
#[unstable(feature = "sgx_platform", issue = "56975")]
unsafe impl<T: UserSafeSized> 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")]
Expand Down
76 changes: 74 additions & 2 deletions library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -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.
///
Expand Down Expand Up @@ -249,11 +253,79 @@ pub fn send(event_set: u64, tcs: Option<Tcs>) -> 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<Duration> 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<Tsc<SgxTime>> = 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::<InsecureTimeInfo>::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.
Expand Down
Loading