@@ -69,23 +69,35 @@ impl Rng for OsRng {
6969 const MAX_WAIT : u32 = ( 10 * 1000 ) / WAIT_DUR_MS ; // max 10s
7070 const TRANSIENT_STEP : u32 = MAX_WAIT / 8 ;
7171 let mut err_count = 0 ;
72+ let mut log_err = 0 ; // log when err_count >= log_err
7273
7374 loop {
7475 if let Err ( e) = self . try_fill_bytes ( dest) {
75- // TODO: add logging to explain why we wait and the full cause
76+ if log_err == 0 {
77+ warn ! ( "OsRng failed: {:?}" , e) ;
78+ }
79+
7680 if e. kind ( ) . should_retry ( ) {
7781 if err_count > MAX_WAIT {
7882 panic ! ( "Too many RNG errors or timeout; last error: {}" , e. msg( ) ) ;
7983 }
8084
8185 if e. kind ( ) . should_wait ( ) {
86+ err_count += 1 ;
87+ if err_count >= log_err {
88+ log_err += TRANSIENT_STEP ;
89+ warn ! ( "OsRng: waiting and retrying ..." ) ;
90+ }
8291 #[ cfg( feature="std" ) ] {
8392 let dur = :: std:: time:: Duration :: from_millis ( WAIT_DUR_MS as u64 ) ;
8493 :: std:: thread:: sleep ( dur) ;
8594 }
86- err_count += 1 ;
8795 } else {
8896 err_count += TRANSIENT_STEP ;
97+ if err_count >= log_err {
98+ log_err += TRANSIENT_STEP ;
99+ warn ! ( "OsRng: retrying ..." ) ;
100+ }
89101 }
90102
91103 continue ;
@@ -130,6 +142,7 @@ impl ReadRng {
130142 let mutex = unsafe { READ_RNG_FILE . as_ref ( ) . unwrap ( ) } ;
131143 let mut guard = mutex. lock ( ) . unwrap ( ) ;
132144 if ( * guard) . is_none ( ) {
145+ info ! ( "OsRng: opening random device {}" , path. as_ref( ) . display( ) ) ;
133146 let file = File :: open ( path) . map_err ( |err| Error :: with_cause (
134147 ErrorKind :: Unavailable ,
135148 "error opening random device" ,
@@ -142,6 +155,7 @@ impl ReadRng {
142155 }
143156
144157 fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
158+ trace ! ( "OsRng: reading {} bytes from random device" , dest. len( ) ) ;
145159 if dest. len ( ) == 0 { return Ok ( ( ) ) ; }
146160
147161 // Since we have an instance of Self, we can assume that our memory was
@@ -211,6 +225,7 @@ mod imp {
211225 fn getrandom ( _buf : & mut [ u8 ] ) -> libc:: c_long { -1 }
212226
213227 fn getrandom_try_fill ( v : & mut [ u8 ] ) -> Result < ( ) , Error > {
228+ trace ! ( "OsRng: reading {} bytes via getrandom" , v. len( ) ) ;
214229 let mut read = 0 ;
215230 let len = v. len ( ) ;
216231 while read < len {
@@ -253,6 +268,7 @@ mod imp {
253268 static AVAILABLE : AtomicBool = ATOMIC_BOOL_INIT ;
254269
255270 CHECKER . call_once ( || {
271+ debug ! ( "OsRng: testing getrandom" ) ;
256272 let mut buf: [ u8 ; 0 ] = [ ] ;
257273 let result = getrandom ( & mut buf) ;
258274 let available = if result == -1 {
@@ -262,6 +278,7 @@ mod imp {
262278 true
263279 } ;
264280 AVAILABLE . store ( available, Ordering :: Relaxed ) ;
281+ info ! ( "OsRng: using {}" , if available { "getrandom" } else { "/dev/urandom" } ) ;
265282 } ) ;
266283
267284 AVAILABLE . load ( Ordering :: Relaxed )
@@ -320,6 +337,7 @@ mod imp {
320337 }
321338
322339 pub fn try_fill_bytes ( & mut self , v : & mut [ u8 ] ) -> Result < ( ) , Error > {
340+ trace ! ( "OsRng: reading {} bytes via cloadabi::random_get" , v. len( ) ) ;
323341 if unsafe { cloudabi:: random_get ( v) } == cloudabi:: errno:: SUCCESS {
324342 Ok ( ( ) )
325343 } else {
@@ -360,6 +378,7 @@ mod imp {
360378 Ok ( OsRng )
361379 }
362380 pub fn try_fill_bytes ( & mut self , v : & mut [ u8 ] ) -> Result < ( ) , Error > {
381+ trace ! ( "OsRng: reading {} bytes via SecRandomCopyBytes" , v. len( ) ) ;
363382 let ret = unsafe {
364383 SecRandomCopyBytes ( kSecRandomDefault, v. len ( ) as size_t , v. as_mut_ptr ( ) )
365384 } ;
@@ -395,6 +414,7 @@ mod imp {
395414 // kern.arandom permits a maximum buffer size of 256 bytes
396415 for s in v. chunks_mut ( 256 ) {
397416 let mut s_len = s. len ( ) ;
417+ trace ! ( "OsRng: reading {} bytes via kern.arandom" , v. len( ) ) ;
398418 let ret = unsafe {
399419 libc:: sysctl ( mib. as_ptr ( ) , mib. len ( ) as libc:: c_uint ,
400420 s. as_mut_ptr ( ) as * mut _ , & mut s_len,
@@ -429,6 +449,7 @@ mod imp {
429449 pub fn try_fill_bytes ( & mut self , v : & mut [ u8 ] ) -> Result < ( ) , Error > {
430450 // getentropy(2) permits a maximum buffer size of 256 bytes
431451 for s in v. chunks_mut ( 256 ) {
452+ trace ! ( "OsRng: reading {} bytes via getentropy" , s. len( ) ) ;
432453 let ret = unsafe {
433454 libc:: getentropy ( s. as_mut_ptr ( ) as * mut libc:: c_void , s. len ( ) )
434455 } ;
@@ -482,6 +503,7 @@ mod imp {
482503 }
483504 pub fn try_fill_bytes ( & mut self , v : & mut [ u8 ] ) -> Result < ( ) , Error > {
484505 for s in v. chunks_mut ( fuchsia_zircon:: sys:: ZX_CPRNG_DRAW_MAX_LEN ) {
506+ trace ! ( "OsRng: reading {} bytes via cprng_draw" , s. len( ) ) ;
485507 let mut filled = 0 ;
486508 while filled < s. len ( ) {
487509 match fuchsia_zircon:: cprng_draw ( & mut s[ filled..] ) {
@@ -523,6 +545,7 @@ mod imp {
523545 // RtlGenRandom takes an ULONG (u32) for the length so we need to
524546 // split up the buffer.
525547 for slice in v. chunks_mut ( <ULONG >:: max_value ( ) as usize ) {
548+ trace ! ( "OsRng: reading {} bytes via RtlGenRandom" , slice. len( ) ) ;
526549 let ret = unsafe {
527550 RtlGenRandom ( slice. as_mut_ptr ( ) as PVOID , slice. len ( ) as ULONG )
528551 } ;
0 commit comments