diff --git a/.travis.yml b/.travis.yml index 19e566c1..a4950821 100644 --- a/.travis.yml +++ b/.travis.yml @@ -118,6 +118,7 @@ matrix: - cargo xbuild --target=x86_64-unknown-uefi - cargo xbuild --target=x86_64-unknown-hermit - cargo xbuild --target=x86_64-unknown-l4re-uclibc + - cargo xbuild --target=x86_64-wrs-vxworks # also test minimum dependency versions are usable - cargo generate-lockfile -Z minimal-versions - cargo build --target=x86_64-sun-solaris diff --git a/Cargo.toml b/Cargo.toml index cdf4e3cb..dcb6abc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,8 @@ cfg-if = "0.1" compiler_builtins = { version = "0.1", optional = true } core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" } -[target.'cfg(any(unix, target_os = "redox"))'.dependencies] -libc = { version = "0.2.62", default-features = false } +[target.'cfg(unix)'.dependencies] +libc = { version = "0.2.64", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] wasi = "0.5" diff --git a/src/error.rs b/src/error.rs index c68a7677..555f3dfe 100644 --- a/src/error.rs +++ b/src/error.rs @@ -138,6 +138,7 @@ pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7); pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8); pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9); pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10); +pub(crate) const RAND_SECURE_FATAL: Error = internal_error!(11); fn internal_desc(error: Error) -> Option<&'static str> { match error { @@ -152,6 +153,7 @@ fn internal_desc(error: Error) -> Option<&'static str> { BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"), STDWEB_NO_RNG => Some("stdweb: no randomness source available"), STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"), + RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"), _ => None, } } diff --git a/src/lib.rs b/src/lib.rs index 023a6230..509c5a20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ //! | Haiku | `/dev/random` (identical to `/dev/urandom`) //! | L4RE, SGX, UEFI | [RDRAND][18] //! | Hermit | [RDRAND][18] as [`sys_rand`][22] is currently broken. +//! | VxWorks | `randABytes` after checking entropy pool initialization with `randSecure` //! | Web browsers | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and ams.js][14]) //! | Node.js | [`crypto.randomBytes`][15] (see [Support for WebAssembly and ams.js][16]) //! | WASI | [`__wasi_random_get`][17] @@ -160,6 +161,10 @@ pub use crate::error::Error; #[allow(dead_code)] mod util; +#[cfg(target_os = "vxworks")] +#[allow(dead_code)] +mod util_libc; + cfg_if! { // Unlike the other Unix, Fuchsia and iOS don't use the libc to make any calls. if #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "emscripten", @@ -221,6 +226,8 @@ cfg_if! { #[path = "solaris_illumos.rs"] mod imp; } else if #[cfg(target_os = "wasi")] { #[path = "wasi.rs"] mod imp; + } else if #[cfg(target_os = "vxworks")] { + #[path = "vxworks.rs"] mod imp; } else if #[cfg(all(windows, getrandom_uwp))] { #[path = "windows_uwp.rs"] mod imp; } else if #[cfg(windows)] { diff --git a/src/util_libc.rs b/src/util_libc.rs index d662fc62..5a051701 100644 --- a/src/util_libc.rs +++ b/src/util_libc.rs @@ -26,7 +26,10 @@ cfg_if! { } pub fn last_os_error() -> Error { + #[cfg(not(target_os = "vxworks"))] let errno = unsafe { *errno_location() }; + #[cfg(target_os = "vxworks")] + let errno = unsafe { libc::errnoGet() }; if errno > 0 { Error::from(NonZeroU32::new(errno as u32).unwrap()) } else { diff --git a/src/vxworks.rs b/src/vxworks.rs new file mode 100644 index 00000000..a2fe52ad --- /dev/null +++ b/src/vxworks.rs @@ -0,0 +1,35 @@ +// Copyright 2018 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementation for VxWorks +use crate::error::{Error, RAND_SECURE_FATAL}; +use crate::util_libc::last_os_error; +use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; + +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + static RNG_INIT: AtomicBool = AtomicBool::new(false); + while !RNG_INIT.load(Relaxed) { + let ret = unsafe { libc::randSecure() }; + if ret < 0 { + return Err(RAND_SECURE_FATAL); + } else if ret > 0 { + RNG_INIT.store(true, Relaxed); + break; + } + unsafe { libc::usleep(10) }; + } + + // Prevent overflow of i32 + for chunk in dest.chunks_mut(i32::max_value() as usize) { + let ret = unsafe { libc::randABytes(chunk.as_mut_ptr(), chunk.len() as i32) }; + if ret != 0 { + return Err(last_os_error()); + } + } + Ok(()) +}