Skip to content

Commit ac5e838

Browse files
committed
Unconditionally use libc::getrandom on Illumos and Solaris
Also removes the use of `GRND_RANDOM`, which appears to be based on outdated staements about the RNGs. For Solaris, see [this blog post](https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2). For Illumos, the algorithms are less clear, but I don't see a clear reason to continue using `GRND_RANDOM`. I updated the documentation in `getrandom.rs` to full document this decision and to have a common place listing when `getrandom(2)` became avalible on each platform. I also updated the main lib.rs docs to point to the correct man pages. Note that Solaris 11.3 has a maximum buffer length of 1024 bytes, while Illumos doesn't have this sort of issue. Signed-off-by: Joe Richey <[email protected]>
1 parent dca4961 commit ac5e838

File tree

4 files changed

+46
-67
lines changed

4 files changed

+46
-67
lines changed

src/getrandom.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,43 @@
11
//! Implementation using libc::getrandom
2+
//!
3+
//! Available since:
4+
//! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20
5+
//! - Android API level 23 (Marshmallow)
6+
//! - NetBSD 10.0
7+
//! - FreeBSD 12.0
8+
//! - Solaris 11.3
9+
//! - Illumos since Dec 2018
10+
//! - DragonFly 5.7
11+
//! - Hurd Glibc 2.31
12+
//! - shim-3ds since Feb 2022
13+
//!
14+
//! For all platforms, we use the default randomness source (the one used
15+
//! by /dev/urandom) rather than the /dev/random (GRND_RANDOM) source. For
16+
//! more information see the linked man pages in lib.rs.
17+
//! - On Linux, "/dev/urandom is preferred and sufficient in all use cases".
18+
//! - On NetBSD, "there is no reason to ever use" GRND_RANDOM.
19+
//! - On Illumos, the default source is used for getentropy() and the like:
20+
//! https://github.com/illumos/illumos-gate/blob/89cf0c2ce8a47dcf555bb1596f9034f07b9467fa/usr/src/lib/libc/port/gen/getentropy.c#L33
21+
//! - On Solaris, both sources use FIPS 140-2 / NIST SP-900-90A DRBGs, see:
22+
//! https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2
23+
//! - On Redox, only /dev/urandom is provided.
24+
//! - On AIX, /dev/urandom will "provide cryptographically secure output".
25+
//! - On Haiku, QNX Neutrino, DragonFly, and FreeBSD, they are identical.
226
use crate::{util_libc::sys_fill_exact, Error};
327
use core::mem::MaybeUninit;
428

29+
// On Solaris 11.3, getrandom() will fail if bufsz > 1024 (bufsz > 133120 on Solaris 11.4).
30+
// This issue is not present in Illumos's implementation of getrandom().
31+
#[cfg(target_os = "solaris")]
32+
const MAX_BYTES: usize = 1024;
33+
#[cfg(not(target_os = "solaris"))]
34+
const MAX_BYTES: usize = usize::MAX;
35+
536
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
6-
sys_fill_exact(dest, |buf| unsafe {
7-
libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
8-
})
37+
for chunk in dest.chunks_mut(MAX_BYTES) {
38+
sys_fill_exact(chunk, |buf| unsafe {
39+
libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
40+
})?;
41+
}
42+
Ok(())
943
}

src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
//! | OpenBSD | `*‑openbsd` | [`getentropy`][7]
1313
//! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
1414
//! | Dragonfly BSD | `*‑dragonfly` | [`getrandom`][9]
15-
//! | Solaris, illumos | `*‑solaris`, `*‑illumos` | [`getrandom`][11] if available, otherwise [`/dev/random`][12]
15+
//! | Solaris | `*‑solaris` | [`getrandom`][11]
16+
//! | Illumos | `*‑illumos` | [`getrandom`][12]
1617
//! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`]
1718
//! | Redox | `*‑redox` | `/dev/urandom`
1819
//! | Haiku | `*‑haiku` | `/dev/urandom` (identical to `/dev/random`)
@@ -25,7 +26,7 @@
2526
//! | WASI | `wasm32‑wasi` | [`random_get`]
2627
//! | Web Browser and Node.js | `wasm*‑*‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js, see [WebAssembly support]
2728
//! | SOLID | `*-kmc-solid_*` | `SOLID_RNG_SampleRandomBytes`
28-
//! | Nintendo 3DS | `armv6k-nintendo-3ds` | [`getrandom`][1]
29+
//! | Nintendo 3DS | `armv6k-nintendo-3ds` | [`getrandom`][18]
2930
//! | PS Vita | `armv7-sony-vita-newlibeabihf` | [`getentropy`][13]
3031
//! | QNX Neutrino | `*‑nto-qnx*` | [`/dev/urandom`][14] (identical to `/dev/random`)
3132
//! | AIX | `*-ibm-aix` | [`/dev/urandom`][15]
@@ -177,12 +178,13 @@
177178
//! [8]: https://man.netbsd.org/sysctl.7
178179
//! [9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
179180
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
180-
//! [12]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
181+
//! [12]: https://illumos.org/man/2/getrandom
181182
//! [13]: https://github.com/emscripten-core/emscripten/pull/12240
182183
//! [14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html
183184
//! [15]: https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices
184185
//! [16]: https://man.netbsd.org/getrandom.2
185186
//! [17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom
187+
//! [18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d
186188
//!
187189
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
188190
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
@@ -241,6 +243,8 @@ cfg_if! {
241243
target_os = "dragonfly",
242244
target_os = "freebsd",
243245
target_os = "hurd",
246+
target_os = "illumos",
247+
target_os = "solaris",
244248
// Check for target_arch = "arm" to only include the 3DS. Does not
245249
// include the Nintendo Switch (which is target_arch = "aarch64").
246250
all(target_os = "horizon", target_arch = "arm"),
@@ -294,11 +298,7 @@ cfg_if! {
294298
} else if #[cfg(any(target_os = "android", target_os = "linux"))] {
295299
mod util_libc;
296300
#[path = "linux_android.rs"] mod imp;
297-
} else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
298-
mod util_libc;
299-
mod use_file;
300-
#[path = "solaris_illumos.rs"] mod imp;
301-
} else if #[cfg(target_os = "netbsd")] {
301+
} else if #[cfg(target_os = "freebsd")] {
302302
mod util_libc;
303303
#[path = "netbsd.rs"] mod imp;
304304
} else if #[cfg(target_os = "fuchsia")] {

src/solaris_illumos.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/use_file.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,7 @@ use core::{
99
sync::atomic::{AtomicUsize, Ordering::Relaxed},
1010
};
1111

12-
// We prefer using /dev/urandom and only use /dev/random if the OS
13-
// documentation indicates that /dev/urandom is insecure.
14-
// On Solaris/Illumos, see src/solaris_illumos.rs
15-
// On Dragonfly, Haiku, and QNX Neutrino the devices are identical.
16-
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
17-
const FILE_PATH: &str = "/dev/random\0";
18-
#[cfg(any(
19-
target_os = "aix",
20-
target_os = "android",
21-
target_os = "linux",
22-
target_os = "redox",
23-
target_os = "dragonfly",
24-
target_os = "haiku",
25-
target_os = "nto",
26-
))]
12+
// We always use /dev/urandom, see the comment in getrandom.rs.
2713
const FILE_PATH: &str = "/dev/urandom\0";
2814
const FD_UNINIT: usize = usize::max_value();
2915

0 commit comments

Comments
 (0)