Path: blob/main/crypto/openssl/providers/implementations/rands/seeding/rand_win.c
107897 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;5455#ifdef OPENSSL_RAND_SEED_RDTSC56entropy_available = ossl_prov_acquire_entropy_from_tsc(pool);57if (entropy_available > 0)58return entropy_available;59#endif6061#ifdef OPENSSL_RAND_SEED_RDCPU62entropy_available = ossl_prov_acquire_entropy_from_cpu(pool);63if (entropy_available > 0)64return entropy_available;65#endif6667#ifdef USE_BCRYPTGENRANDOM68bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);69buffer = ossl_rand_pool_add_begin(pool, bytes_needed);70if (buffer != NULL) {71size_t bytes = 0;72if (BCryptGenRandom(NULL, buffer, bytes_needed,73BCRYPT_USE_SYSTEM_PREFERRED_RNG)74== 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)90!= 0) {91if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0)92bytes = bytes_needed;9394CryptReleaseContext(hProvider, 0);95}9697ossl_rand_pool_add_end(pool, bytes, 8 * bytes);98entropy_available = ossl_rand_pool_entropy_available(pool);99}100if (entropy_available > 0)101return entropy_available;102103bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);104buffer = ossl_rand_pool_add_begin(pool, bytes_needed);105if (buffer != NULL) {106size_t bytes = 0;107/* poll the Pentium PRG with CryptoAPI */108if (CryptAcquireContextW(&hProvider, NULL,109INTEL_DEF_PROV, PROV_INTEL_SEC,110CRYPT_VERIFYCONTEXT | CRYPT_SILENT)111!= 0) {112if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0)113bytes = bytes_needed;114115CryptReleaseContext(hProvider, 0);116}117ossl_rand_pool_add_end(pool, bytes, 8 * bytes);118entropy_available = ossl_rand_pool_entropy_available(pool);119}120if (entropy_available > 0)121return entropy_available;122#endif123124return ossl_rand_pool_entropy_available(pool);125}126127int ossl_pool_add_nonce_data(RAND_POOL *pool)128{129struct {130DWORD pid;131DWORD tid;132FILETIME time;133} data;134135/* Erase the entire structure including any padding */136memset(&data, 0, sizeof(data));137138/*139* Add process id, thread id, and a high resolution timestamp to140* ensure that the nonce is unique with high probability for141* different process instances.142*/143data.pid = GetCurrentProcessId();144data.tid = GetCurrentThreadId();145GetSystemTimeAsFileTime(&data.time);146147return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);148}149150int ossl_rand_pool_init(void)151{152return 1;153}154155void ossl_rand_pool_cleanup(void)156{157}158159void ossl_rand_pool_keep_random_devices_open(int keep)160{161}162163#endif164165166