From 906fe47083bc9ab7ed2b70c99c1b0daad021f126 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 23 Jul 2021 14:04:30 +0000 Subject: bpo-44611: Use BCryptGenRandom instead of CryptGenRandom on Windows (GH-27168) --- Doc/whatsnew/3.11.rst | 8 ++++ .../2021-07-16-01-01-11.bpo-44611.LcfHN-.rst | 2 + PCbuild/pythoncore.vcxproj | 2 +- Python/bootstrap_hash.c | 48 ++++------------------ 4 files changed, 19 insertions(+), 41 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-07-16-01-01-11.bpo-44611.LcfHN-.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 7d2e4e8..190c422 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -198,6 +198,14 @@ math Dickinson in :issue:`44339`.) +os +-- + +* On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API + which is deprecated from Microsoft Windows API. + (Contributed by Dong-hee Na in :issue:`44611`.) + + sqlite3 ------- diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-07-16-01-01-11.bpo-44611.LcfHN-.rst b/Misc/NEWS.d/next/Core and Builtins/2021-07-16-01-01-11.bpo-44611.LcfHN-.rst new file mode 100644 index 0000000..1cc8b12 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-07-16-01-01-11.bpo-44611.LcfHN-.rst @@ -0,0 +1,2 @@ +On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API +which is deprecated from Microsoft Windows API. Patch by Dong-hee Na. diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 7cd3c21..7b2a9b5 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -106,7 +106,7 @@ _Py_HAVE_ZLIB;%(PreprocessorDefinitions) - version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;%(AdditionalDependencies) + version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies) diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index a212f69..144f7cb 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -2,9 +2,7 @@ #include "pycore_initconfig.h" #ifdef MS_WINDOWS # include -/* All sample MSDN wincrypt programs include the header below. It is at least - * required with Min GW. */ -# include +# include #else # include # ifdef HAVE_SYS_STAT_H @@ -25,7 +23,7 @@ # include #endif -#if defined(__APPLE__) && defined(__has_builtin) +#if defined(__APPLE__) && defined(__has_builtin) # if __has_builtin(__builtin_available) # define HAVE_GETENTRYPY_GETRANDOM_RUNTIME __builtin_available(macOS 10.12, iOS 10.10, tvOS 10.0, watchOS 3.0, *) # endif @@ -42,43 +40,18 @@ static int _Py_HashSecret_Initialized = 0; #endif #ifdef MS_WINDOWS -static HCRYPTPROV hCryptProv = 0; - -static int -win32_urandom_init(int raise) -{ - /* Acquire context */ - if (!CryptAcquireContextW(&hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - goto error; - - return 0; - -error: - if (raise) { - PyErr_SetFromWindowsErr(0); - } - return -1; -} /* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen API. Return 0 on success, or raise an exception and return -1 on error. */ static int win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) { - if (hCryptProv == 0) - { - if (win32_urandom_init(raise) == -1) { - return -1; - } - } - while (size > 0) { DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX); - if (!CryptGenRandom(hCryptProv, chunk, buffer)) - { - /* CryptGenRandom() failed */ + NTSTATUS status = BCryptGenRandom(NULL, buffer, chunk, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (!BCRYPT_SUCCESS(status)) { + /* BCryptGenRandom() failed */ if (raise) { PyErr_SetFromWindowsErr(0); } @@ -221,7 +194,7 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) static int -py_getentropy(char *buffer, Py_ssize_t size, int raise) +py_getentropy(char *buffer, Py_ssize_t size, int raise) __attribute__((availability(macos,introduced=10.12))) __attribute__((availability(ios,introduced=10.0))) __attribute__((availability(tvos,introduced=10.0))) @@ -458,7 +431,7 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) Used sources of entropy ordered by preference, preferred source first: - - CryptGenRandom() on Windows + - BCryptGenRandom() on Windows - getrandom() function (ex: Linux and Solaris): call py_getrandom() - getentropy() function (ex: OpenBSD): call py_getentropy() - /dev/urandom device @@ -612,12 +585,7 @@ _Py_HashRandomization_Init(const PyConfig *config) void _Py_HashRandomization_Fini(void) { -#ifdef MS_WINDOWS - if (hCryptProv) { - CryptReleaseContext(hCryptProv, 0); - hCryptProv = 0; - } -#else +#ifndef MS_WINDOWS dev_urandom_close(); #endif } -- cgit v0.12