Skip to content

Commit

Permalink
Solaris: consistantly use /dev/random source
Browse files Browse the repository at this point in the history
On Solaris, we opt to use /dev/random source instead of /dev/urandom due
to reasons explained in the comments and
[in this Solaris blog post](https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2).

However, we haven't been making the same choice when getting randomness
via the `getrandom(2)` function, as we just pass `0` for the flags. We
[used to](https://github.com/rust-random/rand/pull/730/files#diff-694d4302a3ff2a976f2fbd34bc05ada22ee61a4e21d2d985beab27f7a809268fR151)
always set `GRND_RANDOM`, but that was removed in the move from `OsRng`
to this crate.

For context, rust-random/rand#730,
#9, and
#51 are the major changes
to the Solaris/Illumos implementation over the years.

See the solaris documentation for:
- [`getrandom(2)`](https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html)
- [`urandom(4)`](https://docs.oracle.com/cd/E88353_01/html/E37851/urandom-4d.html)

I also updated the doucmentation to better reflect when
[Illumos added the `getrandom(2)` function](https://www.illumos.org/issues/9971#change-23483).

Signed-off-by: Joe Richey <joerichey@google.com>
  • Loading branch information
josephlr committed Oct 23, 2022
1 parent 2ec38ad commit b1ec46a
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -18,7 +18,7 @@ compiler_builtins = { version = "0.1", optional = true }
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }

[target.'cfg(unix)'.dependencies]
libc = { version = "0.2.120", default-features = false }
libc = { version = "0.1.128", default-features = false }

[target.'cfg(target_os = "wasi")'.dependencies]
wasi = "0.11"
Expand Down
15 changes: 5 additions & 10 deletions src/solaris_illumos.rs
Expand Up @@ -8,12 +8,11 @@

//! Implementation for the Solaris family
//!
//! Read from `/dev/random`, with chunks of limited size (256 bytes).
//! `/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`.
//! secure. We choose to read from `/dev/random` (and use GRND_RANDOM).
//!
//! Since Solaris 11.3 and mid-2015 illumos, the `getrandom` syscall is available.
//! 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.
Expand All @@ -24,21 +23,17 @@ use crate::{
};
use core::mem::{self, MaybeUninit};

#[cfg(target_os = "illumos")]
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
#[cfg(target_os = "solaris")]
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::c_int;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// getrandom(2) was introduced in Solaris 11.3 for Illumos in 2015.
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 { 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 {
func(buf.as_mut_ptr() as *mut u8, buf.len(), 0) as libc::ssize_t
func(buf.as_mut_ptr() as *mut u8, buf.len(), libc::GRND_RANDOM)
})?
}
Ok(())
Expand Down

0 comments on commit b1ec46a

Please sign in to comment.