diff options
author | Isis Lovecruft <isis@torproject.org> | 2018-04-10 19:05:42 +0000 |
---|---|---|
committer | Isis Lovecruft <isis@torproject.org> | 2018-04-20 23:54:47 +0000 |
commit | 49639b282602c5389e30f906f535c29ddaa62308 (patch) | |
tree | 14d014f1f4992778000dbdf57271fef849cac50e /src/rust/external | |
parent | f17ace1460f0de50f32d28e8086fe11032d8cb3f (diff) | |
download | tor-49639b282602c5389e30f906f535c29ddaa62308.tar.gz tor-49639b282602c5389e30f906f535c29ddaa62308.zip |
rust: Expose our (P)RNGs in Rust and provide safe wrappers.
* FIXES #24660: https://bugs.torproject.org/24660
Diffstat (limited to 'src/rust/external')
-rw-r--r-- | src/rust/external/crypto_rand.rs | 95 | ||||
-rw-r--r-- | src/rust/external/lib.rs | 4 |
2 files changed, 98 insertions, 1 deletions
diff --git a/src/rust/external/crypto_rand.rs b/src/rust/external/crypto_rand.rs new file mode 100644 index 0000000000..19b9ab2816 --- /dev/null +++ b/src/rust/external/crypto_rand.rs @@ -0,0 +1,95 @@ +// Copyright (c) 2018, The Tor Project, Inc. +// Copyright (c) 2018, isis agora lovecruft +// See LICENSE for licensing information + +//! Bindings to external (P)RNG interfaces and utilities in +//! src/common/crypto_rand.[ch]. +//! +//! We wrap our C implementations in src/common/crypto_rand.[ch] here in order +//! to provide wrappers with native Rust types, and then provide more Rusty +//! types and and trait implementations in src/rust/crypto/rand/. + +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_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 +/// system. +/// +/// # Returns +/// +/// `true` on success; `false` on failure. +pub fn c_tor_crypto_seed_rng() -> bool { + let ret: c_int; + + unsafe { + ret = crypto_seed_rng(); + } + match ret { + 0 => return true, + _ => return false, + } +} + +/// Fill the bytes of `dest` with strong random data. +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 + // paranoid caller should assert on the length of dest *before* calling this + // function. + unsafe { + crypto_strongest_rand(dest.as_mut_ptr(), dest.len() as size_t); + } +} + +/// Get a random time, in seconds since the Unix Epoch. +/// +/// # Returns +/// +/// A `std::time::Duration` of seconds since the Unix Epoch. +pub fn c_tor_crypto_rand_time_range(min: &Duration, max: &Duration) -> Duration { + let ret: time_t; + + unsafe { + ret = crypto_rand_time_range(min.as_secs() as time_t, max.as_secs() as time_t); + } + + Duration::from_secs(ret as u64) +} + +/// Return a pseudorandom 64-bit float, chosen uniformly from the range [0.0, 1.0). +pub fn c_tor_crypto_rand_double() -> f64 { + unsafe { + crypto_rand_double() + } +} + +#[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/external/lib.rs b/src/rust/external/lib.rs index 0af0d6452d..5fd74cf4c2 100644 --- a/src/rust/external/lib.rs +++ b/src/rust/external/lib.rs @@ -1,4 +1,4 @@ -//! Copyright (c) 2016-2017, The Tor Project, Inc. */ +//! Copyright (c) 2016-2018, The Tor Project, Inc. */ //! See LICENSE for licensing information */ //! Interface for external calls to tor C ABI @@ -9,6 +9,8 @@ extern crate libc; +mod crypto_rand; mod external; +pub use crypto_rand::*; pub use external::*; |