use anyhow::Result;
use core::arch::asm;
pub trait Entropy {
fn entropy(&mut self) -> Result<u128>;
}
pub struct Time;
#[derive(Debug)]
struct Timespec {
tv_sec: i64,
tv_nsec: i64,
}
unsafe fn clock_gettime(clock_id: i32, tp: *mut Timespec) -> i32 {
let mut ret: i32;
asm!(
"syscall",
in("rax") 228, in("rdi") clock_id,
in("rsi") tp,
lateout("rax") ret,
out("rcx") _,
out("r11") _,
);
ret
}
#[cfg(target_os = "macos")]
unsafe fn clock_gettime(clock_id: i32, tp: *mut Timespec) -> i32 {
let mut ret: i32;
asm!(
"syscall",
in("rax") 0x2000074, in("rdi") clock_id,
in("rsi") tp,
lateout("rax") ret,
out("rcx") _,
out("r11") _,
);
ret
}
impl Entropy for Time {
fn entropy(&mut self) -> Result<u128> {
#[cfg(any(target_os = "macos", target_os = "linux"))]
{
let mut entropy: u128 = 0;
unsafe {
let ret = clock_gettime(0, &mut entropy as *mut _ as *mut _);
if ret == 0 {
Ok(entropy)
} else {
use anyhow::bail;
bail!("failed to get clock time")
}
}
}
}
}