diff --git a/.travis.yml b/.travis.yml index d5dbdca04..ce2775c94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -102,7 +102,7 @@ matrix: - rustup target add x86_64-sun-solaris - rustup target add x86_64-unknown-cloudabi - rustup target add x86_64-unknown-freebsd - #- rustup target add x86_64-unknown-fuchsia + - rustup target add x86_64-fuchsia - rustup target add x86_64-unknown-netbsd - rustup target add x86_64-unknown-redox - rustup target add x86_64-fortanix-unknown-sgx @@ -113,7 +113,7 @@ matrix: - cargo build --target=x86_64-sun-solaris --all-features - cargo build --target=x86_64-unknown-cloudabi --all-features - cargo build --target=x86_64-unknown-freebsd --all-features - #- cargo build --target=x86_64-unknown-fuchsia --all-features + - cargo build --target=x86_64-fuchsia --all-features - cargo build --target=x86_64-unknown-netbsd --all-features - cargo build --target=x86_64-unknown-redox --all-features - cargo build --target=x86_64-fortanix-unknown-sgx --all-features @@ -123,7 +123,7 @@ matrix: - cargo build --target=x86_64-sun-solaris --all-features - cargo build --target=x86_64-unknown-cloudabi --all-features - cargo build --target=x86_64-unknown-freebsd --all-features - #- cargo build --target=x86_64-unknown-fuchsia --all-features + - cargo build --target=x86_64-fuchsia --all-features - cargo build --target=x86_64-unknown-netbsd --all-features - cargo build --target=x86_64-unknown-redox --all-features - cargo build --target=x86_64-fortanix-unknown-sgx --all-features diff --git a/Cargo.toml b/Cargo.toml index 92baaa233..59975909b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,32 +20,21 @@ members = ["tests/wasm_bindgen"] [dependencies] log = { version = "0.4", optional = true } -[target.'cfg(unix)'.dependencies] -libc = "0.2.34" -lazy_static = "1.3.0" - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.6", features = ["minwindef", "ntsecapi", "winnt"] } - -[target.'cfg(target_os = "cloudabi")'.dependencies] -cloudabi = "0.0.3" - -[target.'cfg(fuchsia)'.dependencies] -fuchsia-cprng = "0.1" +[target.'cfg(any(unix, target_os = "wasi"))'.dependencies] +libc = "0.2.54" -[target.'cfg(target_os = "redox")'.dependencies] +# For holding file descriptors +[target.'cfg(any(unix, target_os = "redox"))'.dependencies] lazy_static = "1.3.0" +# For caching result of CPUID check for RDRAND +[target.'cfg(any(target_env = "sgx", target_os = "uefi"))'.dependencies] +lazy_static = { version = "1.3.0", features = ["spin_no_std"] } + [target.wasm32-unknown-unknown.dependencies] wasm-bindgen = { version = "0.2.29", optional = true } stdweb = { version = "0.4.9", optional = true } lazy_static = "1.3.0" -[target.wasm32-wasi.dependencies] -libc = "0.2.54" - -[target.'cfg(any(target_env = "sgx", target_os = "uefi"))'.dependencies] -lazy_static = { version = "1.3.0", features = ["spin_no_std"] } - [features] std = [] diff --git a/src/cloudabi.rs b/src/cloudabi.rs index f89c6368b..e87359ee6 100644 --- a/src/cloudabi.rs +++ b/src/cloudabi.rs @@ -10,14 +10,17 @@ use crate::Error; use core::num::NonZeroU32; +extern "C" { + fn cloudabi_sys_random_get(buf: *mut u8, buf_len: usize) -> u16; +} + pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - let errno = unsafe { cloudabi::random_get(dest) }; - if errno == cloudabi::errno::SUCCESS { - Ok(()) - } else { - let code = NonZeroU32::new(errno as u32).unwrap(); - error!("cloudabi::random_get syscall failed with code {}", code); + let errno = unsafe { cloudabi_sys_random_get(dest.as_mut_ptr(), dest.len()) }; + if let Some(code) = NonZeroU32::new(errno as u32) { + error!("cloudabi_sys_random_get failed with code {}", code); Err(Error::from(code)) + } else { + Ok(()) // Zero means success for CloudABI } } diff --git a/src/fuchsia.rs b/src/fuchsia.rs index cf3de6861..a9f538886 100644 --- a/src/fuchsia.rs +++ b/src/fuchsia.rs @@ -10,8 +10,13 @@ use crate::Error; use core::num::NonZeroU32; +#[link(name = "zircon")] +extern "C" { + fn zx_cprng_draw(buffer: *mut u8, length: usize); +} + pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - fuchsia_cprng::cprng_draw(dest); + unsafe { zx_cprng_draw(dest.as_mut_ptr(), dest.len()) } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 62217a7ff..063dffc91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ //! | Solaris, illumos | [`getrandom`][9] system call if available, otherwise [`/dev/random`][10] //! | Fuchsia OS | [`cprng_draw`][11] //! | Redox | [`rand:`][12] -//! | CloudABI | [`random_get`][13] +//! | CloudABI | [`cloudabi_sys_random_get`][13] //! | Haiku | `/dev/random` (identical to `/dev/urandom`) //! | SGX, UEFI | [RDRAND][18] //! | Web browsers | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and ams.js][14]) @@ -99,7 +99,7 @@ //! //! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html //! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html -//! [3]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx +//! [3]: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-rtlgenrandom //! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc //! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4 //! [6]: https://man.openbsd.org/getentropy.2 @@ -107,9 +107,9 @@ //! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random§ion=4 //! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html //! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html -//! [11]: https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/cprng_draw.md +//! [11]: https://fuchsia.googlesource.com/fuchsia/+/master/zircon/docs/syscalls/cprng_draw.md //! [12]: https://github.com/redox-os/randd/blob/master/src/main.rs -//! [13]: https://github.com/NuxiNL/cloudabi/blob/v0.20/cloudabi.txt#L1826 +//! [13]: https://github.com/nuxinl/cloudabi#random_get //! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues //! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback //! [16]: #support-for-webassembly-and-amsjs @@ -153,11 +153,11 @@ macro_rules! mod_use { }; } +// These targets use std anyway, so we use the std declarations. #[cfg(any( feature = "std", windows, unix, - target_os = "cloudabi", target_os = "redox", target_arch = "wasm32", ))] diff --git a/src/macos.rs b/src/macos.rs index 9017d4558..24157f9f4 100644 --- a/src/macos.rs +++ b/src/macos.rs @@ -22,7 +22,7 @@ struct SecRandom([u8; 0]); extern "C" { static kSecRandomDefault: *const SecRandom; - fn SecRandomCopyBytes(rnd: *const SecRandom, count: usize, bytes: *mut u8) -> libc::c_int; + fn SecRandomCopyBytes(rnd: *const SecRandom, count: usize, bytes: *mut u8) -> i32; } pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { diff --git a/src/windows.rs b/src/windows.rs index 4a99cebd7..f3f96d8c0 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -12,14 +12,16 @@ extern crate std; use crate::Error; use core::num::NonZeroU32; use std::io; -use winapi::shared::minwindef::ULONG; -use winapi::um::ntsecapi::RtlGenRandom; -use winapi::um::winnt::PVOID; + +extern "system" { + #[link_name = "SystemFunction036"] + fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8; +} pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - // Prevent overflow of ULONG - for chunk in dest.chunks_mut(ULONG::max_value() as usize) { - let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr() as PVOID, chunk.len() as ULONG) }; + // Prevent overflow of u32 + for chunk in dest.chunks_mut(u32::max_value() as usize) { + let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr(), chunk.len() as u32) }; if ret == 0 { error!("RtlGenRandom call failed"); return Err(io::Error::last_os_error().into());