diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/getrandom/src/windows.rs | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/getrandom/src/windows.rs')
-rw-r--r-- | vendor/getrandom/src/windows.rs | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/vendor/getrandom/src/windows.rs b/vendor/getrandom/src/windows.rs index 41dc37a5c..92d70429e 100644 --- a/vendor/getrandom/src/windows.rs +++ b/vendor/getrandom/src/windows.rs @@ -7,7 +7,7 @@ // except according to those terms. use crate::Error; -use core::{ffi::c_void, num::NonZeroU32, ptr}; +use core::{ffi::c_void, mem::MaybeUninit, num::NonZeroU32, ptr}; const BCRYPT_USE_SYSTEM_PREFERRED_RNG: u32 = 0x00000002; @@ -21,20 +21,37 @@ extern "system" { ) -> u32; } -pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { +// Forbidden when targetting UWP +#[cfg(not(target_vendor = "uwp"))] +#[link(name = "advapi32")] +extern "system" { + #[link_name = "SystemFunction036"] + fn RtlGenRandom(RandomBuffer: *mut c_void, RandomBufferLength: u32) -> u8; +} + +pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { // Prevent overflow of u32 for chunk in dest.chunks_mut(u32::max_value() as usize) { // BCryptGenRandom was introduced in Windows Vista let ret = unsafe { BCryptGenRandom( ptr::null_mut(), - chunk.as_mut_ptr(), + chunk.as_mut_ptr() as *mut u8, chunk.len() as u32, BCRYPT_USE_SYSTEM_PREFERRED_RNG, ) }; // NTSTATUS codes use the two highest bits for severity status. if ret >> 30 == 0b11 { + // Failed. Try RtlGenRandom as a fallback. + #[cfg(not(target_vendor = "uwp"))] + { + let ret = + unsafe { RtlGenRandom(chunk.as_mut_ptr() as *mut c_void, chunk.len() as u32) }; + if ret != 0 { + continue; + } + } // We zeroize the highest bit, so the error code will reside // inside the range designated for OS codes. let code = ret ^ (1 << 31); |