mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Use the getentropy(2) syscall on OpenBSD
Rust already supports Linux's getrandom(2), which is very similar and was based on getentropy(2). This is a pretty clean, simple addition that uses the same approach as the iOS randomness API support.
This commit is contained in:
parent
5dd29cc310
commit
f4d409d6ed
@ -47,6 +47,7 @@
|
||||
//! if the entropy pool is very small, such as immediately after first booting.
|
||||
//! Linux 3.17 added the `getrandom(2)` system call which solves the issue: it blocks if entropy
|
||||
//! pool is not initialized yet, but it does not block once initialized.
|
||||
//! `getrandom(2)` was based on `getentropy(2)`, an existing system call in OpenBSD.
|
||||
//! `OsRng` tries to use `getrandom(2)` if available, and use `/dev/urandom` fallback if not.
|
||||
//! If an application does not have `getrandom` and likely to be run soon after first booting,
|
||||
//! or on a system with very few entropy sources, one should consider using `/dev/random` via
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
pub use self::imp::OsRng;
|
||||
|
||||
#[cfg(all(unix, not(target_os = "ios")))]
|
||||
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "openbsd")))]
|
||||
mod imp {
|
||||
use self::OsRngInner::*;
|
||||
|
||||
@ -131,6 +131,7 @@ mod imp {
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
|
||||
/// - OpenBSD: uses the `getentropy(2)` system call.
|
||||
///
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
@ -178,6 +179,67 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
mod imp {
|
||||
use io;
|
||||
use mem;
|
||||
use libc::c_long;
|
||||
use sys::os::errno;
|
||||
use rand::Rng;
|
||||
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
/// the operating system. Platform sources:
|
||||
///
|
||||
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
|
||||
/// `/dev/urandom`, or from `getrandom(2)` system call if available.
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
|
||||
/// - OpenBSD: uses the `getentropy(2)` system call.
|
||||
///
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
// dummy field to ensure that this struct cannot be constructed outside
|
||||
// of this module
|
||||
_dummy: (),
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn syscall(number: c_long, ...) -> c_long;
|
||||
}
|
||||
|
||||
impl OsRng {
|
||||
/// Create a new `OsRng`.
|
||||
pub fn new() -> io::Result<OsRng> {
|
||||
Ok(OsRng { _dummy: () })
|
||||
}
|
||||
}
|
||||
|
||||
impl Rng for OsRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let mut v = [0; 4];
|
||||
self.fill_bytes(&mut v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
let mut v = [0; 8];
|
||||
self.fill_bytes(&mut v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
let mut ret: c_long;
|
||||
|
||||
// getentropy(2) permits a maximum buffer size of 256 bytes
|
||||
for s in v.chunks_mut(256) {
|
||||
unsafe { ret = syscall(7, s.as_mut_ptr(), s.len()); }
|
||||
if ret == -1 {
|
||||
panic!("unexpected getrandom error: {}", errno());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
mod imp {
|
||||
#[cfg(stage0)] use prelude::v1::*;
|
||||
@ -196,6 +258,7 @@ mod imp {
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
|
||||
/// - OpenBSD: uses the `getentropy(2)` system call.
|
||||
///
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
@ -261,6 +324,7 @@ mod imp {
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
|
||||
/// - OpenBSD: uses the `getentropy(2)` system call.
|
||||
///
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
|
Loading…
Reference in New Issue
Block a user