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:
5db094c85ae14bbd9f80247d46d90e00061187cc
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>
// 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
// 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
// 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")
--- /dev/null
+// 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
+}
+++ /dev/null
-// 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
-}