1 use crate::std::mem; 2 use crate::std::ptr; 3 use crate::std::sys::c; 4 5 pub fn hashmap_random_keys() -> (u64, u64) { 6 let mut v = (0, 0); 7 let ret = unsafe { 8 c::BCryptGenRandom( 9 ptr::null_mut(), 10 &mut v as *mut _ as *mut u8, 11 mem::size_of_val(&v) as c::ULONG, 12 c::BCRYPT_USE_SYSTEM_PREFERRED_RNG, 13 ) 14 }; 15 if c::nt_success(ret) { 16 v 17 } else { 18 fallback_rng() 19 } 20 } 21 22 /// Generate random numbers using the fallback RNG function (RtlGenRandom) 23 /// 24 /// This is necessary because of a failure to load the SysWOW64 variant of the 25 /// bcryptprimitives.dll library from code that lives in bcrypt.dll 26 /// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1788004#c9> 27 #[cfg(not(target_vendor = "uwp"))] 28 #[inline(never)] 29 fn fallback_rng() -> (u64, u64) { 30 use crate::std::ffi::c_void; 31 use crate::std::io; 32 33 let mut v = (0, 0); 34 let ret = unsafe { 35 c::RtlGenRandom( 36 &mut v as *mut _ as *mut c_void, 37 mem::size_of_val(&v) as c::ULONG, 38 ) 39 }; 40 41 if ret != 0 { 42 v 43 } else { 44 panic!("fallback RNG broken: {}", io::Error::last_os_error()) 45 } 46 } 47 48 /// We can't use RtlGenRandom with UWP, so there is no fallback 49 #[cfg(target_vendor = "uwp")] 50 #[inline(never)] 51 fn fallback_rng() -> (u64, u64) { 52 panic!("fallback RNG broken: RtlGenRandom() not supported on UWP"); 53 } 54