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 package rand 6 7 import ( 8 "internal/syscall/unix" 9 "sync" 10 ) 11 12 func init() { 13 altGetRandom = getRandomLinux 14 } 15 16 var ( 17 once sync.Once 18 useSyscall bool 19 ) 20 21 func pickStrategy() { 22 // Test whether we should use the system call or /dev/urandom. 23 // We'll fall back to urandom if: 24 // - the kernel is too old (before 3.17) 25 // - the machine has no entropy available (early boot + no hardware 26 // entropy source?) and we want to avoid blocking later. 27 var buf [1]byte 28 n, err := unix.GetRandom(buf[:], unix.GRND_NONBLOCK) 29 useSyscall = n == 1 && err == nil 30 } 31 32 func getRandomLinux(p []byte) (ok bool) { 33 once.Do(pickStrategy) 34 if !useSyscall { 35 return false 36 } 37 n, err := unix.GetRandom(p, 0) 38 return n == len(p) && err == nil 39 } 40