Skip to content

Commit

Permalink
Rollup merge of rust-lang#37385 - raphlinus:fuchsia_random, r=alexcri…
Browse files Browse the repository at this point in the history
…chton

Add support for kernel randomness for Fuchsia

Wire up cprng syscall as provider for rand::os::OsRng on Fuchsia.
  • Loading branch information
Manishearth committed Oct 26, 2016
2 parents f8d0a1f + 592d7bf commit 8b212e3
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 8b212e3

Please sign in to comment.