Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton committed Sep 7, 2022
1 parent ff479b1 commit 0bd71e4
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 38 deletions.
2 changes: 1 addition & 1 deletion library/std/src/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pub fn nt_success(status: NTSTATUS) -> bool {
status >= 0
}

pub const BCRYPT_RNG_ALG_HANDLE: usize = 0x81;
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;

#[repr(C)]
pub struct UNICODE_STRING {
Expand Down
41 changes: 4 additions & 37 deletions library/std/src/sys/windows/rand.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,16 @@
//! # Random key generation
//!
//! This module wraps the RNG provided by the OS. There are a few different
//! ways to interface with the OS RNG so it's worth exploring each of the options.
//! Note that at the time of writing these all go through the (undocumented)
//! `bcryptPrimitives.dll` but they use different route to get there.
//!
//! Originally we were using [`RtlGenRandom`], however that function is
//! deprecated and warns it "may be altered or unavailable in subsequent versions".
//!
//! So we switched to [`BCryptGenRandom`] with the `BCRYPT_USE_SYSTEM_PREFERRED_RNG`
//! flag to query and find the system configured RNG. However, this change caused a small
//! but significant number of users to experience panics caused by a failure of
//! this function. See [#94098].
//!
//! The current version changes this to use the `BCRYPT_RNG_ALG_HANDLE`
//! [Pseudo-handle], which gets the default RNG algorithm without querying the
//! system preference thus hopefully avoiding the previous issue.
//! This is only supported on Windows 10+ so a fallback is used for older versions.
//!
//! [#94098]: https://github.com/rust-lang/rust/issues/94098
//! [`RtlGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! [Pseudo-handle]: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles
use crate::io;
use crate::mem;
use crate::ptr;
use crate::sys::c;

/// Generates high quality secure random keys for use by [`HashMap`].
///
/// This is used to seed the default [`RandomState`].
///
/// [`HashMap`]: crate::collections::HashMap
/// [`RandomState`]: crate::collections::hash_map::RandomState
pub fn hashmap_random_keys() -> (u64, u64) {
let mut v = (0, 0);
let ret = unsafe {
let size = mem::size_of_val(&v).try_into().unwrap();
c::BCryptGenRandom(
// BCRYPT_RNG_ALG_HANDLE is only supported in Windows 10+.
// So for Windows 8.1 and Windows 7 we'll need a fallback when this fails.
ptr::invalid_mut(c::BCRYPT_RNG_ALG_HANDLE),
ptr::addr_of_mut!(v).cast(),
size,
0,
ptr::null_mut(),
&mut v as *mut _ as *mut u8,
mem::size_of_val(&v) as c::ULONG,
c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
)
};
if ret != 0 { fallback_rng() } else { v }
Expand Down

0 comments on commit 0bd71e4

Please sign in to comment.