This commit is contained in:
Mounir IDRASSI 2025-03-21 06:46:11 +00:00 committed by GitHub
commit 2b37d072eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -20,40 +20,102 @@
# endif
# include <windows.h>
/* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */
# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \
&& defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
# define USE_BCRYPTGENRANDOM
# include <wincrypt.h>
# include "internal/thread_once.h"
# ifndef STATUS_SUCCESS
# define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
# endif
# ifdef USE_BCRYPTGENRANDOM
# include <bcrypt.h>
# ifdef _MSC_VER
# pragma comment(lib, "bcrypt.lib")
# endif
# ifndef STATUS_SUCCESS
# define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
# endif
# else
# include <wincrypt.h>
# ifndef GET_MODULE_HANDLE_EX_FLAG_PIN
# define GET_MODULE_HANDLE_EX_FLAG_PIN 0x00000001
# endif
# ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG
# define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002
# endif
/* prototype of GetModuleHandleExA used to pin bcrypt.dll in memory */
typedef BOOL (WINAPI *GetModuleHandleExAFn)(
DWORD dwFlags,
LPCSTR lpModuleName,
HMODULE* phModule
);
/* prototype of BCryptGenRandom function from bcrypt.dll */
typedef long (WINAPI *BCryptGenRandomFn)(
void* hAlgorithm,
unsigned char* pbBuffer,
unsigned long cbBuffer,
unsigned long dwFlags
);
static BCryptGenRandomFn BCryptGenRandomPtr = NULL;
static CRYPTO_ONCE load_bcrypt_dll = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_load_bcrypt_dll)
{
HMODULE hBCryptDll = NULL;
char system32_path[MAX_PATH];
GetModuleHandleExAFn GetModuleHandleExAPtr = NULL;
/* We get pointer to GetModuleHandleExA dynamically in case it's not
* defined in the compiler's headers
*/
GetModuleHandleExAPtr =
(GetModuleHandleExAFn) GetProcAddress (
GetModuleHandleA ("kernel32.dll"),
"GetModuleHandleExA");
if (GetModuleHandleExAPtr != NULL) {
/* we load bcrypt.dll using absolute path to protect from
* possible dll hijacking since bcrypt.dll is not part of
* the KnownDlls list protected by Windows from such attacks
*/
if (GetSystemDirectoryA (system32_path, MAX_PATH)
&& (strlen(system32_path) < (MAX_PATH - 11))) {
/* we have enough room for "\bcrypt.dll" */
strcat (system32_path, "\\bcrypt.dll");
}
else {
strcpy (system32_path, "C:\\Windows\\System32\\bcrypt.dll");
}
/* Load bcrypt.dll if it is not already loaded and ensure that
* it remains loaded in memory to replicate previous behavior
* where it was linked against explicitely
*/
if (!GetModuleHandleExAPtr (GET_MODULE_HANDLE_EX_FLAG_PIN,
system32_path,
&hBCryptDll)) {
hBCryptDll = LoadLibraryA (system32_path);
if (hBCryptDll != NULL) {
GetModuleHandleExAPtr ( GET_MODULE_HANDLE_EX_FLAG_PIN,
system32_path,
&hBCryptDll);
}
}
}
if (hBCryptDll != NULL) {
BCryptGenRandomPtr = (BCryptGenRandomFn)
GetProcAddress (hBCryptDll, "BCryptGenRandom");
}
return 1;
}
/*
* Intel hardware RNG CSP -- available from
* http://developer.intel.com/design/security/rng/redist_license.htm
*/
# define PROV_INTEL_SEC 22
# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
# endif
# define PROV_INTEL_SEC 22
# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
{
# ifndef USE_BCRYPTGENRANDOM
HCRYPTPROV hProvider;
# endif
unsigned char *buffer;
size_t bytes_needed;
size_t entropy_available = 0;
# ifdef OPENSSL_RAND_SEED_RDTSC
entropy_available = ossl_prov_acquire_entropy_from_tsc(pool);
if (entropy_available > 0)
@ -66,21 +128,24 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
return entropy_available;
# endif
# ifdef USE_BCRYPTGENRANDOM
bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
size_t bytes = 0;
if (BCryptGenRandom(NULL, buffer, bytes_needed,
BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)
bytes = bytes_needed;
if (RUN_ONCE(&load_bcrypt_dll, do_load_bcrypt_dll)) {
if (BCryptGenRandomPtr != NULL) {
bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
size_t bytes = 0;
if (BCryptGenRandomPtr(NULL, buffer, bytes_needed,
BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)
bytes = bytes_needed;
ossl_rand_pool_add_end(pool, bytes, 8 * bytes);
entropy_available = ossl_rand_pool_entropy_available(pool);
ossl_rand_pool_add_end(pool, bytes, 8 * bytes);
entropy_available = ossl_rand_pool_entropy_available(pool);
}
if (entropy_available > 0)
return entropy_available;
}
}
if (entropy_available > 0)
return entropy_available;
# else
bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
@ -118,7 +183,6 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
}
if (entropy_available > 0)
return entropy_available;
# endif
return ossl_rand_pool_entropy_available(pool);
}