Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ use std::env;

fn main() {
let target = env::var("TARGET").expect("TARGET was not set");
if target.contains("-uwp-windows-") {
if target.contains("windows") {
// for BCryptGenRandom
println!("cargo:rustc-link-lib=bcrypt");
} else if target.contains("windows") {
// for RtlGenRandom (aka SystemFunction036)
println!("cargo:rustc-link-lib=advapi32");
} else if target.contains("apple-ios") {
// for SecRandomCopyBytes and kSecRandomDefault
println!("cargo:rustc-link-lib=framework=Security");
Expand Down
9 changes: 2 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
//! | Target | Target Triple | Implementation
//! | ----------------- | ------------------ | --------------
//! | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random` |
//! | Windows | `*‑pc‑windows‑*` | [`RtlGenRandom`][3] |
//! | [Windows UWP][22] | `*‑uwp‑windows‑*` | [`BCryptGenRandom`][23] |
//! | Windows | `*‑pc‑windows‑*` | [`BCryptGenRandom`][3] |
//! | macOS | `*‑apple‑darwin` | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
//! | iOS | `*‑apple‑ios` | [`SecRandomCopyBytes`][4]
//! | FreeBSD | `*‑freebsd` | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
Expand Down Expand Up @@ -121,7 +120,7 @@
//!
//! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
//! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
//! [3]: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-rtlgenrandom
//! [3]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
//! [6]: https://man.openbsd.org/getentropy.2
Expand All @@ -139,8 +138,6 @@
//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
//! [20]: https://www.unix.com/man-page/mojave/4/random/
//! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
//! [22]: https://docs.microsoft.com/en-us/windows/uwp/
//! [23]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom

#![doc(
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
Expand Down Expand Up @@ -201,8 +198,6 @@ cfg_if! {
} else if #[cfg(target_os = "vxworks")] {
mod util_libc;
#[path = "vxworks.rs"] mod imp;
} else if #[cfg(all(windows, target_vendor = "uwp"))] {
#[path = "windows_uwp.rs"] mod imp;
} else if #[cfg(windows)] {
#[path = "windows.rs"] mod imp;
} else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
Expand Down
33 changes: 27 additions & 6 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,41 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for Windows
use crate::Error;
use core::{ffi::c_void, num::NonZeroU32, ptr};

const BCRYPT_USE_SYSTEM_PREFERRED_RNG: u32 = 0x00000002;

extern "system" {
#[link_name = "SystemFunction036"]
fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8;
fn BCryptGenRandom(
hAlgorithm: *mut c_void,
pBuffer: *mut u8,
cbBuffer: u32,
dwFlags: u32,
) -> u32;
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
// Prevent overflow of u32
for chunk in dest.chunks_mut(u32::max_value() as usize) {
let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr(), chunk.len() as u32) };
if ret == 0 {
return Err(Error::WINDOWS_RTL_GEN_RANDOM);
let ret = unsafe {
BCryptGenRandom(
ptr::null_mut(),
chunk.as_mut_ptr(),
chunk.len() as u32,
BCRYPT_USE_SYSTEM_PREFERRED_RNG,
)
};
// NTSTATUS codes use the two highest bits for severity status.
if ret >> 30 == 0b11 {
// We zeroize the highest bit, so the error code will reside
// inside the range designated for OS codes.
let code = ret ^ (1 << 31);
// SAFETY: the second highest bit is always equal to one,
// so it's impossible to get zero. Unfortunately the type
// system does not have a way to express this yet.
let code = unsafe { NonZeroU32::new_unchecked(code) };
return Err(Error::from(code));
}
}
Ok(())
Expand Down
49 changes: 0 additions & 49 deletions src/windows_uwp.rs

This file was deleted.