Skip to content

Commit bc793c9

Browse files
committed
Use BCRYPT_RNG_ALG_HANDLE by default
Also briefly document the history of `sys/windows/rand.rs` as they may be relevant to any future changes.
1 parent e4f0493 commit bc793c9

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

library/std/src/sys/windows/c.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ pub fn nt_success(status: NTSTATUS) -> bool {
285285
status >= 0
286286
}
287287

288-
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
288+
pub const BCRYPT_RNG_ALG_HANDLE: usize = 0x81;
289289

290290
#[repr(C)]
291291
pub struct UNICODE_STRING {

library/std/src/sys/windows/rand.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,49 @@
1+
//! # Random key generation
2+
//!
3+
//! This module wraps the RNG provided by the OS. There are a few different
4+
//! ways to interface with the OS RNG so it's worth exploring each of the options.
5+
//! Note that at the time of writing these all go through the (undocumented)
6+
//! `bcryptPrimitives.dll` but they use different route to get there.
7+
//!
8+
//! Originally we were using [`RtlGenRandom`], however that function is
9+
//! deprecated and warns it "may be altered or unavailable in subsequent versions".
10+
//!
11+
//! So we switched to [`BCryptGenRandom`] with the `BCRYPT_USE_SYSTEM_PREFERRED_RNG`
12+
//! flag to query and find the system configured RNG. However, this change caused a small
13+
//! but significant number of users to experience panics caused by a failure of
14+
//! this function. See [#94098].
15+
//!
16+
//! The current version changes this to use the `BCRYPT_RNG_ALG_HANDLE`
17+
//! [Pseudo-handle], which gets the default RNG algorithm without querying the
18+
//! system preference thus hopefully avoiding the previous issue.
19+
//! This is only supported on Windows 10+ so a fallback is used for older versions.
20+
//!
21+
//! [#94098]: https://github.com/rust-lang/rust/issues/94098
22+
//! [`RtlGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
23+
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
24+
//! [Pseudo-handle]: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles
125
use crate::io;
226
use crate::mem;
327
use crate::ptr;
428
use crate::sys::c;
529

30+
/// Generates high quality secure random keys for use by [`HashMap`].
31+
///
32+
/// This is used to seed the default [`RandomState`].
33+
///
34+
/// [`HashMap`]: crate::collections::HashMap
35+
/// [`RandomState`]: crate::collections::hash_map::RandomState
636
pub fn hashmap_random_keys() -> (u64, u64) {
737
let mut v = (0, 0);
838
let ret = unsafe {
39+
let size = mem::size_of_val(&v).try_into().unwrap();
940
c::BCryptGenRandom(
10-
ptr::null_mut(),
11-
&mut v as *mut _ as *mut u8,
12-
mem::size_of_val(&v) as c::ULONG,
13-
c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
41+
// BCRYPT_RNG_ALG_HANDLE is only supported in Windows 10+.
42+
// So for Windows 8.1 and Windows 7 we'll need a fallback when this fails.
43+
ptr::invalid_mut(c::BCRYPT_RNG_ALG_HANDLE),
44+
ptr::addr_of_mut!(v).cast(),
45+
size,
46+
0,
1447
)
1548
};
1649
if ret != 0 { fallback_rng() } else { v }

0 commit comments

Comments
 (0)