diff options
| author | Raph Levien <raph@google.com> | 2016-10-24 16:42:57 -0700 |
|---|---|---|
| committer | Raph Levien <raph@google.com> | 2016-10-24 16:48:45 -0700 |
| commit | 592d7bfb3af75ded9c5233ee243cc6c751531671 (patch) | |
| tree | ccf54ae7f1b236245a4ae662121ed5ecf294d348 /src/libstd/sys/unix/rand.rs | |
| parent | 4879166194ed63ebd2a8c3ce8db1ccde4a6a1920 (diff) | |
| download | rust-592d7bfb3af75ded9c5233ee243cc6c751531671.tar.gz rust-592d7bfb3af75ded9c5233ee243cc6c751531671.zip | |
Add support for kernel randomness for Fuchsia
Wire up cprng syscall as provider for rand::os::OsRng on Fuchsia.
Diffstat (limited to 'src/libstd/sys/unix/rand.rs')
| -rw-r--r-- | src/libstd/sys/unix/rand.rs | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index f28a6ad3375..3aebb8c18ec 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -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 @@ 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)..]; + } + } + } +} |
