Skip to content

Commit 592d7bf

Browse files
committed
Add support for kernel randomness for Fuchsia
Wire up cprng syscall as provider for rand::os::OsRng on Fuchsia.
1 parent 4879166 commit 592d7bf

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/libstd/build.rs

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ fn main() {
5858
println!("cargo:rustc-link-lib=ws2_32");
5959
println!("cargo:rustc-link-lib=userenv");
6060
println!("cargo:rustc-link-lib=shell32");
61+
} else if target.contains("fuchsia") {
62+
println!("cargo:rustc-link-lib=magenta");
6163
}
6264
}
6365

src/libstd/sys/unix/rand.rs

+53-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
2727
#[cfg(all(unix,
2828
not(target_os = "ios"),
2929
not(target_os = "openbsd"),
30-
not(target_os = "freebsd")))]
30+
not(target_os = "freebsd"),
31+
not(target_os = "fuchsia")))]
3132
mod imp {
3233
use self::OsRngInner::*;
3334
use super::{next_u32, next_u64};
@@ -339,3 +340,54 @@ mod imp {
339340
}
340341
}
341342
}
343+
344+
#[cfg(target_os = "fuchsia")]
345+
mod imp {
346+
use super::{next_u32, next_u64};
347+
348+
use io;
349+
use rand::Rng;
350+
351+
#[link(name = "magenta")]
352+
extern {
353+
fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize;
354+
}
355+
356+
fn getrandom(buf: &mut [u8]) -> isize {
357+
unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) }
358+
}
359+
360+
pub struct OsRng {
361+
// dummy field to ensure that this struct cannot be constructed outside
362+
// of this module
363+
_dummy: (),
364+
}
365+
366+
impl OsRng {
367+
/// Create a new `OsRng`.
368+
pub fn new() -> io::Result<OsRng> {
369+
Ok(OsRng { _dummy: () })
370+
}
371+
}
372+
373+
impl Rng for OsRng {
374+
fn next_u32(&mut self) -> u32 {
375+
next_u32(&mut |v| self.fill_bytes(v))
376+
}
377+
fn next_u64(&mut self) -> u64 {
378+
next_u64(&mut |v| self.fill_bytes(v))
379+
}
380+
fn fill_bytes(&mut self, v: &mut [u8]) {
381+
let mut buf = v;
382+
while !buf.is_empty() {
383+
let ret = getrandom(buf);
384+
if ret < 0 {
385+
panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
386+
ret, buf.len());
387+
}
388+
let move_buf = buf;
389+
buf = &mut move_buf[(ret as usize)..];
390+
}
391+
}
392+
}
393+
}

0 commit comments

Comments
 (0)