Skip to content

Commit

Permalink
Add support for kernel randomness for Fuchsia
Browse files Browse the repository at this point in the history
Wire up cprng syscall as provider for rand::os::OsRng on Fuchsia.
  • Loading branch information
raphlinus committed Oct 24, 2016
1 parent 4879166 commit 592d7bf
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down
54 changes: 53 additions & 1 deletion src/libstd/sys/unix/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -339,3 +340,54 @@ mod imp {
}
}
}

#[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)..];
}
}
}
}

0 comments on commit 592d7bf

Please sign in to comment.