Skip to content

Commit 9f20e28

Browse files
Remove unnecessary error branch of ProcessPrng (#579)
ProcessPrng is guaranteed to never fail during runtime, so there's no need to handle that case. Also found that windows_targets declares all extern functions as pub, so wrapped the link! macro in a local module to prevent it from being accessible outside of windows.rs.
1 parent 9fb4a9a commit 9f20e28

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

src/backends/windows.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Implementation for Windows 10 and later
22
//!
33
//! On Windows 10 and later, ProcessPrng "is the primary interface to the
4-
//! user-mode per-processer PRNGs" and only requires bcryptprimitives.dll,
4+
//! user-mode per-processor PRNGs" and only requires bcryptprimitives.dll,
55
//! making it a better option than the other Windows RNG APIs:
66
//! - BCryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
77
//! - Requires bcrypt.dll (which loads bcryptprimitives.dll anyway)
@@ -28,20 +28,19 @@ pub use crate::util::{inner_u32, inner_u64};
2828
// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As
2929
// bcryptprimitives.dll lacks an import library, we use the windows-targets
3030
// crate to link to it.
31-
windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL);
32-
#[allow(clippy::upper_case_acronyms)]
33-
pub type BOOL = i32;
34-
pub const TRUE: BOOL = 1i32;
31+
//
32+
// TODO(MSRV 1.71): Migrate to linking as raw-dylib directly.
33+
// https://github.com/joboet/rust/blob/5c1c72572479afe98734d5f78fa862abe662c41a/library/std/src/sys/pal/windows/c.rs#L119
34+
// https://github.com/microsoft/windows-rs/blob/0.60.0/crates/libs/targets/src/lib.rs
35+
windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> i32);
3536

3637
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
37-
// ProcessPrng should always return TRUE, but we check just in case.
38-
match unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) } {
39-
TRUE => Ok(()),
40-
_ => Err(Error::WINDOWS_PROCESS_PRNG),
41-
}
42-
}
43-
44-
impl Error {
45-
/// Calling Windows ProcessPrng failed.
46-
pub(crate) const WINDOWS_PROCESS_PRNG: Error = Self::new_internal(10);
38+
let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) };
39+
// Since Windows 10, calls to the user-mode RNG are guaranteed to never
40+
// fail during runtime (rare windows W); `ProcessPrng` will only ever
41+
// return 1 (which is how windows represents TRUE).
42+
// See the bottom of page 6 of the aforementioned Windows RNG
43+
// whitepaper for more information.
44+
debug_assert!(result == 1);
45+
Ok(())
4746
}

src/error.rs

-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ impl Error {
114114
target_os = "tvos",
115115
))]
116116
Error::IOS_RANDOM_GEN => "SecRandomCopyBytes: iOS Security framework failure",
117-
#[cfg(all(windows, not(target_vendor = "win7")))]
118-
Error::WINDOWS_PROCESS_PRNG => "ProcessPrng: Windows system function failure",
119117
#[cfg(all(windows, target_vendor = "win7"))]
120118
Error::WINDOWS_RTL_GEN_RANDOM => "RtlGenRandom: Windows system function failure",
121119
#[cfg(getrandom_backend = "wasm_js")]

0 commit comments

Comments
 (0)