Address review feedback
This commit is contained in:
parent
0c92519d01
commit
3de6c2ca33
@ -1,9 +1,9 @@
|
||||
use crate::io;
|
||||
use crate::lazy;
|
||||
use crate::mem;
|
||||
use crate::sync;
|
||||
use crate::sys::c;
|
||||
|
||||
// The kinds of HashMap RNG that may be available
|
||||
/// The kinds of HashMap RNG that may be available
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum HashMapRng {
|
||||
Preferred,
|
||||
@ -16,44 +16,35 @@ pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
preferred_rng().expect("couldn't generate random bytes with preferred RNG")
|
||||
}
|
||||
HashMapRng::Fallback => {
|
||||
fallback_rng().unwrap().expect("couldn't generate random bytes with fallback RNG")
|
||||
fallback_rng().expect("couldn't generate random bytes with fallback RNG")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the HashMap RNG that should be used
|
||||
//
|
||||
// Panics if they are both broken
|
||||
/// Returns the HashMap RNG that should be used
|
||||
///
|
||||
/// Panics if they are both broken
|
||||
fn get_hashmap_rng() -> HashMapRng {
|
||||
// Assume that if the preferred RNG is broken the first time we use it, it likely means
|
||||
// that: the DLL has failed to load, there is no point to calling it over-and-over again,
|
||||
// and we should cache the result
|
||||
static INIT: sync::Once = sync::Once::new();
|
||||
static mut HASHMAP_RNG: HashMapRng = HashMapRng::Preferred;
|
||||
|
||||
unsafe {
|
||||
INIT.call_once(|| HASHMAP_RNG = choose_hashmap_rng());
|
||||
HASHMAP_RNG
|
||||
}
|
||||
static VALUE: lazy::SyncOnceCell<HashMapRng> = lazy::SyncOnceCell::new();
|
||||
*VALUE.get_or_init(choose_hashmap_rng)
|
||||
}
|
||||
|
||||
// Test whether we should use the preferred or fallback RNG
|
||||
//
|
||||
// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful,
|
||||
// we choose that
|
||||
//
|
||||
// Panics if both the preferred and the fallback RNG are both non-functional
|
||||
/// Test whether we should use the preferred or fallback RNG
|
||||
///
|
||||
/// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful,
|
||||
/// we choose that
|
||||
///
|
||||
/// Panics if both the preferred and the fallback RNG are both non-functional
|
||||
fn choose_hashmap_rng() -> HashMapRng {
|
||||
let preferred_error = match preferred_rng() {
|
||||
Ok(_) => return HashMapRng::Preferred,
|
||||
Err(e) => e,
|
||||
};
|
||||
|
||||
// On UWP, there is no fallback
|
||||
let fallback_result = fallback_rng()
|
||||
.unwrap_or_else(|| panic!("preferred RNG broken: `{}`, no fallback", preferred_error));
|
||||
|
||||
match fallback_result {
|
||||
match fallback_rng() {
|
||||
Ok(_) => return HashMapRng::Fallback,
|
||||
Err(fallback_error) => panic!(
|
||||
"preferred RNG broken: `{}`, fallback RNG broken: `{}`",
|
||||
@ -62,7 +53,7 @@ fn choose_hashmap_rng() -> HashMapRng {
|
||||
}
|
||||
}
|
||||
|
||||
// Generate random numbers using the preferred RNG function (BCryptGenRandom)
|
||||
/// Generate random numbers using the preferred RNG function (BCryptGenRandom)
|
||||
fn preferred_rng() -> Result<(u64, u64), io::Error> {
|
||||
use crate::ptr;
|
||||
|
||||
@ -79,18 +70,18 @@ fn preferred_rng() -> Result<(u64, u64), io::Error> {
|
||||
if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
|
||||
}
|
||||
|
||||
// Generate random numbers using the fallback RNG function (RtlGenRandom)
|
||||
/// Generate random numbers using the fallback RNG function (RtlGenRandom)
|
||||
#[cfg(not(target_vendor = "uwp"))]
|
||||
fn fallback_rng() -> Option<Result<(u64, u64), io::Error>> {
|
||||
fn fallback_rng() -> Result<(u64, u64), io::Error> {
|
||||
let mut v = (0, 0);
|
||||
let ret =
|
||||
unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
|
||||
|
||||
Some(if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) })
|
||||
if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
|
||||
}
|
||||
|
||||
// We can't use RtlGenRandom with UWP, so there is no fallback
|
||||
/// We can't use RtlGenRandom with UWP, so there is no fallback
|
||||
#[cfg(target_vendor = "uwp")]
|
||||
fn fallback_rng() -> Option<Result<(u64, u64), io::Error>> {
|
||||
None
|
||||
fn fallback_rng() -> Result<(u64, u64), io::Error> {
|
||||
Err(io::const_io_error!(io::ErrorKind::Unsupported, "unsupported on UWP"))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user