From: Chris Denton Date: Sun, 17 Jul 2022 10:11:05 +0000 (+0100) Subject: Simplify Windows `hashmap_random_keys` X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=46673bb08ffa22f21287349d966d875038e41b37;p=rust.git Simplify Windows `hashmap_random_keys` --- diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index 57248e3651b..f8fd93a7398 100644 --- a/library/std/src/sys/windows/rand.rs +++ b/library/std/src/sys/windows/rand.rs @@ -1,62 +1,9 @@ use crate::io; use crate::mem; -use crate::sync; +use crate::ptr; use crate::sys::c; -/// The kinds of HashMap RNG that may be available -#[derive(Clone, Copy, Debug, PartialEq)] -enum HashMapRng { - Preferred, - Fallback, -} - pub fn hashmap_random_keys() -> (u64, u64) { - match get_hashmap_rng() { - HashMapRng::Preferred => { - preferred_rng().expect("couldn't generate random bytes with preferred RNG") - } - HashMapRng::Fallback => { - 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 -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 VALUE: sync::OnceLock = sync::OnceLock::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 -fn choose_hashmap_rng() -> HashMapRng { - let preferred_error = match preferred_rng() { - Ok(_) => return HashMapRng::Preferred, - Err(e) => e, - }; - - match fallback_rng() { - Ok(_) => return HashMapRng::Fallback, - Err(fallback_error) => panic!( - "preferred RNG broken: `{}`, fallback RNG broken: `{}`", - preferred_error, fallback_error - ), - } -} - -/// Generate random numbers using the preferred RNG function (BCryptGenRandom) -fn preferred_rng() -> Result<(u64, u64), io::Error> { - use crate::ptr; - let mut v = (0, 0); let ret = unsafe { c::BCryptGenRandom( @@ -66,22 +13,23 @@ fn preferred_rng() -> Result<(u64, u64), io::Error> { c::BCRYPT_USE_SYSTEM_PREFERRED_RNG, ) }; - - if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) } + if ret != 0 { fallback_rng() } else { v } } /// Generate random numbers using the fallback RNG function (RtlGenRandom) #[cfg(not(target_vendor = "uwp"))] -fn fallback_rng() -> Result<(u64, u64), io::Error> { +#[inline(never)] +fn fallback_rng() -> (u64, u64) { 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) }; - if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) } + if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) } } /// We can't use RtlGenRandom with UWP, so there is no fallback #[cfg(target_vendor = "uwp")] -fn fallback_rng() -> Result<(u64, u64), io::Error> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "RtlGenRandom() not supported on UWP")) +#[inline(never)] +fn fallback_rng() -> (u64, u64) { + panic!("fallback RNG broken: RtlGenRandom() not supported on UWP"); }