Skip to content

Merge branch 'master' into '0.2' #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,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
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ cfg-if = "0.1.2"
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.7"
Expand Down
28 changes: 16 additions & 12 deletions src/freebsd.rs → src/bsd_arandom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for FreeBSD
use crate::util_libc::{sys_fill_exact, Weak};
//! Implementation for FreeBSD and NetBSD
use crate::util_libc::sys_fill_exact;
use crate::Error;
use core::{mem, ptr};

type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
use core::ptr;

fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
Expand All @@ -27,19 +25,25 @@ fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
)
};
if ret == -1 {
error!("freebsd: kern.arandom syscall failed");
error!("sysctl kern.arandom: syscall failed");
-1
} else {
len as libc::ssize_t
}
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { mem::transmute(fptr) };
sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) })
} else {
sys_fill_exact(dest, kern_arnd)
#[cfg(target_os = "freebsd")]
{
use crate::util_libc::Weak;
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
type GetRandomFn =
unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;

if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
}
}
sys_fill_exact(dest, kern_arnd)
}
4 changes: 3 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Error {
///
/// This method is identical to `std::io::Error::raw_os_error()`, except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Diplay` implementation.
/// error value can still be formatted via the `Display` implementation.
#[inline]
pub fn raw_os_error(self) -> Option<i32> {
if self.0.get() < Self::INTERNAL_START {
Expand Down Expand Up @@ -145,6 +145,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 {
Expand All @@ -159,6 +160,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,
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! | iOS | [`SecRandomCopyBytes`][4]
//! | FreeBSD | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
//! | OpenBSD | [`getentropy`][6]
//! | NetBSD | [`/dev/urandom`][7] after successfully polling `/dev/random`
//! | NetBSD | [`kern.arandom`][7]
//! | Dragonfly BSD | [`/dev/random`][8]
//! | Solaris, illumos | [`getrandom`][9] system call if available, otherwise [`/dev/random`][10]
//! | Fuchsia OS | [`cprng_draw`][11]
Expand All @@ -27,8 +27,9 @@
//! | Haiku | `/dev/random` (identical to `/dev/urandom`)
//! | L4RE, SGX, UEFI | [RDRAND][18]
//! | Hermit | [RDRAND][18] as [`sys_rand`][22] is currently broken.
//! | 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])
//! | VxWorks | `randABytes` after checking entropy pool initialization with `randSecure`
//! | Web browsers | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and asm.js][16])
//! | Node.js | [`crypto.randomBytes`][15] (see [Support for WebAssembly and asm.js][16])
//! | WASI | [`__wasi_random_get`][17]
//!
//! Getrandom doesn't have a blanket implementation for all Unix-like operating
Expand Down Expand Up @@ -80,7 +81,7 @@
//! A few, Linux, NetBSD and Solaris, offer a choice between blocking and
//! getting an error; in these cases we always choose to block.
//!
//! On Linux (when the `genrandom` system call is not available) and on NetBSD
//! On Linux (when the `getrandom` system call is not available) and on NetBSD
//! reading from `/dev/urandom` never blocks, even when the OS hasn't collected
//! enough entropy yet. To avoid returning low-entropy bytes, we first read from
//! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
Expand All @@ -102,7 +103,7 @@
//! [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
//! [7]: http://netbsd.gw.com/cgi-bin/man-cgi?random+4+NetBSD-current
//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=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
Expand All @@ -111,7 +112,7 @@
//! [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
//! [16]: #support-for-webassembly-and-asmjs
//! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
//! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
Expand Down Expand Up @@ -196,7 +197,7 @@ cfg_if! {
} else if #[cfg(target_os = "emscripten")] {
#[path = "use_file.rs"] mod imp;
} else if #[cfg(target_os = "freebsd")] {
#[path = "freebsd.rs"] mod imp;
#[path = "bsd_arandom.rs"] mod imp;
} else if #[cfg(target_os = "fuchsia")] {
#[path = "fuchsia.rs"] mod imp;
} else if #[cfg(target_os = "haiku")] {
Expand All @@ -210,7 +211,7 @@ cfg_if! {
} else if #[cfg(target_os = "macos")] {
#[path = "macos.rs"] mod imp;
} else if #[cfg(target_os = "netbsd")] {
#[path = "use_file.rs"] mod imp;
#[path = "bsd_arandom.rs"] mod imp;
} else if #[cfg(target_os = "openbsd")] {
#[path = "openbsd.rs"] mod imp;
} else if #[cfg(target_os = "redox")] {
Expand All @@ -219,6 +220,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)] {
Expand Down
2 changes: 1 addition & 1 deletion src/rdrand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
let mut el = mem::zeroed();
if _rdrand64_step(&mut el) == 1 {
// AMD CPUs from families 14h to 16h (pre Ryzen) sometimes fail to
// set CF on bogus random data, so we check these values explictly.
// set CF on bogus random data, so we check these values explicitly.
// See https://github.com/systemd/systemd/issues/11810#issuecomment-489727505
// We perform this check regardless of target to guard against
// any implementation that incorrectly fails to set CF.
Expand Down
2 changes: 1 addition & 1 deletion src/solaris_illumos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//!
//! Since Solaris 11.3 and mid-2015 illumos, the `getrandom` syscall is available.
//! To make sure we can compile on both Solaris and its derivatives, as well as
//! function, we check for the existance of getrandom(2) in libc by calling
//! function, we check for the existence of getrandom(2) in libc by calling
//! libc::dlsym.
use crate::util_libc::{sys_fill_exact, Weak};
use crate::{use_file, Error};
Expand Down
2 changes: 1 addition & 1 deletion src/use_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
}

cfg_if! {
if #[cfg(any(target_os = "android", target_os = "linux", target_os = "netbsd"))] {
if #[cfg(any(target_os = "android", target_os = "linux"))] {
fn init_file() -> Option<libc::c_int> {
// Poll /dev/random to make sure it is ok to read from /dev/urandom.
let mut pfd = libc::pollfd {
Expand Down
6 changes: 3 additions & 3 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};

// This structure represents a laziliy initialized static usize value. Useful
// when it is perferable to just rerun initialization instead of locking.
// This structure represents a lazily initialized static usize value. Useful
// when it is preferable to just rerun initialization instead of locking.
// Both unsync_init and sync_init will invoke an init() function until it
// succeeds, then return the cached value for future calls.
//
Expand All @@ -25,7 +25,7 @@ use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
// v
// }
// the effects of c() or writes to shared memory will not necessarily be
// observed and additional syncronization methods with be needed.
// observed and additional synchronization methods with be needed.
pub struct LazyUsize(AtomicUsize);

impl LazyUsize {
Expand Down
3 changes: 3 additions & 0 deletions src/util_libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
35 changes: 35 additions & 0 deletions src/vxworks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, 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(())
}
2 changes: 1 addition & 1 deletion src/windows_uwp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// except according to those terms.

//! Implementation for Windows UWP targets. After deprecation of Windows XP
//! and Vista, this can superseed the `RtlGenRandom`-based implementation.
//! and Vista, this can supersede the `RtlGenRandom`-based implementation.
use crate::Error;
use core::{ffi::c_void, num::NonZeroU32, ptr};

Expand Down