From 46673bb08ffa22f21287349d966d875038e41b37 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 17 Jul 2022 11:11:05 +0100 Subject: [PATCH] Simplify Windows `hashmap_random_keys` --- library/std/src/sys/windows/rand.rs | 68 ++++------------------------- 1 file changed, 8 insertions(+), 60 deletions(-) diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index 57248e3651ba2..f8fd93a7398e1 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"); }