From ddfe7b3dc00291862f33224b68ffdad0ef4001ab Mon Sep 17 00:00:00 2001 From: Michael McConville Date: Sat, 2 Jan 2016 20:50:57 -0500 Subject: [PATCH] crypto/rand: use the getentropy syscall on OpenBSD Go already supports Linux's getrandom, which is a slightly modified version of getentropy. getentropy was added in OpenBSD 5.6. All supported versions of OpenBSD include it so, unlike with Linux and getrandom, we don't need to test for its presence. Fixes #13785. Change-Id: Ib536b96675f257cd8c5de1e3a36165e15c9abac9 Reviewed-on: https://go-review.googlesource.com/18219 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/crypto/rand/rand.go | 3 +- src/crypto/rand/rand_openbsd.go | 28 +++++++++++++++++++ .../syscall/unix/getentropy_openbsd.go | 25 +++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/crypto/rand/rand_openbsd.go create mode 100644 src/internal/syscall/unix/getentropy_openbsd.go diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go index ee32fa0bd6..5e48fc9cd9 100644 --- a/src/crypto/rand/rand.go +++ b/src/crypto/rand/rand.go @@ -11,8 +11,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 OpenBSD, Reader uses getentropy(2). +// On other Unix-like systems, Reader reads from /dev/urandom. // On Windows systems, Reader uses the CryptGenRandom API. var Reader io.Reader diff --git a/src/crypto/rand/rand_openbsd.go b/src/crypto/rand/rand_openbsd.go new file mode 100644 index 0000000000..405c091060 --- /dev/null +++ b/src/crypto/rand/rand_openbsd.go @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +package rand + +import ( + "internal/syscall/unix" +) + +func init() { + altGetRandom = getRandomOpenBSD +} + +func getRandomOpenBSD(p []byte) (ok bool) { + // getentropy(2) returns a maximum of 256 bytes per call + for i := 0; i < len(p); i += 256 { + end := i + 256 + if len(p) < end { + end = len(p) + } + err := unix.GetEntropy(p[i:end]) + if err != nil { + return false + } + } + return true +} diff --git a/src/internal/syscall/unix/getentropy_openbsd.go b/src/internal/syscall/unix/getentropy_openbsd.go new file mode 100644 index 0000000000..fd3dabc3f2 --- /dev/null +++ b/src/internal/syscall/unix/getentropy_openbsd.go @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +package unix + +import ( + "syscall" + "unsafe" +) + +// getentropy(2)'s syscall number, from /usr/src/sys/kern/syscalls.master +const entropyTrap uintptr = 7 + +// GetEntropy calls the OpenBSD getentropy system call. +func GetEntropy(p []byte) error { + _, _, errno := syscall.Syscall(entropyTrap, + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + 0) + if errno != 0 { + return errno + } + return nil +} -- 2.51.0