diff --git a/src/getrandom.rs b/src/getrandom.rs index 38100384..3b2cde15 100644 --- a/src/getrandom.rs +++ b/src/getrandom.rs @@ -1,4 +1,15 @@ -//! Implementation using libc::getrandom +//! Implementation using `libc::getrandom`. +//! +//! Available since: +//! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20 +//! - Android API level 23 (Marshmallow) +//! - NetBSD 10.0 +//! - FreeBSD 12.0 +//! - Solaris 11.3 +//! - Illumos since Dec 2018 +//! - DragonFly 5.7 +//! - Hurd Glibc 2.31 +//! - shim-3ds since Feb 2022 use crate::{util_libc::sys_fill_exact, Error}; use core::mem::MaybeUninit; diff --git a/src/lib.rs b/src/lib.rs index 6823041f..c30e95bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,8 @@ //! | OpenBSD | `*‑openbsd` | [`getentropy`][7] //! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8] //! | Dragonfly BSD | `*‑dragonfly` | [`getrandom`][9] -//! | Solaris, illumos | `*‑solaris`, `*‑illumos` | [`getrandom`][11] if available, otherwise [`/dev/random`][12] +//! | Solaris | `*‑solaris` | [`getentropy`][11] +//! | Illumos | `*‑illumos` | [`getrandom`][12] //! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`] //! | Redox | `*‑redox` | `/dev/urandom` //! | Haiku | `*‑haiku` | `/dev/urandom` (identical to `/dev/random`) @@ -25,15 +26,11 @@ //! | WASI | `wasm32‑wasi` | [`random_get`] //! | Web Browser and Node.js | `wasm*‑*‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js, see [WebAssembly support] //! | SOLID | `*-kmc-solid_*` | `SOLID_RNG_SampleRandomBytes` -//! | Nintendo 3DS | `armv6k-nintendo-3ds` | [`getrandom`][1] +//! | Nintendo 3DS | `*-nintendo-3ds` | [`getrandom`][18] //! | PS Vita | `*-vita-*` | [`getentropy`][13] //! | QNX Neutrino | `*‑nto-qnx*` | [`/dev/urandom`][14] (identical to `/dev/random`) //! | AIX | `*-ibm-aix` | [`/dev/urandom`][15] //! -//! There is no blanket implementation on `unix` targets that reads from -//! `/dev/urandom`. This ensures all supported targets are using the recommended -//! interface and respect maximum buffer sizes. -//! //! Pull Requests that add support for new targets to `getrandom` are always welcome. //! //! ## Unsupported targets @@ -176,13 +173,14 @@ //! [7]: https://man.openbsd.org/getentropy.2 //! [8]: https://man.netbsd.org/sysctl.7 //! [9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom -//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html -//! [12]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html +//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getentropy-2.html +//! [12]: https://illumos.org/man/2/getrandom //! [13]: https://github.com/emscripten-core/emscripten/pull/12240 //! [14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html //! [15]: https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices //! [16]: https://man.netbsd.org/getrandom.2 //! [17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom +//! [18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d //! //! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom //! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues @@ -240,6 +238,7 @@ cfg_if! { } else if #[cfg(any( target_os = "macos", target_os = "openbsd", + target_os = "solaris", target_os = "vita", target_os = "emscripten", ))] { @@ -249,6 +248,7 @@ cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", + target_os = "illumos", // Check for target_arch = "arm" to only include the 3DS. Does not // include the Nintendo Switch (which is target_arch = "aarch64"). all(target_os = "horizon", target_arch = "arm"), @@ -302,10 +302,6 @@ cfg_if! { } else if #[cfg(any(target_os = "android", target_os = "linux"))] { mod util_libc; #[path = "linux_android.rs"] mod imp; - } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { - mod util_libc; - mod use_file; - #[path = "solaris_illumos.rs"] mod imp; } else if #[cfg(target_os = "netbsd")] { mod util_libc; #[path = "netbsd.rs"] mod imp; diff --git a/src/solaris_illumos.rs b/src/solaris_illumos.rs deleted file mode 100644 index fbc23943..00000000 --- a/src/solaris_illumos.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Implementation for the Solaris family -//! -//! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A. -//! `/dev/urandom` uses the FIPS 186-2 algorithm, which is considered less -//! secure. We choose to read from `/dev/random` (and use GRND_RANDOM). -//! -//! Solaris 11.3 and late-2018 illumos added the getrandom(2) libc function. -//! To make sure we can compile on both Solaris and its derivatives, as well as -//! function, we check for the existence of getrandom(2) in libc by calling -//! libc::dlsym. -use crate::{ - use_file, - util_libc::{sys_fill_exact, Weak}, - Error, -}; -use core::mem::{self, MaybeUninit}; - -static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") }; -type GetRandomFn = - unsafe extern "C" fn(*mut libc::c_void, libc::size_t, libc::c_uint) -> libc::ssize_t; - -pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - if let Some(fptr) = GETRANDOM.ptr() { - let func: GetRandomFn = unsafe { mem::transmute(fptr) }; - // 256 bytes is the lowest common denominator across all the Solaris - // derived platforms for atomically obtaining random data. - for chunk in dest.chunks_mut(256) { - sys_fill_exact(chunk, |buf| unsafe { - // A cast is needed for the flags as libc uses the wrong type. - func( - buf.as_mut_ptr() as *mut libc::c_void, - buf.len(), - libc::GRND_RANDOM as libc::c_uint, - ) - })? - } - Ok(()) - } else { - use_file::getrandom_inner(dest) - } -} diff --git a/src/use_file.rs b/src/use_file.rs index 333325b5..bd643ae5 100644 --- a/src/use_file.rs +++ b/src/use_file.rs @@ -9,21 +9,12 @@ use core::{ sync::atomic::{AtomicUsize, Ordering::Relaxed}, }; -// We prefer using /dev/urandom and only use /dev/random if the OS -// documentation indicates that /dev/urandom is insecure. -// On Solaris/Illumos, see src/solaris_illumos.rs -// On Dragonfly, Haiku, and QNX Neutrino the devices are identical. -#[cfg(any(target_os = "solaris", target_os = "illumos"))] -const FILE_PATH: &str = "/dev/random\0"; -#[cfg(any( - target_os = "aix", - target_os = "android", - target_os = "linux", - target_os = "redox", - target_os = "dragonfly", - target_os = "haiku", - target_os = "nto", -))] +/// For all platforms, we use `/dev/urandom` rather than `/dev/random`. +/// For more information see the linked man pages in lib.rs. +/// - On Linux, "/dev/urandom is preferred and sufficient in all use cases". +/// - On Redox, only /dev/urandom is provided. +/// - On AIX, /dev/urandom will "provide cryptographically secure output". +/// - On Haiku and QNX Neutrino they are identical. const FILE_PATH: &str = "/dev/urandom\0"; const FD_UNINIT: usize = usize::max_value();