From 6b4bcc16234575108bb691c15c3532198d9bf98a Mon Sep 17 00:00:00 2001 From: David Gumberg Date: Thu, 1 May 2025 16:36:24 -0700 Subject: [PATCH] random: Use modern Windows randomness functions The old randomness API has been deprecated and may be removed soon.[^1] For reference on `BCryptGenRandom`, see: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom. `STATUS_SUCCESS`[^2] gets defined here since including `ntstatus.h` is more trouble than it's worth. [^3] [^1]: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontextw & https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom [^2]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 [^3]: See https://github.com/bitcoin-core/secp256k1/blob/70f149b9a1bf4ed3266f97774d0ae9577534bf40/examples/examples_util.h#L19-L28 --- contrib/guix/symbol-check.py | 3 ++- src/kernel/CMakeLists.txt | 1 + src/random.cpp | 18 ++++++++---------- src/util/CMakeLists.txt | 1 + 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/contrib/guix/symbol-check.py b/contrib/guix/symbol-check.py index 9bb5322e170..bf102e911e6 100755 --- a/contrib/guix/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -153,7 +153,8 @@ MACHO_ALLOWED_LIBRARIES = { } PE_ALLOWED_LIBRARIES = { -'ADVAPI32.dll', # security & registry +'ADVAPI32.dll', # legacy security & registry +'bcrypt.dll', # newer security and identity API 'IPHLPAPI.DLL', # IP helper API 'KERNEL32.dll', # win32 base APIs 'msvcrt.dll', # C standard library for MSVC diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index b9f37969d37..52e91671dd0 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -87,6 +87,7 @@ target_link_libraries(bitcoinkernel bitcoin_crypto leveldb secp256k1 + $<$:bcrypt> $ PUBLIC Boost::headers diff --git a/src/random.cpp b/src/random.cpp index fa3d8ec3f1e..bd17f6f590f 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -27,8 +27,7 @@ #include #ifdef WIN32 -#include -#include +#include #else #include #include @@ -287,16 +286,15 @@ void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA void GetOSRand(unsigned char *ent32) { #if defined(WIN32) - HCRYPTPROV hProvider; - int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - if (!ret) { + constexpr uint32_t STATUS_SUCCESS{0x00000000}; + NTSTATUS status = BCryptGenRandom(/*hAlgorithm=*/NULL, + /*pbBuffer=*/ent32, + /*cbBuffer=*/NUM_OS_RANDOM_BYTES, + /*dwFlags=*/BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (status != STATUS_SUCCESS) { RandFailure(); } - ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32); - if (!ret) { - RandFailure(); - } - CryptReleaseContext(hProvider, 0); #elif defined(HAVE_GETRANDOM) /* Linux. From the getrandom(2) man page: * "If the urandom source has been initialized, reads of up to 256 bytes diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 4999dbf13f0..9953956f277 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -43,4 +43,5 @@ target_link_libraries(bitcoin_util bitcoin_crypto $<$:ws2_32> $<$:iphlpapi> + $<$:bcrypt> )