mirror of
https://github.com/python/cpython.git
synced 2025-08-30 13:38:43 +00:00
bpo-44611: Use BCryptGenRandom instead of CryptGenRandom on Windows (GH-27168)
This commit is contained in:
parent
a4760cc32d
commit
906fe47083
4 changed files with 19 additions and 41 deletions
|
@ -2,9 +2,7 @@
|
|||
#include "pycore_initconfig.h"
|
||||
#ifdef MS_WINDOWS
|
||||
# include <windows.h>
|
||||
/* All sample MSDN wincrypt programs include the header below. It is at least
|
||||
* required with Min GW. */
|
||||
# include <wincrypt.h>
|
||||
# include <bcrypt.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# ifdef HAVE_SYS_STAT_H
|
||||
|
@ -25,7 +23,7 @@
|
|||
# include <sanitizer/msan_interface.h>
|
||||
#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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue