8
8
9
9
//! Entropy generator, or wrapper around external generators
10
10
11
- use rand_core:: { RngCore , CryptoRng , Error , ErrorKind , impls} ;
11
+ #![ allow( deprecated) ] // whole module is deprecated
12
+
13
+ use rand_core:: { RngCore , CryptoRng , Error } ;
12
14
#[ allow( unused) ]
13
- use rngs;
15
+ use rngs:: OsRng ;
14
16
15
17
/// An interface returning random data from external source(s), provided
16
18
/// specifically for securely seeding algorithmic generators (PRNGs).
17
19
///
18
- /// Where possible, `EntropyRng` retrieves random data from the operating
19
- /// system's interface for random numbers ([`OsRng`]); if that fails it will
20
- /// fall back to the [`JitterRng`] entropy collector. In the latter case it will
21
- /// still try to use [`OsRng`] on the next usage.
22
- ///
23
- /// If no secure source of entropy is available `EntropyRng` will panic on use;
24
- /// i.e. it should never output predictable data.
25
- ///
26
- /// This is either a little slow ([`OsRng`] requires a system call) or extremely
27
- /// slow ([`JitterRng`] must use significant CPU time to generate sufficient
28
- /// jitter); for better performance it is common to seed a local PRNG from
29
- /// external entropy then primarily use the local PRNG ([`thread_rng`] is
30
- /// provided as a convenient, local, automatically-seeded CSPRNG).
31
- ///
32
- /// # Panics
33
- ///
34
- /// On most systems, like Windows, Linux, macOS and *BSD on common hardware, it
35
- /// is highly unlikely for both [`OsRng`] and [`JitterRng`] to fail. But on
36
- /// combinations like webassembly without Emscripten or stdweb both sources are
37
- /// unavailable. If both sources fail, only [`try_fill_bytes`] is able to
38
- /// report the error, and only the one from `OsRng`. The other [`RngCore`]
39
- /// methods will panic in case of an error.
40
- ///
41
- /// [`OsRng`]: rngs::OsRng
42
- /// [`thread_rng`]: crate::thread_rng
43
- /// [`JitterRng`]: crate::rngs::JitterRng
44
- /// [`try_fill_bytes`]: RngCore::try_fill_bytes
20
+ /// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
45
21
#[ derive( Debug ) ]
22
+ #[ deprecated( since="0.7.0" , note="use rngs::OsRng instead" ) ]
46
23
pub struct EntropyRng {
47
- source : Source ,
48
- }
49
-
50
- #[ derive( Debug ) ]
51
- enum Source {
52
- Os ( Os ) ,
53
- Custom ( Custom ) ,
54
- Jitter ( Jitter ) ,
55
- None ,
24
+ source : OsRng ,
56
25
}
57
26
58
27
impl EntropyRng {
@@ -62,7 +31,7 @@ impl EntropyRng {
62
31
/// those are done on first use. This is done to make `new` infallible,
63
32
/// and `try_fill_bytes` the only place to report errors.
64
33
pub fn new ( ) -> Self {
65
- EntropyRng { source : Source :: None }
34
+ EntropyRng { source : OsRng }
66
35
}
67
36
}
68
37
@@ -74,167 +43,25 @@ impl Default for EntropyRng {
74
43
75
44
impl RngCore for EntropyRng {
76
45
fn next_u32 ( & mut self ) -> u32 {
77
- impls :: next_u32_via_fill ( self )
46
+ self . source . next_u32 ( )
78
47
}
79
48
80
49
fn next_u64 ( & mut self ) -> u64 {
81
- impls :: next_u64_via_fill ( self )
50
+ self . source . next_u64 ( )
82
51
}
83
52
84
53
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
85
- self . try_fill_bytes ( dest) . unwrap_or_else ( |err|
86
- panic ! ( "all entropy sources failed; first error: {}" , err) )
54
+ self . source . fill_bytes ( dest)
87
55
}
88
56
89
57
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
90
- let mut reported_error = None ;
91
-
92
- if let Source :: Os ( ref mut os_rng) = self . source {
93
- match os_rng. fill ( dest) {
94
- Ok ( ( ) ) => return Ok ( ( ) ) ,
95
- Err ( err) => {
96
- warn ! ( "EntropyRng: OsRng failed \
97
- [trying other entropy sources]: {}", err) ;
98
- reported_error = Some ( err) ;
99
- } ,
100
- }
101
- } else if Os :: is_supported ( ) {
102
- match Os :: new_and_fill ( dest) {
103
- Ok ( os_rng) => {
104
- debug ! ( "EntropyRng: using OsRng" ) ;
105
- self . source = Source :: Os ( os_rng) ;
106
- return Ok ( ( ) ) ;
107
- } ,
108
- Err ( err) => { reported_error = reported_error. or ( Some ( err) ) } ,
109
- }
110
- }
111
-
112
- if let Source :: Custom ( ref mut rng) = self . source {
113
- match rng. fill ( dest) {
114
- Ok ( ( ) ) => return Ok ( ( ) ) ,
115
- Err ( err) => {
116
- warn ! ( "EntropyRng: custom entropy source failed \
117
- [trying other entropy sources]: {}", err) ;
118
- reported_error = Some ( err) ;
119
- } ,
120
- }
121
- } else if Custom :: is_supported ( ) {
122
- match Custom :: new_and_fill ( dest) {
123
- Ok ( custom) => {
124
- debug ! ( "EntropyRng: using custom entropy source" ) ;
125
- self . source = Source :: Custom ( custom) ;
126
- return Ok ( ( ) ) ;
127
- } ,
128
- Err ( err) => { reported_error = reported_error. or ( Some ( err) ) } ,
129
- }
130
- }
131
-
132
- if let Source :: Jitter ( ref mut jitter_rng) = self . source {
133
- match jitter_rng. fill ( dest) {
134
- Ok ( ( ) ) => return Ok ( ( ) ) ,
135
- Err ( err) => {
136
- warn ! ( "EntropyRng: JitterRng failed: {}" , err) ;
137
- reported_error = Some ( err) ;
138
- } ,
139
- }
140
- } else if Jitter :: is_supported ( ) {
141
- match Jitter :: new_and_fill ( dest) {
142
- Ok ( jitter_rng) => {
143
- debug ! ( "EntropyRng: using JitterRng" ) ;
144
- self . source = Source :: Jitter ( jitter_rng) ;
145
- return Ok ( ( ) ) ;
146
- } ,
147
- Err ( err) => { reported_error = reported_error. or ( Some ( err) ) } ,
148
- }
149
- }
150
-
151
- if let Some ( err) = reported_error {
152
- Err ( Error :: with_cause ( ErrorKind :: Unavailable ,
153
- "All entropy sources failed" ,
154
- err) )
155
- } else {
156
- Err ( Error :: new ( ErrorKind :: Unavailable ,
157
- "No entropy sources available" ) )
158
- }
58
+ self . source . try_fill_bytes ( dest)
159
59
}
160
60
}
161
61
162
62
impl CryptoRng for EntropyRng { }
163
63
164
64
165
-
166
- trait EntropySource {
167
- fn new_and_fill ( dest : & mut [ u8 ] ) -> Result < Self , Error >
168
- where Self : Sized ;
169
-
170
- fn fill ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > ;
171
-
172
- fn is_supported ( ) -> bool { true }
173
- }
174
-
175
- #[ allow( unused) ]
176
- #[ derive( Clone , Debug ) ]
177
- struct NoSource ;
178
-
179
- #[ allow( unused) ]
180
- impl EntropySource for NoSource {
181
- fn new_and_fill ( dest : & mut [ u8 ] ) -> Result < Self , Error > {
182
- Err ( Error :: new ( ErrorKind :: Unavailable , "Source not supported" ) )
183
- }
184
-
185
- fn fill ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
186
- unreachable ! ( )
187
- }
188
-
189
- fn is_supported ( ) -> bool { false }
190
- }
191
-
192
-
193
- #[ cfg( feature="getrandom" ) ]
194
- #[ derive( Clone , Debug ) ]
195
- pub struct Os ( rngs:: OsRng ) ;
196
-
197
- #[ cfg( feature="getrandom" ) ]
198
- impl EntropySource for Os {
199
- fn new_and_fill ( dest : & mut [ u8 ] ) -> Result < Self , Error > {
200
- let rng = rngs:: OsRng ;
201
- rngs:: OsRng . try_fill_bytes ( dest) ?;
202
- Ok ( Os ( rng) )
203
- }
204
-
205
- fn fill ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
206
- self . 0 . try_fill_bytes ( dest)
207
- }
208
- }
209
-
210
- #[ cfg( not( feature="std" ) ) ]
211
- type Os = NoSource ;
212
-
213
-
214
- type Custom = NoSource ;
215
-
216
-
217
- #[ cfg( not( target_arch = "wasm32" ) ) ]
218
- #[ derive( Clone , Debug ) ]
219
- pub struct Jitter ( rngs:: JitterRng ) ;
220
-
221
- #[ cfg( not( target_arch = "wasm32" ) ) ]
222
- impl EntropySource for Jitter {
223
- fn new_and_fill ( dest : & mut [ u8 ] ) -> Result < Self , Error > {
224
- let mut rng = rngs:: JitterRng :: new ( ) ?;
225
- rng. try_fill_bytes ( dest) ?;
226
- Ok ( Jitter ( rng) )
227
- }
228
-
229
- fn fill ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
230
- self . 0 . try_fill_bytes ( dest)
231
- }
232
- }
233
-
234
- #[ cfg( target_arch = "wasm32" ) ]
235
- type Jitter = NoSource ;
236
-
237
-
238
65
#[ cfg( test) ]
239
66
mod test {
240
67
use super :: * ;
0 commit comments