summaryrefslogtreecommitdiff
path: root/libgo/go/crypto/rand
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/rand')
-rw-r--r--libgo/go/crypto/rand/eagain.go27
-rw-r--r--libgo/go/crypto/rand/rand.go2
-rw-r--r--libgo/go/crypto/rand/rand_linux.go6
-rw-r--r--libgo/go/crypto/rand/rand_unix.go18
-rw-r--r--libgo/go/crypto/rand/util_test.go2
5 files changed, 50 insertions, 5 deletions
diff --git a/libgo/go/crypto/rand/eagain.go b/libgo/go/crypto/rand/eagain.go
new file mode 100644
index 00000000000..2c853d0a134
--- /dev/null
+++ b/libgo/go/crypto/rand/eagain.go
@@ -0,0 +1,27 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package rand
+
+import (
+ "os"
+ "syscall"
+)
+
+func init() {
+ isEAGAIN = unixIsEAGAIN
+}
+
+// unixIsEAGAIN reports whether err is a syscall.EAGAIN wrapped in a PathError.
+// See golang.org/issue/9205
+func unixIsEAGAIN(err error) bool {
+ if pe, ok := err.(*os.PathError); ok {
+ if errno, ok := pe.Err.(syscall.Errno); ok && errno == syscall.EAGAIN {
+ return true
+ }
+ }
+ return false
+}
diff --git a/libgo/go/crypto/rand/rand.go b/libgo/go/crypto/rand/rand.go
index 4da3adb7010..ee32fa0bd67 100644
--- a/libgo/go/crypto/rand/rand.go
+++ b/libgo/go/crypto/rand/rand.go
@@ -10,7 +10,9 @@ import "io"
// Reader is a global, shared instance of a cryptographically
// strong pseudo-random generator.
+//
// On Unix-like systems, Reader reads from /dev/urandom.
+// On Linux, Reader uses getrandom(2) if available, /dev/urandom otherwise.
// On Windows systems, Reader uses the CryptGenRandom API.
var Reader io.Reader
diff --git a/libgo/go/crypto/rand/rand_linux.go b/libgo/go/crypto/rand/rand_linux.go
index 8cb59c75dff..7d6d9e8a094 100644
--- a/libgo/go/crypto/rand/rand_linux.go
+++ b/libgo/go/crypto/rand/rand_linux.go
@@ -5,7 +5,7 @@
package rand
import (
- "internal/syscall"
+ "internal/syscall/unix"
"sync"
)
@@ -25,7 +25,7 @@ func pickStrategy() {
// - the machine has no entropy available (early boot + no hardware
// entropy source?) and we want to avoid blocking later.
var buf [1]byte
- n, err := syscall.GetRandom(buf[:], syscall.GRND_NONBLOCK)
+ n, err := unix.GetRandom(buf[:], unix.GRND_NONBLOCK)
useSyscall = n == 1 && err == nil
}
@@ -34,6 +34,6 @@ func getRandomLinux(p []byte) (ok bool) {
if !useSyscall {
return false
}
- n, err := syscall.GetRandom(p, 0)
+ n, err := unix.GetRandom(p, 0)
return n == len(p) && err == nil
}
diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go
index 62d0fbdb350..75c36e05b34 100644
--- a/libgo/go/crypto/rand/rand_unix.go
+++ b/libgo/go/crypto/rand/rand_unix.go
@@ -58,12 +58,28 @@ func (r *devReader) Read(b []byte) (n int, err error) {
if runtime.GOOS == "plan9" {
r.f = f
} else {
- r.f = bufio.NewReader(f)
+ r.f = bufio.NewReader(hideAgainReader{f})
}
}
return r.f.Read(b)
}
+var isEAGAIN func(error) bool // set by eagain.go on unix systems
+
+// hideAgainReader masks EAGAIN reads from /dev/urandom.
+// See golang.org/issue/9205
+type hideAgainReader struct {
+ r io.Reader
+}
+
+func (hr hideAgainReader) Read(p []byte) (n int, err error) {
+ n, err = hr.r.Read(p)
+ if err != nil && isEAGAIN != nil && isEAGAIN(err) {
+ err = nil
+ }
+ return
+}
+
// Alternate pseudo-random implementation for use on
// systems without a reliable /dev/urandom.
diff --git a/libgo/go/crypto/rand/util_test.go b/libgo/go/crypto/rand/util_test.go
index 1e2a4dd84b7..2f7cba8364a 100644
--- a/libgo/go/crypto/rand/util_test.go
+++ b/libgo/go/crypto/rand/util_test.go
@@ -10,7 +10,7 @@ import (
"testing"
)
-// http://golang.org/issue/6849.
+// https://golang.org/issue/6849.
func TestPrimeSmall(t *testing.T) {
for n := 2; n < 10; n++ {
p, err := rand.Prime(rand.Reader, n)