From bdf7c942fd87d646e7ed2903dcd9f632b068e1cb Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 14 Aug 2019 17:58:16 +0300 Subject: [PATCH 01/13] add vxworks support --- .travis.yml | 1 + src/lib.rs | 3 +++ src/vxworks.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/vxworks.rs diff --git a/.travis.yml b/.travis.yml index d510624b..0f403341 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/src/lib.rs b/src/lib.rs index 104ec441..c74c5f3e 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 | `randBytes` //! | 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] @@ -225,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/vxworks.rs b/src/vxworks.rs new file mode 100644 index 00000000..7d17aa3f --- /dev/null +++ b/src/vxworks.rs @@ -0,0 +1,33 @@ +// 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; + +extern { + fn randBytes (buf: *mut u8, length: i32) -> i32; + // errnoLib.h + fn errnoGet() -> i32; +} + +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + // Prevent overflow of i32 + for chunk in dest.chunks_mut(i32::max_value() as usize) { + let ret = randBytes(chunk.as_mut_ptr(), chunk.len()); + if ret == -1 { + let errno = errnoGet(); + let err = if errno > 0 { + Error::from(NonZeroU32::new(errno as u32).unwrap()) + } else { + ERRNO_NOT_POSITIVE + }; + return Err(err); + } + } + Ok(()) +} From a2a7b1140e8e99ac0acb97f28c1a05b10685e300 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 14 Aug 2019 18:10:58 +0300 Subject: [PATCH 02/13] fix --- src/vxworks.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vxworks.rs b/src/vxworks.rs index 7d17aa3f..43d61494 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -7,9 +7,10 @@ // except according to those terms. //! Implementation for VxWorks -use crate::Error; +use crate::error::{Error, ERRNO_NOT_POSITIVE}; +use core::num::NonZeroU32; -extern { +extern "C" { fn randBytes (buf: *mut u8, length: i32) -> i32; // errnoLib.h fn errnoGet() -> i32; @@ -18,7 +19,7 @@ extern { pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { // Prevent overflow of i32 for chunk in dest.chunks_mut(i32::max_value() as usize) { - let ret = randBytes(chunk.as_mut_ptr(), chunk.len()); + let ret = randBytes(chunk.as_mut_ptr(), chunk.len() as i32); if ret == -1 { let errno = errnoGet(); let err = if errno > 0 { From fd002ec5d147fae6a88a676360bf22d6f820bc3a Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 14 Aug 2019 18:28:34 +0300 Subject: [PATCH 03/13] fix2 --- src/vxworks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vxworks.rs b/src/vxworks.rs index 43d61494..2519498a 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -11,7 +11,7 @@ use crate::error::{Error, ERRNO_NOT_POSITIVE}; use core::num::NonZeroU32; extern "C" { - fn randBytes (buf: *mut u8, length: i32) -> i32; + fn randBytes(buf: *mut u8, length: i32) -> i32; // errnoLib.h fn errnoGet() -> i32; } @@ -19,9 +19,9 @@ extern "C" { pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { // Prevent overflow of i32 for chunk in dest.chunks_mut(i32::max_value() as usize) { - let ret = randBytes(chunk.as_mut_ptr(), chunk.len() as i32); + let ret = unsafe { randBytes(chunk.as_mut_ptr(), chunk.len() as i32) }; if ret == -1 { - let errno = errnoGet(); + let errno = unsafe { errnoGet() }; let err = if errno > 0 { Error::from(NonZeroU32::new(errno as u32).unwrap()) } else { From 38a0254c8567ecf65d71eec7f909b94242b55135 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Sun, 18 Aug 2019 03:07:14 +0300 Subject: [PATCH 04/13] use libc --- src/lib.rs | 3 ++- src/util_libc.rs | 3 +++ src/vxworks.rs | 33 +++++++++++++++++---------------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c74c5f3e..bd25e0d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +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 | `randBytes` +//! | 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] @@ -172,6 +172,7 @@ mod util; target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "vxworks", ))] #[allow(dead_code)] mod util_libc; 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 index 2519498a..3c140095 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -7,27 +7,28 @@ // except according to those terms. //! Implementation for VxWorks -use crate::error::{Error, ERRNO_NOT_POSITIVE}; -use core::num::NonZeroU32; +use crate::error::Error; +use core::sync::atomic::{AtomicUBool, Ordering::Relaxed}; -extern "C" { - fn randBytes(buf: *mut u8, length: i32) -> i32; - // errnoLib.h - fn errnoGet() -> i32; -} +static RNG_INIT: AtomicBool = AtomicBool::new(false); pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + while !RNG_INIT.load(Relaxed) { + let ret = unsafe { libc::randSecure() }; + if ret < 0 { + return Err(last_os_error()); + } 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 { randBytes(chunk.as_mut_ptr(), chunk.len() as i32) }; - if ret == -1 { - let errno = unsafe { errnoGet() }; - let err = if errno > 0 { - Error::from(NonZeroU32::new(errno as u32).unwrap()) - } else { - ERRNO_NOT_POSITIVE - }; - return Err(err); + let ret = unsafe { randABytes(chunk.as_mut_ptr(), chunk.len() as i32) }; + if ret < 0 { + return Err(last_os_error()); } } Ok(()) From 625d97d81ff8ca4aa369ac0a0707ec4e7bf04c64 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Sun, 18 Aug 2019 03:18:10 +0300 Subject: [PATCH 05/13] fix --- src/vxworks.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vxworks.rs b/src/vxworks.rs index 3c140095..d235638d 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -8,7 +8,8 @@ //! Implementation for VxWorks use crate::error::Error; -use core::sync::atomic::{AtomicUBool, Ordering::Relaxed}; +use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; +use util_libc::last_os_error; static RNG_INIT: AtomicBool = AtomicBool::new(false); From d34f279a98fcc46cb344ac7ca5d852a2de942d00 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 18 Aug 2019 00:42:59 +0000 Subject: [PATCH 06/13] fix2 --- src/vxworks.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vxworks.rs b/src/vxworks.rs index d235638d..9b3efdc5 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -8,8 +8,8 @@ //! Implementation for VxWorks use crate::error::Error; +use crate::util_libc::last_os_error; use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; -use util_libc::last_os_error; static RNG_INIT: AtomicBool = AtomicBool::new(false); @@ -27,7 +27,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { // Prevent overflow of i32 for chunk in dest.chunks_mut(i32::max_value() as usize) { - let ret = unsafe { randABytes(chunk.as_mut_ptr(), chunk.len() as i32) }; + let ret = unsafe { libc::randABytes(chunk.as_mut_ptr(), chunk.len() as i32) }; if ret < 0 { return Err(last_os_error()); } From 234cf6c2477cd466a324f30eadf149c48ebb3f30 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Sun, 18 Aug 2019 04:37:14 +0300 Subject: [PATCH 07/13] add RAND_SECURE_FATAL constant --- src/error.rs | 2 ++ src/vxworks.rs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/error.rs b/src/error.rs index c68a7677..ca2e629a 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: fatal error"), _ => None, } } diff --git a/src/vxworks.rs b/src/vxworks.rs index 9b3efdc5..93248979 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -7,7 +7,7 @@ // except according to those terms. //! Implementation for VxWorks -use crate::error::Error; +use crate::error::{Error, RAND_SECURE_FATAL}; use crate::util_libc::last_os_error; use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; @@ -17,7 +17,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { while !RNG_INIT.load(Relaxed) { let ret = unsafe { libc::randSecure() }; if ret < 0 { - return Err(last_os_error()); + return Err(RAND_SECURE_FATAL); } else if ret > 0 { RNG_INIT.store(true, Relaxed); break; @@ -28,7 +28,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { // 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 { + if ret != 0 { return Err(last_os_error()); } } From 7113c54bd7ac6bfc1c900f22afd3caeb522bd3a5 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Fri, 6 Sep 2019 15:36:11 +0300 Subject: [PATCH 08/13] simplify libc cfg --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index cdf4e3cb..03abdd4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ 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] +[target.'cfg(unix)'.dependencies] libc = { version = "0.2.62", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] From 78a905422342b17d38e5d1189bbc5d8f2827ea66 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 15 Oct 2019 18:21:06 +0000 Subject: [PATCH 09/13] libc update --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 03abdd4c..dcb6abc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ compiler_builtins = { version = "0.1", optional = true } core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" } [target.'cfg(unix)'.dependencies] -libc = { version = "0.2.62", default-features = false } +libc = { version = "0.2.64", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] wasi = "0.5" From ce5c773f40818b80c3498afd91659d3cff427674 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 22 Oct 2019 16:50:00 +0300 Subject: [PATCH 10/13] fix cfg --- src/lib.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 48095799..06b4e897 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,19 +161,22 @@ 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", - target_os = "freebsd", target_os = "haiku", target_os = "illumos", - target_os = "linux", target_os = "macos", target_os = "netbsd", - target_os = "openbsd", target_os = "redox", target_os = "solaris"))] { + if #[cfg(any( + target_os = "android", target_os = "dragonfly", target_os = "emscripten", + target_os = "freebsd", target_os = "haiku", target_os = "illumos", + target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris", + ))] { #[allow(dead_code)] mod util_libc; // Keep std-only trait definitions for backwards compatiblity mod error_impls; - } else if #[cfg(target_os = "vxworks")] { - #[allow(dead_code)] - mod util_libc; } else if #[cfg(feature = "std")] { mod error_impls; } From 168806b0a3d2c73437be8982d8b9b8832a7a0f03 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 22 Oct 2019 16:52:25 +0300 Subject: [PATCH 11/13] revert cfg_if formatting --- src/lib.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 06b4e897..509c5a20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -167,12 +167,10 @@ 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", - target_os = "freebsd", target_os = "haiku", target_os = "illumos", - target_os = "linux", target_os = "macos", target_os = "netbsd", - target_os = "openbsd", target_os = "redox", target_os = "solaris", - ))] { + if #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "emscripten", + target_os = "freebsd", target_os = "haiku", target_os = "illumos", + target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris"))] { #[allow(dead_code)] mod util_libc; // Keep std-only trait definitions for backwards compatiblity From 2f13c46fb81fc1a9e061d565f3d166e4367d7da5 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 22 Oct 2019 16:53:37 +0300 Subject: [PATCH 12/13] move RNG_INIT --- src/vxworks.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vxworks.rs b/src/vxworks.rs index 93248979..a2fe52ad 100644 --- a/src/vxworks.rs +++ b/src/vxworks.rs @@ -11,9 +11,8 @@ use crate::error::{Error, RAND_SECURE_FATAL}; use crate::util_libc::last_os_error; use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; -static RNG_INIT: AtomicBool = AtomicBool::new(false); - 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 { From eb79bb705dae1407bfb220bdbd627eba05151caa Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 23 Oct 2019 09:00:36 +0000 Subject: [PATCH 13/13] update RAND_SECURE_FATAL description --- src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index ca2e629a..555f3dfe 100644 --- a/src/error.rs +++ b/src/error.rs @@ -153,7 +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: fatal error"), + RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"), _ => None, } }