#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
# 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
#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);
}
#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)))
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
void
_Py_HashRandomization_Fini(void)
{
-#ifdef MS_WINDOWS
- if (hCryptProv) {
- CryptReleaseContext(hCryptProv, 0);
- hCryptProv = 0;
- }
-#else
+#ifndef MS_WINDOWS
dev_urandom_close();
#endif
}