|
1 |
| -//! Implementation using `libc::getrandom`. |
| 1 | +//! Implementation using getrandom(2). |
2 | 2 | //!
|
3 | 3 | //! Available since:
|
4 | 4 | //! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20
|
5 | 5 | //! - Android API level 23 (Marshmallow)
|
6 | 6 | //! - NetBSD 10.0
|
7 | 7 | //! - FreeBSD 12.0
|
8 | 8 | //! - Solaris 11.3
|
9 |
| -//! - Illumos since Dec 2018 |
| 9 | +//! - illumos since Dec 2018 |
10 | 10 | //! - DragonFly 5.7
|
11 | 11 | //! - Hurd Glibc 2.31
|
12 | 12 | //! - 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 |
13 | 22 | use crate::{util_libc::sys_fill_exact, Error};
|
14 | 23 | use core::mem::MaybeUninit;
|
15 | 24 |
|
| 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 | + |
16 | 32 | 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 | + } |
20 | 38 | }
|
0 commit comments