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  

View as plain text