@@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
27
27
#[ cfg( all( unix,
28
28
not( target_os = "ios" ) ,
29
29
not( target_os = "openbsd" ) ,
30
- not( target_os = "freebsd" ) ) ) ]
30
+ not( target_os = "freebsd" ) ,
31
+ not( target_os = "fuchsia" ) ) ) ]
31
32
mod imp {
32
33
use self :: OsRngInner :: * ;
33
34
use super :: { next_u32, next_u64} ;
@@ -339,3 +340,54 @@ mod imp {
339
340
}
340
341
}
341
342
}
343
+
344
+ #[ cfg( target_os = "fuchsia" ) ]
345
+ mod imp {
346
+ use super :: { next_u32, next_u64} ;
347
+
348
+ use io;
349
+ use rand:: Rng ;
350
+
351
+ #[ link( name = "magenta" ) ]
352
+ extern {
353
+ fn mx_cprng_draw ( buffer : * mut u8 , len : usize ) -> isize ;
354
+ }
355
+
356
+ fn getrandom ( buf : & mut [ u8 ] ) -> isize {
357
+ unsafe { mx_cprng_draw ( buf. as_mut_ptr ( ) , buf. len ( ) ) }
358
+ }
359
+
360
+ pub struct OsRng {
361
+ // dummy field to ensure that this struct cannot be constructed outside
362
+ // of this module
363
+ _dummy : ( ) ,
364
+ }
365
+
366
+ impl OsRng {
367
+ /// Create a new `OsRng`.
368
+ pub fn new ( ) -> io:: Result < OsRng > {
369
+ Ok ( OsRng { _dummy : ( ) } )
370
+ }
371
+ }
372
+
373
+ impl Rng for OsRng {
374
+ fn next_u32 ( & mut self ) -> u32 {
375
+ next_u32 ( & mut |v| self . fill_bytes ( v) )
376
+ }
377
+ fn next_u64 ( & mut self ) -> u64 {
378
+ next_u64 ( & mut |v| self . fill_bytes ( v) )
379
+ }
380
+ fn fill_bytes ( & mut self , v : & mut [ u8 ] ) {
381
+ let mut buf = v;
382
+ while !buf. is_empty ( ) {
383
+ let ret = getrandom ( buf) ;
384
+ if ret < 0 {
385
+ panic ! ( "kernel mx_cprng_draw call failed! (returned {}, buf.len() {})" ,
386
+ ret, buf. len( ) ) ;
387
+ }
388
+ let move_buf = buf;
389
+ buf = & mut move_buf[ ( ret as usize ) ..] ;
390
+ }
391
+ }
392
+ }
393
+ }
0 commit comments