Source file src/crypto/rand/rand_batched.go

Documentation: crypto/rand

     1  // Copyright 2014 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  // +build linux freebsd
     6  
     7  package rand
     8  
     9  import (
    10  	"internal/syscall/unix"
    11  )
    12  
    13  // maxGetRandomRead is platform dependent.
    14  func init() {
    15  	altGetRandom = batched(getRandomBatch, maxGetRandomRead)
    16  }
    17  
    18  // batched returns a function that calls f to populate a []byte by chunking it
    19  // into subslices of, at most, readMax bytes.
    20  func batched(f func([]byte) bool, readMax int) func([]byte) bool {
    21  	return func(buf []byte) bool {
    22  		for len(buf) > readMax {
    23  			if !f(buf[:readMax]) {
    24  				return false
    25  			}
    26  			buf = buf[readMax:]
    27  		}
    28  		return len(buf) == 0 || f(buf)
    29  	}
    30  }
    31  
    32  // If the kernel is too old to support the getrandom syscall(),
    33  // unix.GetRandom will immediately return ENOSYS and we will then fall back to
    34  // reading from /dev/urandom in rand_unix.go. unix.GetRandom caches the ENOSYS
    35  // result so we only suffer the syscall overhead once in this case.
    36  // If the kernel supports the getrandom() syscall, unix.GetRandom will block
    37  // until the kernel has sufficient randomness (as we don't use GRND_NONBLOCK).
    38  // In this case, unix.GetRandom will not return an error.
    39  func getRandomBatch(p []byte) (ok bool) {
    40  	n, err := unix.GetRandom(p, 0)
    41  	return n == len(p) && err == nil
    42  }
    43  

View as plain text