Skip to content

Commit 08caefb

Browse files
committed
Windows: Use ProcessPrng for random keys
1 parent 43fdd49 commit 08caefb

File tree

4 files changed

+28
-44
lines changed

4 files changed

+28
-44
lines changed

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

+15
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,21 @@ pub unsafe fn NtWriteFile(
321321
}
322322
}
323323

324+
// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
325+
cfg_if::cfg_if! {
326+
if #[cfg(not(target_vendor = "win7"))] {
327+
#[cfg(target_arch = "x86")]
328+
#[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
329+
extern "system" {
330+
pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
331+
}
332+
#[cfg(not(target_arch = "x86"))]
333+
#[link(name = "bcryptprimitives", kind = "raw-dylib")]
334+
extern "system" {
335+
pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
336+
}
337+
}}
338+
324339
// Functions that aren't available on every version of Windows that we support,
325340
// but we still use them and just provide some form of a fallback implementation.
326341
compat_fn_with_fallback! {

library/std/src/sys/pal/windows/c/bindings.txt

-4
Original file line numberDiff line numberDiff line change
@@ -2180,10 +2180,6 @@ Windows.Win32.Networking.WinSock.WSATRY_AGAIN
21802180
Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND
21812181
Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED
21822182
Windows.Win32.Security.Authentication.Identity.RtlGenRandom
2183-
Windows.Win32.Security.Cryptography.BCRYPT_ALG_HANDLE
2184-
Windows.Win32.Security.Cryptography.BCRYPT_USE_SYSTEM_PREFERRED_RNG
2185-
Windows.Win32.Security.Cryptography.BCryptGenRandom
2186-
Windows.Win32.Security.Cryptography.BCRYPTGENRANDOM_FLAGS
21872183
Windows.Win32.Security.SECURITY_ATTRIBUTES
21882184
Windows.Win32.Security.TOKEN_ACCESS_MASK
21892185
Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE

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

-12
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ extern "system" {
1515
pub fn RtlGenRandom(randombuffer: *mut ::core::ffi::c_void, randombufferlength: u32)
1616
-> BOOLEAN;
1717
}
18-
#[link(name = "bcrypt")]
19-
extern "system" {
20-
pub fn BCryptGenRandom(
21-
halgorithm: BCRYPT_ALG_HANDLE,
22-
pbbuffer: *mut u8,
23-
cbbuffer: u32,
24-
dwflags: BCRYPTGENRANDOM_FLAGS,
25-
) -> NTSTATUS;
26-
}
2718
#[link(name = "kernel32")]
2819
extern "system" {
2920
pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
@@ -889,9 +880,6 @@ impl ::core::clone::Clone for ARM64_NT_NEON128_0 {
889880
*self
890881
}
891882
}
892-
pub type BCRYPTGENRANDOM_FLAGS = u32;
893-
pub type BCRYPT_ALG_HANDLE = *mut ::core::ffi::c_void;
894-
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: BCRYPTGENRANDOM_FLAGS = 2u32;
895883
pub const BELOW_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 16384u32;
896884
pub type BOOL = i32;
897885
pub type BOOLEAN = u8;
+13-28
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,27 @@
1-
use crate::mem;
2-
use crate::ptr;
31
use crate::sys::c;
2+
use core::mem;
3+
use core::ptr;
44

5+
#[cfg(not(target_vendor = "win7"))]
6+
#[inline]
57
pub fn hashmap_random_keys() -> (u64, u64) {
68
let mut v = (0, 0);
7-
let ret = unsafe {
8-
c::BCryptGenRandom(
9-
ptr::null_mut(),
10-
core::ptr::addr_of_mut!(v) 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) { v } else { fallback_rng() }
9+
let ret = unsafe { c::ProcessPrng(ptr::addr_of_mut!(v).cast::<u8>(), mem::size_of_val(&v)) };
10+
// ProcessPrng is documented as always returning `TRUE`.
11+
// https://learn.microsoft.com/en-us/windows/win32/seccng/processprng#return-value
12+
debug_assert_eq!(ret, c::TRUE);
13+
v
1614
}
1715

18-
/// Generate random numbers using the fallback RNG function (RtlGenRandom)
19-
///
20-
/// This is necessary because of a failure to load the SysWOW64 variant of the
21-
/// bcryptprimitives.dll library from code that lives in bcrypt.dll
22-
/// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1788004#c9>
23-
#[cfg(not(target_vendor = "uwp"))]
24-
#[inline(never)]
25-
fn fallback_rng() -> (u64, u64) {
16+
#[cfg(target_vendor = "win7")]
17+
pub fn hashmap_random_keys() -> (u64, u64) {
2618
use crate::ffi::c_void;
2719
use crate::io;
2820

2921
let mut v = (0, 0);
3022
let ret = unsafe {
31-
c::RtlGenRandom(core::ptr::addr_of_mut!(v) as *mut c_void, mem::size_of_val(&v) as c::ULONG)
23+
c::RtlGenRandom(ptr::addr_of_mut!(v).cast::<c_void>(), mem::size_of_val(&v) as c::ULONG)
3224
};
3325

34-
if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
35-
}
36-
37-
/// We can't use RtlGenRandom with UWP, so there is no fallback
38-
#[cfg(target_vendor = "uwp")]
39-
#[inline(never)]
40-
fn fallback_rng() -> (u64, u64) {
41-
panic!("fallback RNG broken: RtlGenRandom() not supported on UWP");
26+
if ret != 0 { v } else { panic!("RNG broken: {}", io::Error::last_os_error()) }
4227
}

0 commit comments

Comments
 (0)