[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] rust: Expose crypto_rand() as an impl of rand_core::RngCore.
commit 94dcd38a1430061a0bb630ad680a41a78262a55c
Author: Isis Lovecruft <isis@xxxxxxxxxxxxxx>
Date: Wed May 2 22:12:38 2018 +0000
rust: Expose crypto_rand() as an impl of rand_core::RngCore.
---
src/rust/external/crypto_rand.rs | 30 ++++++++--------------
src/rust/rand/rng.rs | 54 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/rust/external/crypto_rand.rs b/src/rust/external/crypto_rand.rs
index 19b9ab281..af1ade016 100644
--- a/src/rust/external/crypto_rand.rs
+++ b/src/rust/external/crypto_rand.rs
@@ -11,23 +11,18 @@
use std::time::Duration;
-use libc::c_char;
use libc::c_double;
use libc::c_int;
-use libc::c_uint;
-use libc::c_void;
use libc::size_t;
use libc::time_t;
use libc::uint8_t;
-use libc::uint64_t;
extern "C" {
fn crypto_seed_rng() -> c_int;
+ fn crypto_rand(out: *mut uint8_t, out_len: size_t);
fn crypto_strongest_rand(out: *mut uint8_t, out_len: size_t);
fn crypto_rand_time_range(min: time_t, max: time_t) -> time_t;
fn crypto_rand_double() -> c_double;
- // fn crypto_random_hostname(min_rand_len: c_int, max_rand_len: c_int,
- // prefix: *const c_char, suffix: *const c_char) -> *mut c_char;
}
/// Seed OpenSSL's random number generator with bytes from the operating
@@ -48,7 +43,16 @@ pub fn c_tor_crypto_seed_rng() -> bool {
}
}
-/// Fill the bytes of `dest` with strong random data.
+/// Fill the bytes of `dest` with random data.
+pub fn c_tor_crypto_rand(dest: &mut [u8]) {
+ unsafe {
+ crypto_rand(dest.as_mut_ptr(), dest.len() as size_t);
+ }
+}
+
+/// Fill the bytes of `dest` with "strong" random data by hashing
+/// together randomness obtained from OpenSSL's RNG and the operating
+/// system.
pub fn c_tor_crypto_strongest_rand(dest: &mut [u8]) {
// We'll let the C side panic if the len is larger than
// MAX_STRONGEST_RAND_SIZE, rather than potentially panicking here. A
@@ -81,15 +85,3 @@ pub fn c_tor_crypto_rand_double() -> f64 {
}
}
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn test_layout_tor_weak_rng_t() {
- assert_eq!(::std::mem::size_of::<tor_weak_rng_t>(), 0usize,
- concat!("Size of: ", stringify!(tor_weak_rng_t)));
- assert_eq!(::std::mem::align_of::<tor_weak_rng_t>(), 1usize,
- concat!("Alignment of ", stringify!(tor_weak_rng_t)));
- }
-}
diff --git a/src/rust/rand/rng.rs b/src/rust/rand/rng.rs
index ea234492e..cfd96c961 100644
--- a/src/rust/rand/rng.rs
+++ b/src/rust/rand/rng.rs
@@ -2,7 +2,7 @@
// Copyright (c) 2018, isis agora lovecruft
// See LICENSE for licensing information
-//! Wrappers for Tor's random number generator to provide implementations of
+//! Wrappers for Tor's random number generators to provide implementations of
//! `rand_core` traits.
// This is the real implementation, in use in production, which calls into our C
@@ -18,6 +18,7 @@ mod internal {
use rand_core::impls::next_u32_via_fill;
use rand_core::impls::next_u64_via_fill;
+ use external::c_tor_crypto_rand;
use external::c_tor_crypto_strongest_rand;
use external::c_tor_crypto_seed_rng;
@@ -66,6 +67,53 @@ mod internal {
// C_RUST_COUPLED: `crypto_strongest_rand()` /src/common/crypto_rand.c
fn fill_bytes(&mut self, dest: &mut [u8]) {
+ c_tor_crypto_rand(dest);
+ }
+
+ // C_RUST_COUPLED: `crypto_strongest_rand()` /src/common/crypto_rand.c
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ Ok(self.fill_bytes(dest))
+ }
+ }
+
+ /// A CSPRNG which hashes together randomness from OpenSSL's RNG and entropy
+ /// obtained from the operating system.
+ pub struct TorStrongestRng {
+ // This private, zero-length field forces the struct to be treated the
+ // same as its opaque C couterpart.
+ _unused: [u8; 0],
+ }
+
+ /// Mark `TorRng` as being suitable for cryptographic purposes.
+ impl CryptoRng for TorStrongestRng {}
+
+ impl TorStrongestRng {
+ // C_RUST_COUPLED: `crypto_seed_rng()` /src/common/crypto_rand.c
+ #[allow(dead_code)]
+ fn new() -> Self {
+ if !c_tor_crypto_seed_rng() {
+ tor_log_msg!(LogSeverity::Warn, LogDomain::General,
+ "TorStrongestRng::from_seed()",
+ "The RNG could not be seeded!");
+ }
+ // XXX also log success at info level â??isis
+ TorStrongestRng{ _unused: [0u8; 0] }
+ }
+ }
+
+ impl RngCore for TorStrongestRng {
+ // C_RUST_COUPLED: `crypto_strongest_rand()` /src/common/crypto_rand.c
+ fn next_u32(&mut self) -> u32 {
+ next_u32_via_fill(self)
+ }
+
+ // C_RUST_COUPLED: `crypto_strongest_rand()` /src/common/crypto_rand.c
+ fn next_u64(&mut self) -> u64 {
+ next_u64_via_fill(self)
+ }
+
+ // C_RUST_COUPLED: `crypto_strongest_rand()` /src/common/crypto_rand.c
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
debug_assert!(dest.len() <= MAX_STRONGEST_RAND_SIZE);
c_tor_crypto_strongest_rand(dest);
@@ -81,7 +129,9 @@ mod internal {
// For testing, we expose a pure-Rust implementation.
#[cfg(test)]
mod internal {
- pub use rand::EntropyRng as TorRng;
+ // It doesn't matter if we pretend ChaCha is a CSPRNG in tests.
+ pub use rand::ChaChaRng as TorRng;
+ pub use rand::ChaChaRng as TorStrongestRng;
}
// Finally, expose the public functionality of whichever appropriate internal
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits