diff options
| author | Valerii Hiora <valerii.hiora@gmail.com> | 2014-05-05 10:07:49 +0300 |
|---|---|---|
| committer | Valerii Hiora <valerii.hiora@gmail.com> | 2014-06-12 21:15:14 +0300 |
| commit | a49b765f9a5b5926e338da30fcaae59ff1ae5c02 (patch) | |
| tree | 489f1930d52ae1e9050e840940b3bcb1daedb615 /src/libstd/rand | |
| parent | 0c10c686824bf37084af87af84f338bcd2a7551a (diff) | |
| download | rust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.tar.gz rust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.zip | |
Basic iOS support
Diffstat (limited to 'src/libstd/rand')
| -rw-r--r-- | src/libstd/rand/os.rs | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 2654b7a1acc..f507011c2b9 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -13,7 +13,7 @@ pub use self::imp::OsRng; -#[cfg(unix)] +#[cfg(unix, not(target_os = "ios"))] mod imp { use io::{IoResult, File}; use path::Path; @@ -28,7 +28,7 @@ mod imp { /// `/dev/urandom`. /// - Windows: calls `CryptGenRandom`, using the default cryptographic /// service provider with the `PROV_RSA_FULL` type. - /// + /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed /// This does not block. #[cfg(unix)] pub struct OsRng { @@ -58,6 +58,71 @@ mod imp { } } +#[cfg(target_os = "ios")] +mod imp { + extern crate libc; + + use collections::Collection; + use io::{IoResult}; + use kinds::marker; + use mem; + use os; + use rand::Rng; + use result::{Ok}; + use self::libc::{c_int, size_t}; + use slice::MutableVector; + + /// A random number generator that retrieves randomness straight from + /// the operating system. Platform sources: + /// + /// - Unix-like systems (Linux, Android, Mac OSX): read directly from + /// `/dev/urandom`. + /// - Windows: calls `CryptGenRandom`, using the default cryptographic + /// service provider with the `PROV_RSA_FULL` type. + /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed + /// This does not block. + pub struct OsRng { + marker: marker::NoCopy + } + + struct SecRandom; + + static kSecRandomDefault: *SecRandom = 0 as *SecRandom; + + #[link(name = "Security", kind = "framework")] + extern "C" { + fn SecRandomCopyBytes(rnd: *SecRandom, count: size_t, bytes: *mut u8) -> c_int; + } + + impl OsRng { + /// Create a new `OsRng`. + pub fn new() -> IoResult<OsRng> { + Ok(OsRng {marker: marker::NoCopy} ) + } + } + + impl Rng for OsRng { + fn next_u32(&mut self) -> u32 { + let mut v = [0u8, .. 4]; + self.fill_bytes(v); + unsafe { mem::transmute(v) } + } + fn next_u64(&mut self) -> u64 { + let mut v = [0u8, .. 8]; + self.fill_bytes(v); + unsafe { mem::transmute(v) } + } + fn fill_bytes(&mut self, v: &mut [u8]) { + let ret = unsafe { + SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr()) + }; + if ret == -1 { + fail!("couldn't generate random bytes: {}", os::last_os_error()); + } + } + } +} + #[cfg(windows)] mod imp { extern crate libc; |
