@@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
2727#[ cfg( all( unix,
2828 not( target_os = "ios" ) ,
2929 not( target_os = "openbsd" ) ,
30- not( target_os = "freebsd" ) ) ) ]
30+ not( target_os = "freebsd" ) ,
31+ not( target_os = "fuchsia" ) ) ) ]
3132mod imp {
3233 use self :: OsRngInner :: * ;
3334 use super :: { next_u32, next_u64} ;
@@ -339,3 +340,54 @@ mod imp {
339340 }
340341 }
341342}
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