crypto/rand, internal/syscall/unix: use simpler random seed on NetBSD

sysctl kern.arandom has been supported since NetBSD 4.0, works inside a
chroot, has no confusing bells and whistles like Linux getrandom,
requires no complicated querying to avoid SIGSYS traps, and is what
NetBSD 10 will usee for the getentropy(3) library routine soon to
appear in POSIX.

Change-Id: I23bd84ecd5ff3e33e8958c60896db842c44667ba
GitHub-Last-Rev: 5db094c85a
GitHub-Pull-Request: golang/go#61441
Reviewed-on: https://go-review.googlesource.com/c/go/+/511036
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Maya Rashish 2023-08-02 08:32:07 +00:00 committed by Gopher Robot
parent 20b5f3ae8b
commit 9701d078c6
4 changed files with 41 additions and 59 deletions

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (darwin && !ios) || openbsd
//go:build (darwin && !ios) || openbsd || netbsd
package rand

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || linux || netbsd || solaris
//go:build dragonfly || freebsd || linux || solaris
package rand
@ -21,7 +21,7 @@ func init() {
// is returned by a single call to getrandom() on systems where int
// has a size of 32 bits.
maxGetRandomRead = (1 << 25) - 1
case "dragonfly", "freebsd", "illumos", "netbsd", "solaris":
case "dragonfly", "freebsd", "illumos", "solaris":
maxGetRandomRead = 1 << 8
default:
panic("no maximum specified for GetRandom")

View File

@ -0,0 +1,38 @@
// Copyright 2023 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.
//go:build netbsd
package unix
import (
"syscall"
"unsafe"
)
const (
_CTL_KERN = 1
_KERN_ARND = 81
)
func GetEntropy(p []byte) error {
mib := [2]uint32{_CTL_KERN, _KERN_ARND}
n := uintptr(len(p))
_, _, errno := syscall.Syscall6(
syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])),
uintptr(len(mib)),
uintptr(unsafe.Pointer(&p[0])), // olddata
uintptr(unsafe.Pointer(&n)), // &oldlen
uintptr(unsafe.Pointer(nil)), // newdata
0) // newlen
if errno != 0 {
return syscall.Errno(errno)
}
if n != uintptr(len(p)) {
return syscall.EINVAL
}
return nil
}

View File

@ -1,56 +0,0 @@
// Copyright 2023 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 (
"sync"
"sync/atomic"
"syscall"
"unsafe"
)
// NetBSD getrandom system call number.
const getrandomTrap uintptr = 91
var getrandomUnsupported atomic.Bool
// GetRandomFlag is a flag supported by the getrandom system call.
type GetRandomFlag uintptr
// GetRandom calls the getrandom system call.
func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
if len(p) == 0 {
return 0, nil
}
if getrandomUnsupported.Load() {
return 0, syscall.ENOSYS
}
// getrandom(2) was added in NetBSD 10.0
if getOSRevision() < 1000000000 {
getrandomUnsupported.Store(true)
return 0, syscall.ENOSYS
}
r1, _, errno := syscall.Syscall(getrandomTrap,
uintptr(unsafe.Pointer(&p[0])),
uintptr(len(p)),
uintptr(flags))
if errno != 0 {
if errno == syscall.ENOSYS {
getrandomUnsupported.Store(true)
}
return 0, errno
}
return int(r1), nil
}
var (
osrevisionOnce sync.Once
osrevision uint32
)
func getOSRevision() uint32 {
osrevisionOnce.Do(func() { osrevision, _ = syscall.SysctlUint32("kern.osrevision") })
return osrevision
}