13
13
14
14
pub use self :: imp:: OsRng ;
15
15
16
- #[ cfg( all( unix, not( target_os = "ios" ) ) ) ]
16
+ #[ cfg( all( unix, not( target_os = "ios" ) , not ( target_os = "openbsd" ) ) ) ]
17
17
mod imp {
18
18
use self :: OsRngInner :: * ;
19
19
@@ -131,6 +131,7 @@ mod imp {
131
131
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
132
132
/// service provider with the `PROV_RSA_FULL` type.
133
133
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
134
+ /// - OpenBSD: uses the `getentropy(2)` system call.
134
135
///
135
136
/// This does not block.
136
137
pub struct OsRng {
@@ -178,6 +179,63 @@ mod imp {
178
179
}
179
180
}
180
181
182
+ #[ cfg( target_os = "openbsd" ) ]
183
+ mod imp {
184
+ use io;
185
+ use mem;
186
+ use libc:: c_long;
187
+ use sys:: os:: errno;
188
+ use rand:: Rng ;
189
+
190
+ /// A random number generator that retrieves randomness straight from
191
+ /// the operating system. Platform sources:
192
+ ///
193
+ /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
194
+ /// `/dev/urandom`, or from `getrandom(2)` system call if available.
195
+ /// - Windows: calls `CryptGenRandom`, using the default cryptographic
196
+ /// service provider with the `PROV_RSA_FULL` type.
197
+ /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
198
+ /// - OpenBSD: uses the `getentropy(2)` system call.
199
+ ///
200
+ /// This does not block.
201
+ pub struct OsRng {
202
+ // dummy field to ensure that this struct cannot be constructed outside
203
+ // of this module
204
+ _dummy : ( ) ,
205
+ }
206
+
207
+ impl OsRng {
208
+ /// Create a new `OsRng`.
209
+ pub fn new ( ) -> io:: Result < OsRng > {
210
+ Ok ( OsRng { _dummy : ( ) } )
211
+ }
212
+ }
213
+
214
+ impl Rng for OsRng {
215
+ fn next_u32 ( & mut self ) -> u32 {
216
+ let mut v = [ 0 ; 4 ] ;
217
+ self . fill_bytes ( & mut v) ;
218
+ unsafe { mem:: transmute ( v) }
219
+ }
220
+ fn next_u64 ( & mut self ) -> u64 {
221
+ let mut v = [ 0 ; 8 ] ;
222
+ self . fill_bytes ( & mut v) ;
223
+ unsafe { mem:: transmute ( v) }
224
+ }
225
+ fn fill_bytes ( & mut self , v : & mut [ u8 ] ) {
226
+ // getentropy(2) permits a maximum buffer size of 256 bytes
227
+ for s in v. chunks_mut ( 256 ) {
228
+ let ret = unsafe {
229
+ libc:: syscall ( libc:: NR_GETENTROPY , s. as_mut_ptr ( ) , s. len ( ) )
230
+ } ;
231
+ if ret == -1 {
232
+ panic ! ( "unexpected getentropy error: {}" , errno( ) ) ;
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }
238
+
181
239
#[ cfg( target_os = "ios" ) ]
182
240
mod imp {
183
241
#[ cfg( stage0) ] use prelude:: v1:: * ;
@@ -196,6 +254,7 @@ mod imp {
196
254
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
197
255
/// service provider with the `PROV_RSA_FULL` type.
198
256
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
257
+ /// - OpenBSD: uses the `getentropy(2)` system call.
199
258
///
200
259
/// This does not block.
201
260
pub struct OsRng {
@@ -261,6 +320,7 @@ mod imp {
261
320
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
262
321
/// service provider with the `PROV_RSA_FULL` type.
263
322
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
323
+ /// - OpenBSD: uses the `getentropy(2)` system call.
264
324
///
265
325
/// This does not block.
266
326
pub struct OsRng {
0 commit comments