Source file src/crypto/rand/rand.go
1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package rand implements a cryptographically secure 6 // random number generator. 7 package rand 8 9 import ( 10 "crypto/internal/boring" 11 "io" 12 "os" 13 "sync" 14 "sync/atomic" 15 "time" 16 _ "unsafe" 17 ) 18 19 // Reader is a global, shared instance of a cryptographically 20 // secure random number generator. It is safe for concurrent use. 21 // 22 // - On Linux, FreeBSD, Dragonfly, and Solaris, Reader uses getrandom(2). 23 // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. 24 // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). 25 // - On NetBSD, Reader uses the kern.arandom sysctl. 26 // - On Windows, Reader uses the ProcessPrng API. 27 // - On js/wasm, Reader uses the Web Crypto API. 28 // - On wasip1/wasm, Reader uses random_get. 29 var Reader io.Reader 30 31 func init() { 32 if boring.Enabled { 33 Reader = boring.RandReader 34 return 35 } 36 Reader = &reader{} 37 } 38 39 var firstUse atomic.Bool 40 41 func warnBlocked() { 42 println("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel") 43 } 44 45 type reader struct{} 46 47 // Read always returns len(b) or an error. 48 func (r *reader) Read(b []byte) (n int, err error) { 49 boring.Unreachable() 50 if firstUse.CompareAndSwap(false, true) { 51 // First use of randomness. Start timer to warn about 52 // being blocked on entropy not being available. 53 t := time.AfterFunc(time.Minute, warnBlocked) 54 defer t.Stop() 55 } 56 if err := read(b); err != nil { 57 return 0, err 58 } 59 return len(b), nil 60 } 61 62 // fatal is [runtime.fatal], pushed via linkname. 63 // 64 //go:linkname fatal 65 func fatal(string) 66 67 // Read fills b with cryptographically secure random bytes. It never returns an 68 // error, and always fills b entirely. 69 // 70 // Read calls [io.ReadFull] on [Reader] and crashes the program irrecoverably if 71 // an error is returned. The default Reader uses operating system APIs that are 72 // documented to never return an error on all but legacy Linux systems. 73 func Read(b []byte) (n int, err error) { 74 // We don't want b to escape to the heap, but escape analysis can't see 75 // through a potentially overridden Reader, so we special-case the default 76 // case which we can keep non-escaping, and in the general case we read into 77 // a heap buffer and copy from it. 78 if r, ok := Reader.(*reader); ok { 79 _, err = r.Read(b) 80 } else { 81 bb := make([]byte, len(b)) 82 _, err = io.ReadFull(Reader, bb) 83 copy(b, bb) 84 } 85 if err != nil { 86 fatal("crypto/rand: failed to read random data (see https://go.dev/issue/66821): " + err.Error()) 87 panic("unreachable") // To be sure. 88 } 89 return len(b), nil 90 } 91 92 // The urandom fallback is only used on Linux kernels before 3.17 and on AIX. 93 94 var urandomOnce sync.Once 95 var urandomFile *os.File 96 var urandomErr error 97 98 func urandomRead(b []byte) error { 99 urandomOnce.Do(func() { 100 urandomFile, urandomErr = os.Open("/dev/urandom") 101 }) 102 if urandomErr != nil { 103 return urandomErr 104 } 105 for len(b) > 0 { 106 n, err := urandomFile.Read(b) 107 // Note that we don't ignore EAGAIN because it should not be possible to 108 // hit for a blocking read from urandom, although there were 109 // unreproducible reports of it at https://go.dev/issue/9205. 110 if err != nil { 111 return err 112 } 113 b = b[n:] 114 } 115 return nil 116 } 117