1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use botan_sys::*;
use utils::*;
#[derive(Debug)]
/// A cryptographic random number generator
pub struct RandomNumberGenerator {
obj: botan_rng_t
}
impl Drop for RandomNumberGenerator {
fn drop(&mut self) {
unsafe { botan_rng_destroy(self.obj); }
}
}
impl RandomNumberGenerator {
fn new_of_type(typ: &str) -> Result<RandomNumberGenerator> {
let mut obj = ptr::null_mut();
let typ = make_cstr(typ)?;
call_botan! { botan_rng_init(&mut obj, typ.as_ptr()) }
Ok(RandomNumberGenerator { obj })
}
pub(crate) fn handle(&self) -> botan_rng_t { self.obj }
/// Create a new userspace RNG object
///
/// # Examples
/// ```
/// let userspace_rng = botan::RandomNumberGenerator::new_userspace().unwrap();
/// ```
pub fn new_userspace() -> Result<RandomNumberGenerator> {
RandomNumberGenerator::new_of_type("user")
}
/// Create a new reference to the system PRNG
///
/// # Examples
/// ```
/// let system_rng = botan::RandomNumberGenerator::new_system().unwrap();
/// ```
pub fn new_system() -> Result<RandomNumberGenerator> {
RandomNumberGenerator::new_of_type("system")
}
/// Create a new reference to an RNG of some arbitrary type
///
/// # Examples
/// ```
/// let a_rng = botan::RandomNumberGenerator::new().unwrap();
/// ```
pub fn new() -> Result<RandomNumberGenerator> {
RandomNumberGenerator::new_userspace()
}
/// Read bytes from an RNG
///
/// # Examples
/// ```
/// let rng = botan::RandomNumberGenerator::new().unwrap();
/// let output = rng.read(32).unwrap();
/// assert_eq!(output.len(), 32);
/// ```
pub fn read(&self, len: usize) -> Result<Vec<u8>> {
let mut result = vec![0; len];
self.fill(&mut result)?;
Ok(result)
}
/// Store bytes from the RNG into the passed slice
///
/// # Examples
/// ```
/// let rng = botan::RandomNumberGenerator::new().unwrap();
/// let mut output = vec![0; 32];
/// rng.fill(&mut output).unwrap();
/// ```
pub fn fill(&self, out: &mut [u8]) -> Result<()> {
call_botan! { botan_rng_get(self.obj, out.as_mut_ptr(), out.len()) }
Ok(())
}
/// Attempt to reseed the RNG by unspecified means
///
/// # Examples
/// ```
/// let rng = botan::RandomNumberGenerator::new().unwrap();
/// rng.reseed(256).unwrap();
/// ```
pub fn reseed(&self, bits: usize) -> Result<()> {
call_botan! { botan_rng_reseed(self.obj, bits) }
Ok(())
}
/// Attempt to reseed the RNG by getting data from source RNG
///
/// # Examples
/// ```
/// let system_rng = botan::RandomNumberGenerator::new_system().unwrap();
/// let rng = botan::RandomNumberGenerator::new_userspace().unwrap();
/// rng.reseed_from_rng(&system_rng, 256).unwrap();
/// ```
pub fn reseed_from_rng(&self, source: &RandomNumberGenerator, bits: usize) -> Result<()> {
call_botan! { botan_rng_reseed_from_rng(self.obj, source.handle(), bits) }
Ok(())
}
/// Add some seed material to the RNG
///
/// # Examples
/// ```
/// let rng = botan::RandomNumberGenerator::new_userspace().unwrap();
/// let my_seed = vec![0x42, 0x6F, 0x62];
/// rng.add_entropy(&my_seed);
/// ```
pub fn add_entropy(&self, seed: &[u8]) -> Result<()> {
call_botan! { botan_rng_add_entropy(self.obj, seed.as_ptr(), seed.len()) }
Ok(())
}
}