Skip to content

Commit 7f909f0

Browse files
committed
Use libc::getrandom on Solaris and update docs.
#417 used `getentropy(2)` on Solaris, but after looking at [the blog post introducing `getrandom()` and `getentropy()`](https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2), it seems like we should prefer using `getrandom` based on this quote: > On Solaris the output of getentropy(2) is entropy and should not be used where randomness is needed, in particular it must not be used where an IV or nonce is needed when calling a cryptographic operation. It is intended only for seeding a user space RBG (Random Bit Generator) system. More specifically the data returned by getentropy(2) has not had the required FIPS 140-2 processing for the DRBG applied to it. I also updated some of the documentation explaining: - Why we ever use `getentropy(2)` - Why we don't ever set `GRND_RANDOM` Signed-off-by: Joe Richey <[email protected]>
1 parent 924c88d commit 7f909f0

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

src/getentropy.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
//! Implementation using libc::getentropy
1+
//! Implementation using getentropy(2)
22
//!
33
//! Available since:
44
//! - macOS 10.12
55
//! - OpenBSD 5.6
66
//! - Emscripten 2.0.5
77
//! - vita newlib since Dec 2021
8+
//!
9+
//! For these targets, we use getentropy(2) because getrandom(2) doesn't exist.
810
use crate::{util_libc::last_os_error, Error};
911
use core::mem::MaybeUninit;
1012

src/getrandom.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
1-
//! Implementation using `libc::getrandom`.
1+
//! Implementation using getrandom(2).
22
//!
33
//! Available since:
44
//! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20
55
//! - Android API level 23 (Marshmallow)
66
//! - NetBSD 10.0
77
//! - FreeBSD 12.0
88
//! - Solaris 11.3
9-
//! - Illumos since Dec 2018
9+
//! - illumos since Dec 2018
1010
//! - DragonFly 5.7
1111
//! - Hurd Glibc 2.31
1212
//! - shim-3ds since Feb 2022
13+
//!
14+
//! For all platforms, we always use the default entropy pool and never set the
15+
//! GRND_RANDOM flag to use the /dev/random pool. On Linux/Android/Hurd, using
16+
//! GRND_RANDOM is not recommended. On NetBSD/FreeBSD/Dragonfly/3ds, it does
17+
//! nothing. On illumos, the default pool is used to implement getentropy(2),
18+
//! so we assume it is acceptable here. On Solaris, the story is less clear,
19+
//! but both pools use standard DRBGs (FIPS 140-2 and NIST SP-900-90A), so we
20+
//! use the default pool. For more information on Solaris see this blog post:
21+
//! https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2
1322
use crate::{util_libc::sys_fill_exact, Error};
1423
use core::mem::MaybeUninit;
1524

25+
// On Solaris 11.3, if bufsz > 1024 (> 133120 on Solaris 11.4) calls to
26+
// getrandom(2) will always fail, so we chunk the buffer if it is too long.
27+
#[cfg(target_os = "solaris")]
28+
const MAX_BYTES: usize = 1024;
29+
#[cfg(not(target_os = "solaris"))]
30+
const MAX_BYTES: usize = usize::MAX;
31+
1632
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
17-
sys_fill_exact(dest, |buf| unsafe {
18-
libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
19-
})
33+
for chunk in dest.chunks_mut(MAX_BYTES) {
34+
sys_fill_exact(dest, |buf| unsafe {
35+
libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
36+
})
37+
}
2038
}

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +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 | `*‑solaris` | [`getentropy`][11]
16-
//! | Illumos | `*‑illumos` | [`getrandom`][12]
15+
//! | Solaris | `*‑solaris` | [`getrandom`][11]
16+
//! | illumos | `*‑illumos` | [`getrandom`][12]
1717
//! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`]
1818
//! | Redox | `*‑redox` | `/dev/urandom`
1919
//! | Haiku | `*‑haiku` | `/dev/urandom` (identical to `/dev/random`)
@@ -173,7 +173,7 @@
173173
//! [7]: https://man.openbsd.org/getentropy.2
174174
//! [8]: https://man.netbsd.org/sysctl.7
175175
//! [9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
176-
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getentropy-2.html
176+
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
177177
//! [12]: https://illumos.org/man/2/getrandom
178178
//! [13]: https://github.com/emscripten-core/emscripten/pull/12240
179179
//! [14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html
@@ -238,7 +238,6 @@ cfg_if! {
238238
} else if #[cfg(any(
239239
target_os = "macos",
240240
target_os = "openbsd",
241-
target_os = "solaris",
242241
target_os = "vita",
243242
target_os = "emscripten",
244243
))] {
@@ -248,6 +247,7 @@ cfg_if! {
248247
target_os = "dragonfly",
249248
target_os = "freebsd",
250249
target_os = "hurd",
250+
target_os = "solaris",
251251
target_os = "illumos",
252252
// Check for target_arch = "arm" to only include the 3DS. Does not
253253
// include the Nintendo Switch (which is target_arch = "aarch64").

0 commit comments

Comments
 (0)