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 "crypto/internal/fips140/drbg" 12 "crypto/internal/rand" 13 "io" 14 _ "unsafe" 15 16 // Ensure the go:linkname from testing/cryptotest to 17 // crypto/internal/rand.SetTestingReader works. 18 _ "crypto/internal/rand" 19 ) 20 21 // Reader is a global, shared instance of a cryptographically 22 // secure random number generator. It is safe for concurrent use. 23 // 24 // - On Linux, FreeBSD, Dragonfly, and Solaris, Reader uses getrandom(2). 25 // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. 26 // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). 27 // - On NetBSD, Reader uses the kern.arandom sysctl. 28 // - On Windows, Reader uses the ProcessPrng API. 29 // - On js/wasm, Reader uses the Web Crypto API. 30 // - On wasip1/wasm, Reader uses random_get. 31 // 32 // In FIPS 140-3 mode, the output passes through an SP 800-90A Rev. 1 33 // Deterministric Random Bit Generator (DRBG). 34 var Reader io.Reader = rand.Reader 35 36 // fatal is [runtime.fatal], pushed via linkname. 37 // 38 //go:linkname fatal 39 func fatal(string) 40 41 // Read fills b with cryptographically secure random bytes. It never returns an 42 // error, and always fills b entirely. 43 // 44 // Read calls [io.ReadFull] on [Reader] and crashes the program irrecoverably if 45 // an error is returned. The default Reader uses operating system APIs that are 46 // documented to never return an error on all but legacy Linux systems. 47 func Read(b []byte) (n int, err error) { 48 // We don't want b to escape to the heap, but escape analysis can't see 49 // through a potentially overridden Reader, so we special-case the default 50 // case which we can keep non-escaping, and in the general case we read into 51 // a heap buffer and copy from it. 52 if rand.IsDefaultReader(Reader) { 53 if boring.Enabled { 54 _, err = io.ReadFull(boring.RandReader, b) 55 } else { 56 drbg.Read(b) 57 } 58 } else { 59 bb := make([]byte, len(b)) 60 _, err = io.ReadFull(Reader, bb) 61 copy(b, bb) 62 } 63 if err != nil { 64 fatal("crypto/rand: failed to read random data (see https://go.dev/issue/66821): " + err.Error()) 65 panic("unreachable") // To be sure. 66 } 67 return len(b), nil 68 } 69