Skip to content

Commit c526c89

Browse files
chuttennewpavlov
andauthored
Add in a RtlGenRandom fallback for non-UWP Windows (#337)
* Add in a RtlGenRandom fallback for non-UWP Windows In some instances BCryptRandom will fail when RtlGenRandom will work. On UWP, we might be unable to actually use RtlGenRandom. Thread the needle and use RtlGenRandom when we have to, when we're able. See also rust-lang/rust#108060 Fixes #314 * style suggestion Co-authored-by: Artyom Pavlov <newpavlov@gmail.com> * appease clippy --------- Co-authored-by: Artyom Pavlov <newpavlov@gmail.com>
1 parent 7c83ea0 commit c526c89

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

src/windows.rs

+17
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ extern "system" {
2121
) -> u32;
2222
}
2323

24+
// Forbidden when targetting UWP
25+
#[cfg(not(target_vendor = "uwp"))]
26+
#[link(name = "advapi32")]
27+
extern "system" {
28+
#[link_name = "SystemFunction036"]
29+
fn RtlGenRandom(RandomBuffer: *mut c_void, RandomBufferLength: u32) -> u8;
30+
}
31+
2432
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
2533
// Prevent overflow of u32
2634
for chunk in dest.chunks_mut(u32::max_value() as usize) {
@@ -35,6 +43,15 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
3543
};
3644
// NTSTATUS codes use the two highest bits for severity status.
3745
if ret >> 30 == 0b11 {
46+
// Failed. Try RtlGenRandom as a fallback.
47+
#[cfg(not(target_vendor = "uwp"))]
48+
{
49+
let ret =
50+
unsafe { RtlGenRandom(chunk.as_mut_ptr() as *mut c_void, chunk.len() as u32) };
51+
if ret != 0 {
52+
continue;
53+
}
54+
}
3855
// We zeroize the highest bit, so the error code will reside
3956
// inside the range designated for OS codes.
4057
let code = ret ^ (1 << 31);

0 commit comments

Comments
 (0)