[dev.boringcrypto] all: merge master into dev.boringcrypto

Change-Id: I30dbbe508a6252d50b4154cb9a8299cf0a054449
This commit is contained in:
Chressie Himpel 2022-04-21 17:30:08 +02:00
commit 19e4b10f2f
2 changed files with 19 additions and 45 deletions

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris //go:build unix
package rand package rand

View File

@ -10,11 +10,11 @@
package rand package rand
import ( import (
"bufio"
"errors" "errors"
"io" "io"
"os" "os"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
) )
@ -35,7 +35,7 @@ func init() {
type reader struct { type reader struct {
f io.Reader f io.Reader
mu sync.Mutex mu sync.Mutex
used bool // whether this reader has been used used uint32 // Atomic: 0 - never used, 1 - used, but f == nil, 2 - used, and f != nil
} }
// altGetRandom if non-nil specifies an OS-specific function to get // altGetRandom if non-nil specifies an OS-specific function to get
@ -43,24 +43,11 @@ type reader struct {
var altGetRandom func([]byte) (ok bool) var altGetRandom func([]byte) (ok bool)
// batched returns a function that calls f to populate a []byte by chunking it // batched returns a function that calls f to populate a []byte by chunking it
// into subslices of, at most, readMax bytes, buffering min(readMax, 4096) // into subslices of, at most, readMax bytes.
// bytes at a time.
func batched(f func([]byte) error, readMax int) func([]byte) bool { func batched(f func([]byte) error, readMax int) func([]byte) bool {
bufferSize := 4096
if bufferSize > readMax {
bufferSize = readMax
}
fullBuffer := make([]byte, bufferSize)
var buf []byte
return func(out []byte) bool { return func(out []byte) bool {
// First we copy any amount remaining in the buffer. for len(out) > 0 {
n := copy(out, buf) read := len(out)
out, buf = out[n:], buf[n:]
// Then, if we're requesting more than the buffer size,
// generate directly into the output, chunked by readMax.
for len(out) >= len(fullBuffer) {
read := len(out) - (len(out) % len(fullBuffer))
if read > readMax { if read > readMax {
read = readMax read = readMax
} }
@ -69,22 +56,6 @@ func batched(f func([]byte) error, readMax int) func([]byte) bool {
} }
out = out[read:] out = out[read:]
} }
// If there's a partial block left over, fill the buffer,
// and copy in the remainder.
if len(out) > 0 {
if f(fullBuffer[:]) != nil {
return false
}
buf = fullBuffer[:]
n = copy(out, buf)
out, buf = out[n:], buf[n:]
}
if len(out) > 0 {
panic("crypto/rand batching failed to fill buffer")
}
return true return true
} }
} }
@ -95,10 +66,7 @@ func warnBlocked() {
func (r *reader) Read(b []byte) (n int, err error) { func (r *reader) Read(b []byte) (n int, err error) {
boring.Unreachable() boring.Unreachable()
r.mu.Lock() if atomic.CompareAndSwapUint32(&r.used, 0, 1) {
defer r.mu.Unlock()
if !r.used {
r.used = true
// First use of randomness. Start timer to warn about // First use of randomness. Start timer to warn about
// being blocked on entropy not being available. // being blocked on entropy not being available.
t := time.AfterFunc(time.Minute, warnBlocked) t := time.AfterFunc(time.Minute, warnBlocked)
@ -107,14 +75,20 @@ func (r *reader) Read(b []byte) (n int, err error) {
if altGetRandom != nil && altGetRandom(b) { if altGetRandom != nil && altGetRandom(b) {
return len(b), nil return len(b), nil
} }
if r.f == nil { if atomic.LoadUint32(&r.used) != 2 {
f, err := os.Open(urandomDevice) r.mu.Lock()
if err != nil { if r.used != 2 {
return 0, err f, err := os.Open(urandomDevice)
if err != nil {
r.mu.Unlock()
return 0, err
}
r.f = hideAgainReader{f}
atomic.StoreUint32(&r.used, 2)
} }
r.f = bufio.NewReader(hideAgainReader{f}) r.mu.Unlock()
} }
return r.f.Read(b) return io.ReadFull(r.f, b)
} }
// hideAgainReader masks EAGAIN reads from /dev/urandom. // hideAgainReader masks EAGAIN reads from /dev/urandom.