]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.20] crypto/rand,runtime: revert "switch RtlGenRandom for ProcessPrng"
authorRoland Shoemaker <roland@golang.org>
Wed, 29 Nov 2023 20:01:24 +0000 (20:01 +0000)
committerGopher Robot <gobot@golang.org>
Wed, 29 Nov 2023 20:58:26 +0000 (20:58 +0000)
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>

src/crypto/rand/rand.go
src/crypto/rand/rand_windows.go
src/internal/syscall/windows/syscall_windows.go
src/internal/syscall/windows/zsyscall_windows.go
src/runtime/os_windows.go

index 0f3dca4e0ee5370a31c190a6142a8ac1f94a4a4c..af85b966df6e43fe35964b3b79c61fb415ab4e46 100644 (file)
@@ -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
 
index 7380f1f0f1e6e6ee21a912318fdefdf1655e1a0c..6c0655c72b692ae444a85025ecc3d27d65107404 100644 (file)
@@ -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
index b7bf886f3896302c9a37540b7e7f4195a1b3e5c4..8ace2a27e79fcb5f84fa87b959469468050de263 100644 (file)
@@ -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
index 7ed6234451fa2b27b294b8a13e6dc7b441fd34e8..afd64e318e516daea2e2d429bd172a934b252200 100644 (file)
@@ -37,14 +37,13 @@ func errnoErr(e syscall.Errno) error {
 }
 
 var (
-       modadvapi32         = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
-       modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll"))
-       modiphlpapi         = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
-       modkernel32         = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
-       modnetapi32         = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
-       modpsapi            = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
-       moduserenv          = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
-       modws2_32           = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
+       modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
+       modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
+       modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
+       modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
+       modpsapi    = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
+       moduserenv  = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
+       modws2_32   = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
 
        procAdjustTokenPrivileges        = modadvapi32.NewProc("AdjustTokenPrivileges")
        procDuplicateTokenEx             = modadvapi32.NewProc("DuplicateTokenEx")
@@ -53,7 +52,7 @@ var (
        procOpenThreadToken              = modadvapi32.NewProc("OpenThreadToken")
        procRevertToSelf                 = modadvapi32.NewProc("RevertToSelf")
        procSetTokenInformation          = modadvapi32.NewProc("SetTokenInformation")
-       procProcessPrng                  = modbcryptprimitives.NewProc("ProcessPrng")
+       procSystemFunction036            = modadvapi32.NewProc("SystemFunction036")
        procGetAdaptersAddresses         = modiphlpapi.NewProc("GetAdaptersAddresses")
        procGetACP                       = modkernel32.NewProc("GetACP")
        procGetComputerNameExW           = modkernel32.NewProc("GetComputerNameExW")
@@ -145,12 +144,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
        return
 }
 
-func ProcessPrng(buf []byte) (err error) {
+func RtlGenRandom(buf []byte) (err error) {
        var _p0 *byte
        if len(buf) > 0 {
                _p0 = &buf[0]
        }
-       r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
+       r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
        if r1 == 0 {
                err = errnoErr(e1)
        }
index a88d3a8ac6ed78db6813fde4537ae559f8f3c60b..44718f1d21459e164f4dcf7f3592160ef9d81059 100644 (file)
@@ -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
@@ -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)
@@ -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)