xref: /drstd/src/std/sys/windows/rand.rs (revision 0fe3ff0054d3aec7fbf9bddecfecb10bc7d23a51)
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