Add support for kernel randomness for Fuchsia
Wire up cprng syscall as provider for rand::os::OsRng on Fuchsia.
This commit is contained in:
parent
4879166194
commit
592d7bfb3a
@ -58,6 +58,8 @@ fn main() {
|
||||
println!("cargo:rustc-link-lib=ws2_32");
|
||||
println!("cargo:rustc-link-lib=userenv");
|
||||
println!("cargo:rustc-link-lib=shell32");
|
||||
} else if target.contains("fuchsia") {
|
||||
println!("cargo:rustc-link-lib=magenta");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
|
||||
#[cfg(all(unix,
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "freebsd")))]
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "fuchsia")))]
|
||||
mod imp {
|
||||
use self::OsRngInner::*;
|
||||
use super::{next_u32, next_u64};
|
||||
@ -339,3 +340,54 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
mod imp {
|
||||
use super::{next_u32, next_u64};
|
||||
|
||||
use io;
|
||||
use rand::Rng;
|
||||
|
||||
#[link(name = "magenta")]
|
||||
extern {
|
||||
fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize;
|
||||
}
|
||||
|
||||
fn getrandom(buf: &mut [u8]) -> isize {
|
||||
unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) }
|
||||
}
|
||||
|
||||
pub struct OsRng {
|
||||
// dummy field to ensure that this struct cannot be constructed outside
|
||||
// of this module
|
||||
_dummy: (),
|
||||
}
|
||||
|
||||
impl OsRng {
|
||||
/// Create a new `OsRng`.
|
||||
pub fn new() -> io::Result<OsRng> {
|
||||
Ok(OsRng { _dummy: () })
|
||||
}
|
||||
}
|
||||
|
||||
impl Rng for OsRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
next_u32(&mut |v| self.fill_bytes(v))
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
next_u64(&mut |v| self.fill_bytes(v))
|
||||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
let mut buf = v;
|
||||
while !buf.is_empty() {
|
||||
let ret = getrandom(buf);
|
||||
if ret < 0 {
|
||||
panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
|
||||
ret, buf.len());
|
||||
}
|
||||
let move_buf = buf;
|
||||
buf = &mut move_buf[(ret as usize)..];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user