File tree 3 files changed +21
-0
lines changed
3 files changed +21
-0
lines changed Original file line number Diff line number Diff line change @@ -23,3 +23,7 @@ var Reader io.Reader
23
23
func Read (b []byte ) (n int , err error ) {
24
24
return io .ReadFull (Reader , b )
25
25
}
26
+
27
+ func warnBlocked () {
28
+ println ("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel" )
29
+ }
Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ import (
18
18
"os"
19
19
"runtime"
20
20
"sync"
21
+ "sync/atomic"
21
22
"time"
22
23
)
23
24
@@ -39,13 +40,20 @@ type devReader struct {
39
40
name string
40
41
f io.Reader
41
42
mu sync.Mutex
43
+ used int32 // atomic; whether this devReader has been used
42
44
}
43
45
44
46
// altGetRandom if non-nil specifies an OS-specific function to get
45
47
// urandom-style randomness.
46
48
var altGetRandom func ([]byte ) (ok bool )
47
49
48
50
func (r * devReader ) Read (b []byte ) (n int , err error ) {
51
+ if atomic .CompareAndSwapInt32 (& r .used , 0 , 1 ) {
52
+ // First use of randomness. Start timer to warn about
53
+ // being blocked on entropy not being available.
54
+ t := time .AfterFunc (60 * time .Second , warnBlocked )
55
+ defer t .Stop ()
56
+ }
49
57
if altGetRandom != nil && r .name == urandomDevice && altGetRandom (b ) {
50
58
return len (b ), nil
51
59
}
Original file line number Diff line number Diff line change @@ -10,7 +10,9 @@ package rand
10
10
import (
11
11
"os"
12
12
"sync"
13
+ "sync/atomic"
13
14
"syscall"
15
+ "time"
14
16
)
15
17
16
18
// Implemented by using Windows CryptoAPI 2.0.
@@ -19,11 +21,18 @@ func init() { Reader = &rngReader{} }
19
21
20
22
// A rngReader satisfies reads by reading from the Windows CryptGenRandom API.
21
23
type rngReader struct {
24
+ used int32 // atomic; whether this rngReader has been used
22
25
prov syscall.Handle
23
26
mu sync.Mutex
24
27
}
25
28
26
29
func (r * rngReader ) Read (b []byte ) (n int , err error ) {
30
+ if atomic .CompareAndSwapInt32 (& r .used , 0 , 1 ) {
31
+ // First use of randomness. Start timer to warn about
32
+ // being blocked on entropy not being available.
33
+ t := time .AfterFunc (60 * time .Second , warnBlocked )
34
+ defer t .Stop ()
35
+ }
27
36
r .mu .Lock ()
28
37
if r .prov == 0 {
29
38
const provType = syscall .PROV_RSA_FULL
You can’t perform that action at this time.
0 commit comments