#[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};
// full entropy pool
let reader = File::open("/dev/urandom").expect("Unable to open /dev/urandom");
let mut reader_rng = ReaderRng::new(reader);
- reader_rng.fill_bytes(& mut v[read..]);
- read += v.len() as usize;
+ reader_rng.fill_bytes(&mut v[read..]);
+ read += v.len();
} else {
panic!("unexpected getrandom error: {}", err);
}
}
fn fill_bytes(&mut self, v: &mut [u8]) {
let ret = unsafe {
- SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t,
+ SecRandomCopyBytes(kSecRandomDefault, v.len(),
v.as_mut_ptr())
};
if ret == -1 {
}
}
}
+
+#[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, actual: *mut usize) -> i32;
+ }
+
+ fn getrandom(buf: &mut [u8]) -> Result<usize, i32> {
+ unsafe {
+ let mut actual = 0;
+ let status = mx_cprng_draw(buf.as_mut_ptr(), buf.len(), &mut actual);
+ if status == 0 {
+ Ok(actual)
+ } else {
+ Err(status)
+ }
+ }
+ }
+
+ 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);
+ match ret {
+ Err(err) => {
+ panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
+ err, buf.len())
+ }
+ Ok(actual) => {
+ let move_buf = buf;
+ buf = &mut move_buf[(actual as usize)..];
+ }
+ }
+ }
+ }
+ }
+}