2025-08-13 21:50:03 +07:00
|
|
|
From f406141ab7c4861f2738d73ea5b77733ad0aab37 Mon Sep 17 00:00:00 2001
|
2024-11-09 17:58:11 +11:00
|
|
|
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
2025-08-13 21:50:03 +07:00
|
|
|
Date: Wed, 13 Aug 2025 21:41:22 +0700
|
2025-02-14 12:42:07 +07:00
|
|
|
Subject: [PATCH] Switch ProcessPrng back to RtlGenRandom
|
2024-11-09 17:58:11 +11:00
|
|
|
|
|
|
|
|
---
|
2025-02-14 12:42:07 +07:00
|
|
|
src/crypto/internal/sysrand/rand_windows.go | 13 +++++++-
|
2024-11-09 17:58:11 +11:00
|
|
|
src/crypto/rand/rand.go | 2 +-
|
|
|
|
|
.../syscall/windows/syscall_windows.go | 2 +-
|
|
|
|
|
.../syscall/windows/zsyscall_windows.go | 7 ++---
|
|
|
|
|
src/runtime/os_windows.go | 30 ++++++++++++-------
|
2025-02-14 12:42:07 +07:00
|
|
|
5 files changed, 36 insertions(+), 18 deletions(-)
|
2024-11-09 17:58:11 +11:00
|
|
|
|
2025-02-14 12:42:07 +07:00
|
|
|
diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go
|
|
|
|
|
index 91f1490..d23f180 100644
|
|
|
|
|
--- a/src/crypto/internal/sysrand/rand_windows.go
|
|
|
|
|
+++ b/src/crypto/internal/sysrand/rand_windows.go
|
|
|
|
|
@@ -7,5 +7,16 @@ package sysrand
|
|
|
|
|
import "internal/syscall/windows"
|
|
|
|
|
|
|
|
|
|
func read(b []byte) error {
|
|
|
|
|
- return windows.ProcessPrng(b)
|
|
|
|
|
+ const maxChunk = 1<<31 - 1
|
|
|
|
|
+ for len(b) > 0 {
|
|
|
|
|
+ chunk := b
|
|
|
|
|
+ if len(chunk) > maxChunk {
|
|
|
|
|
+ chunk = chunk[:maxChunk]
|
|
|
|
|
+ }
|
|
|
|
|
+ if err := windows.RtlGenRandom(chunk); err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ b = b[len(chunk):]
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
}
|
2024-11-09 17:58:11 +11:00
|
|
|
diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go
|
2025-02-14 12:42:07 +07:00
|
|
|
index 1ca16ca..7d5cea8 100644
|
2024-11-09 17:58:11 +11:00
|
|
|
--- a/src/crypto/rand/rand.go
|
|
|
|
|
+++ b/src/crypto/rand/rand.go
|
2025-02-14 12:42:07 +07:00
|
|
|
@@ -22,7 +22,7 @@ import (
|
|
|
|
|
// - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use.
|
|
|
|
|
// - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3).
|
|
|
|
|
// - On NetBSD, Reader uses the kern.arandom sysctl.
|
2024-11-09 17:58:11 +11:00
|
|
|
-// - On Windows, Reader uses the ProcessPrng API.
|
|
|
|
|
+// - On Windows, Reader uses the RtlGenRandom API.
|
|
|
|
|
// - On js/wasm, Reader uses the Web Crypto API.
|
2025-02-14 12:42:07 +07:00
|
|
|
// - On wasip1/wasm, Reader uses random_get.
|
|
|
|
|
//
|
2024-11-09 17:58:11 +11:00
|
|
|
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
|
2025-08-13 21:50:03 +07:00
|
|
|
index 905cabc..94d280b 100644
|
2024-11-09 17:58:11 +11:00
|
|
|
--- a/src/internal/syscall/windows/syscall_windows.go
|
|
|
|
|
+++ b/src/internal/syscall/windows/syscall_windows.go
|
2025-08-13 21:50:03 +07:00
|
|
|
@@ -419,7 +419,7 @@ func ErrorLoadingGetTempPath2() error {
|
2024-11-09 17:58:11 +11:00
|
|
|
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
|
|
|
|
|
//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
|
|
|
|
|
|
|
|
|
|
-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng
|
|
|
|
|
+//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
|
|
|
|
|
|
|
|
|
|
type FILE_ID_BOTH_DIR_INFO struct {
|
|
|
|
|
NextEntryOffset uint32
|
|
|
|
|
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
|
2025-08-13 21:50:03 +07:00
|
|
|
index 90cf0b9..87d0b9e 100644
|
2024-11-09 17:58:11 +11:00
|
|
|
--- a/src/internal/syscall/windows/zsyscall_windows.go
|
|
|
|
|
+++ b/src/internal/syscall/windows/zsyscall_windows.go
|
|
|
|
|
@@ -38,7 +38,6 @@ 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"))
|
2025-02-14 12:42:07 +07:00
|
|
|
@@ -63,7 +62,7 @@ var (
|
2024-11-09 17:58:11 +11:00
|
|
|
procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus")
|
|
|
|
|
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
|
|
|
|
procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
|
|
|
|
|
- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng")
|
|
|
|
|
+ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036")
|
|
|
|
|
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
|
|
|
|
procCreateEventW = modkernel32.NewProc("CreateEventW")
|
2025-08-13 21:50:03 +07:00
|
|
|
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
|
|
|
|
@@ -242,12 +241,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
|
2024-11-09 17:58:11 +11:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
|
2025-08-13 21:50:03 +07:00
|
|
|
index 04752f2..a6d3211 100644
|
2024-11-09 17:58:11 +11:00
|
|
|
--- a/src/runtime/os_windows.go
|
|
|
|
|
+++ b/src/runtime/os_windows.go
|
2025-08-13 21:50:03 +07:00
|
|
|
@@ -127,8 +127,15 @@ var (
|
2024-11-09 17:58:11 +11:00
|
|
|
_WriteFile,
|
|
|
|
|
_ 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
|
2025-08-13 21:50:03 +07:00
|
|
|
@@ -146,10 +153,11 @@ var (
|
2024-11-09 17:58:11 +11:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
+ advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
+ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
+ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
+ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
+ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Function to be called by windows CreateThread
|
2025-08-13 21:50:03 +07:00
|
|
|
@@ -263,11 +271,11 @@ func windows_QueryPerformanceFrequency() int64 {
|
2024-11-09 17:58:11 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func loadOptionalSyscalls() {
|
|
|
|
|
- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:])
|
|
|
|
|
- if bcryptPrimitives == 0 {
|
|
|
|
|
- throw("bcryptprimitives.dll not found")
|
|
|
|
|
+ a32 := windowsLoadSystemLib(advapi32dll[:])
|
|
|
|
|
+ if a32 == 0 {
|
|
|
|
|
+ throw("advapi32.dll not found")
|
|
|
|
|
}
|
|
|
|
|
- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000"))
|
|
|
|
|
+ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
|
|
|
|
|
|
|
|
|
|
n32 := windowsLoadSystemLib(ntdlldll[:])
|
|
|
|
|
if n32 == 0 {
|
2025-08-13 21:50:03 +07:00
|
|
|
@@ -500,7 +508,7 @@ func osinit() {
|
2024-11-09 17:58:11 +11:00
|
|
|
//go:nosplit
|
|
|
|
|
func readRandom(r []byte) int {
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
return n
|
|
|
|
|
--
|
2025-02-14 12:42:07 +07:00
|
|
|
2.39.5
|
2024-11-09 17:58:11 +11:00
|
|
|
|