Path: blob/main/crypto/openssl/providers/implementations/rands/seeding/rand_win.c
48531 views
/*1* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include "internal/cryptlib.h"10#include <openssl/rand.h>11#include "crypto/rand_pool.h"12#include "crypto/rand.h"13#include "prov/seeding.h"1415#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)1617# ifndef OPENSSL_RAND_SEED_OS18# error "Unsupported seeding method configured; must be os"19# endif2021# include <windows.h>22/* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */23# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \24&& defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x060025# define USE_BCRYPTGENRANDOM26# endif2728# ifdef USE_BCRYPTGENRANDOM29# include <bcrypt.h>30# ifdef _MSC_VER31# pragma comment(lib, "bcrypt.lib")32# endif33# ifndef STATUS_SUCCESS34# define STATUS_SUCCESS ((NTSTATUS)0x00000000L)35# endif36# else37# include <wincrypt.h>38/*39* Intel hardware RNG CSP -- available from40* http://developer.intel.com/design/security/rng/redist_license.htm41*/42# define PROV_INTEL_SEC 2243# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"44# endif4546size_t ossl_pool_acquire_entropy(RAND_POOL *pool)47{48# ifndef USE_BCRYPTGENRANDOM49HCRYPTPROV hProvider;50# endif51unsigned char *buffer;52size_t bytes_needed;53size_t entropy_available = 0;545556# ifdef OPENSSL_RAND_SEED_RDTSC57entropy_available = ossl_prov_acquire_entropy_from_tsc(pool);58if (entropy_available > 0)59return entropy_available;60# endif6162# ifdef OPENSSL_RAND_SEED_RDCPU63entropy_available = ossl_prov_acquire_entropy_from_cpu(pool);64if (entropy_available > 0)65return entropy_available;66# endif6768# ifdef USE_BCRYPTGENRANDOM69bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);70buffer = ossl_rand_pool_add_begin(pool, bytes_needed);71if (buffer != NULL) {72size_t bytes = 0;73if (BCryptGenRandom(NULL, buffer, bytes_needed,74BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)75bytes = bytes_needed;7677ossl_rand_pool_add_end(pool, bytes, 8 * bytes);78entropy_available = ossl_rand_pool_entropy_available(pool);79}80if (entropy_available > 0)81return entropy_available;82# else83bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);84buffer = ossl_rand_pool_add_begin(pool, bytes_needed);85if (buffer != NULL) {86size_t bytes = 0;87/* poll the CryptoAPI PRNG */88if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,89CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {90if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0)91bytes = bytes_needed;9293CryptReleaseContext(hProvider, 0);94}9596ossl_rand_pool_add_end(pool, bytes, 8 * bytes);97entropy_available = ossl_rand_pool_entropy_available(pool);98}99if (entropy_available > 0)100return entropy_available;101102bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);103buffer = ossl_rand_pool_add_begin(pool, bytes_needed);104if (buffer != NULL) {105size_t bytes = 0;106/* poll the Pentium PRG with CryptoAPI */107if (CryptAcquireContextW(&hProvider, NULL,108INTEL_DEF_PROV, PROV_INTEL_SEC,109CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {110if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0)111bytes = bytes_needed;112113CryptReleaseContext(hProvider, 0);114}115ossl_rand_pool_add_end(pool, bytes, 8 * bytes);116entropy_available = ossl_rand_pool_entropy_available(pool);117}118if (entropy_available > 0)119return entropy_available;120# endif121122return ossl_rand_pool_entropy_available(pool);123}124125126int ossl_pool_add_nonce_data(RAND_POOL *pool)127{128struct {129DWORD pid;130DWORD tid;131FILETIME time;132} data;133134/* Erase the entire structure including any padding */135memset(&data, 0, sizeof(data));136137/*138* Add process id, thread id, and a high resolution timestamp to139* ensure that the nonce is unique with high probability for140* different process instances.141*/142data.pid = GetCurrentProcessId();143data.tid = GetCurrentThreadId();144GetSystemTimeAsFileTime(&data.time);145146return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);147}148149int ossl_rand_pool_init(void)150{151return 1;152}153154void ossl_rand_pool_cleanup(void)155{156}157158void ossl_rand_pool_keep_random_devices_open(int keep)159{160}161162#endif163164165