Skip to content

Commit 906fe47

Browse files
authored
bpo-44611: Use BCryptGenRandom instead of CryptGenRandom on Windows (GH-27168)
1 parent a4760cc commit 906fe47

File tree

4 files changed

+19
-41
lines changed

4 files changed

+19
-41
lines changed

Doc/whatsnew/3.11.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ math
198198
Dickinson in :issue:`44339`.)
199199

200200

201+
os
202+
--
203+
204+
* On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API
205+
which is deprecated from Microsoft Windows API.
206+
(Contributed by Dong-hee Na in :issue:`44611`.)
207+
208+
201209
sqlite3
202210
-------
203211

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API
2+
which is deprecated from Microsoft Windows API. Patch by Dong-hee Na.

PCbuild/pythoncore.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
<PreprocessorDefinitions Condition="$(IncludeExternals)">_Py_HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
107107
</ClCompile>
108108
<Link>
109-
<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
109+
<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
110110
</Link>
111111
</ItemDefinitionGroup>
112112
<ItemGroup>

Python/bootstrap_hash.c

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
#include "pycore_initconfig.h"
33
#ifdef MS_WINDOWS
44
# include <windows.h>
5-
/* All sample MSDN wincrypt programs include the header below. It is at least
6-
* required with Min GW. */
7-
# include <wincrypt.h>
5+
# include <bcrypt.h>
86
#else
97
# include <fcntl.h>
108
# ifdef HAVE_SYS_STAT_H
@@ -25,7 +23,7 @@
2523
# include <sanitizer/msan_interface.h>
2624
#endif
2725

28-
#if defined(__APPLE__) && defined(__has_builtin)
26+
#if defined(__APPLE__) && defined(__has_builtin)
2927
# if __has_builtin(__builtin_available)
3028
# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME __builtin_available(macOS 10.12, iOS 10.10, tvOS 10.0, watchOS 3.0, *)
3129
# endif
@@ -42,43 +40,18 @@ static int _Py_HashSecret_Initialized = 0;
4240
#endif
4341

4442
#ifdef MS_WINDOWS
45-
static HCRYPTPROV hCryptProv = 0;
46-
47-
static int
48-
win32_urandom_init(int raise)
49-
{
50-
/* Acquire context */
51-
if (!CryptAcquireContextW(&hCryptProv, NULL, NULL,
52-
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
53-
goto error;
54-
55-
return 0;
56-
57-
error:
58-
if (raise) {
59-
PyErr_SetFromWindowsErr(0);
60-
}
61-
return -1;
62-
}
6343

6444
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
6545
API. Return 0 on success, or raise an exception and return -1 on error. */
6646
static int
6747
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
6848
{
69-
if (hCryptProv == 0)
70-
{
71-
if (win32_urandom_init(raise) == -1) {
72-
return -1;
73-
}
74-
}
75-
7649
while (size > 0)
7750
{
7851
DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX);
79-
if (!CryptGenRandom(hCryptProv, chunk, buffer))
80-
{
81-
/* CryptGenRandom() failed */
52+
NTSTATUS status = BCryptGenRandom(NULL, buffer, chunk, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
53+
if (!BCRYPT_SUCCESS(status)) {
54+
/* BCryptGenRandom() failed */
8255
if (raise) {
8356
PyErr_SetFromWindowsErr(0);
8457
}
@@ -221,7 +194,7 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
221194

222195
#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
223196
static int
224-
py_getentropy(char *buffer, Py_ssize_t size, int raise)
197+
py_getentropy(char *buffer, Py_ssize_t size, int raise)
225198
__attribute__((availability(macos,introduced=10.12)))
226199
__attribute__((availability(ios,introduced=10.0)))
227200
__attribute__((availability(tvos,introduced=10.0)))
@@ -458,7 +431,7 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
458431
459432
Used sources of entropy ordered by preference, preferred source first:
460433
461-
- CryptGenRandom() on Windows
434+
- BCryptGenRandom() on Windows
462435
- getrandom() function (ex: Linux and Solaris): call py_getrandom()
463436
- getentropy() function (ex: OpenBSD): call py_getentropy()
464437
- /dev/urandom device
@@ -612,12 +585,7 @@ _Py_HashRandomization_Init(const PyConfig *config)
612585
void
613586
_Py_HashRandomization_Fini(void)
614587
{
615-
#ifdef MS_WINDOWS
616-
if (hCryptProv) {
617-
CryptReleaseContext(hCryptProv, 0);
618-
hCryptProv = 0;
619-
}
620-
#else
588+
#ifndef MS_WINDOWS
621589
dev_urandom_close();
622590
#endif
623591
}

0 commit comments

Comments
 (0)