]> git.proxmox.com Git - rustc.git/blobdiff - src/libstd/sys/unix/rand.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / libstd / sys / unix / rand.rs
index 6b50ca9bcdf6d8ee9e003a95a8c47a2ad50e1bd6..9b1cf6ffd0e2200a4b395e45ffc3c5948e2ffe07 100644 (file)
@@ -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};
@@ -97,8 +98,8 @@ mod imp {
                     // 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);
                 }
@@ -281,7 +282,7 @@ mod imp {
         }
         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 {
@@ -339,3 +340,66 @@ 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, 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)..];
+                    }
+                }
+            }
+        }
+    }
+}