Skip to content

Commit

Permalink
[release-branch.go1.20] crypto/rand,runtime: revert "switch RtlGenRan…
Browse files Browse the repository at this point in the history
…dom for ProcessPrng"

This reverts CL 545356.

Reason for revert: 1.20 still supports Windows versions before
ProcessPrng was introduced.

Change-Id: I224b8c4e7d0ca9ad5e733819b24dd92d14e61ab8
Reviewed-on: https://go-review.googlesource.com/c/go/+/545995
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
  • Loading branch information
rolandshoemaker authored and gopherbot committed Nov 29, 2023
1 parent d77307f commit 77397ff
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/crypto/rand/rand.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import "io"
// available, /dev/urandom otherwise.
// On OpenBSD and macOS, Reader uses getentropy(2).
// On other Unix-like systems, Reader reads from /dev/urandom.
// On Windows systems, Reader uses the ProcessPrng API.
// On Windows systems, Reader uses the RtlGenRandom API.
// On Wasm, Reader uses the Web Crypto API.
var Reader io.Reader

Expand Down
7 changes: 5 additions & 2 deletions src/crypto/rand/rand_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ func init() { Reader = &rngReader{} }

type rngReader struct{}

func (r *rngReader) Read(b []byte) (int, error) {
if err := windows.ProcessPrng(b); err != nil {
func (r *rngReader) Read(b []byte) (n int, err error) {
// RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at
// most 1<<31-1 bytes at a time so that this works the same on 32-bit
// and 64-bit systems.
if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil {
return 0, err
}
return len(b), nil
Expand Down
2 changes: 1 addition & 1 deletion src/internal/syscall/windows/syscall_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,4 @@ func LoadGetFinalPathNameByHandle() error {
//sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock

//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng
//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
21 changes: 10 additions & 11 deletions src/internal/syscall/windows/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 15 additions & 8 deletions src/runtime/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,15 @@ var (
_LoadLibraryExW,
_ stdFunction

// Use ProcessPrng to generate cryptographically random data.
_ProcessPrng stdFunction
// Use RtlGenRandom to generate cryptographically random data.
// This approach has been recommended by Microsoft (see issue
// 15589 for details).
// The RtlGenRandom is not listed in advapi32.dll, instead
// RtlGenRandom function can be found by searching for SystemFunction036.
// Also some versions of Mingw cannot link to SystemFunction036
// when building executable as Cgo. So load SystemFunction036
// manually during runtime startup.
_RtlGenRandom stdFunction

// Load ntdll.dll manually during startup, otherwise Mingw
// links wrong printf function to cgo executable (see issue
Expand Down Expand Up @@ -249,12 +256,12 @@ func loadOptionalSyscalls() {
_LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)

var bcryptprimitivesdll = []byte("bcryptprimitives.dll\000")
bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll)
if bcryptPrimitives == 0 {
throw("bcryptprimitives.dll not found")
var advapi32dll = []byte("advapi32.dll\000")
a32 := windowsLoadSystemLib(advapi32dll)
if a32 == 0 {
throw("advapi32.dll not found")
}
_ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000"))
_RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))

var ntdll = []byte("ntdll.dll\000")
n32 := windowsLoadSystemLib(ntdll)
Expand Down Expand Up @@ -637,7 +644,7 @@ func initWine(k32 uintptr) {
//go:nosplit
func getRandomData(r []byte) {
n := 0
if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
n = len(r)
}
extendRandom(r, n)
Expand Down

0 comments on commit 77397ff

Please sign in to comment.