1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//! Runtime time source.
use std::{
sync::Mutex,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use lazy_static::lazy_static;
use slog::error;
use crate::common::{logger::get_logger, process};
const INITIAL_MINIMUM_TIME: i64 = 1704067200; // Mon, 01 Jan 2024 00:00:00 UTC
struct TimeSource {
inner: Mutex<Inner>,
}
struct Inner {
timestamp: i64,
}
/// Returns the number of seconds since the UNIX epoch. The time returned
/// is guaranteed to never decrease within each enclave instance (though it
/// may decrease iff the enclave is re-launched).
///
/// The returned timestamp MUST NOT be trusted on in any way, as the underlying
/// time source is reliant on the host operating system.
pub fn insecure_posix_time() -> i64 {
let mut inner = TIME_SOURCE.inner.lock().unwrap();
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let now = now.as_secs() as i64;
if now < inner.timestamp {
error!(
get_logger("runtime/time"),
"clock appeared to have ran backwards"
);
process::abort();
}
inner.timestamp = now;
inner.timestamp
}
// Returns `insecure_posix_time` as SystemTime.
pub fn insecure_posix_system_time() -> SystemTime {
UNIX_EPOCH + Duration::from_secs(insecure_posix_time() as u64)
}
/// Force update the minimum timestamp from a semi-trusted source (eg: the AVR
/// timestamp), under the assumption that the semi-trusted source is more trust
/// worthy than the host operating system.
pub(crate) fn update_insecure_posix_time(timestamp: i64) {
let mut inner = TIME_SOURCE.inner.lock().unwrap();
if timestamp > inner.timestamp {
inner.timestamp = timestamp;
}
// The IAS clock and local clock should be closely synced, and minor
// differences in NTP implementations (eg: smear vs no smear), should
// be masked by the fact that the AVR timestamp will be a minimum of
// 1 RTT in the past.
}
lazy_static! {
static ref TIME_SOURCE: TimeSource = TimeSource {
inner: Mutex::new(Inner {
timestamp: INITIAL_MINIMUM_TIME,
})
};
}