]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
6decf943 | 2 | * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. |
2ace287d | 3 | * |
b1322259 RS |
4 | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
2ace287d BM |
8 | */ |
9 | ||
b39fc560 | 10 | #include "internal/cryptlib.h" |
c0722725 UM |
11 | #include <openssl/rand.h> |
12 | #include "rand_lcl.h" | |
6decf943 | 13 | #include "internal/rand_int.h" |
7a8c7288 | 14 | #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) |
8389ec4b RS |
15 | |
16 | # ifndef OPENSSL_RAND_SEED_OS | |
17 | # error "Unsupported seeding method configured; must be os" | |
18 | # endif | |
19 | ||
0f113f3e | 20 | # include <windows.h> |
0814afcf | 21 | /* On Windows 7 or higher use BCrypt instead of the legacy CryptoAPI */ |
8389ec4b RS |
22 | # if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0601 |
23 | # define USE_BCRYPTGENRANDOM | |
0814afcf M |
24 | # endif |
25 | ||
8389ec4b | 26 | # ifdef USE_BCRYPTGENRANDOM |
fa64e633 M |
27 | # include <bcrypt.h> |
28 | # pragma comment(lib, "bcrypt.lib") | |
6191fc86 M |
29 | # ifndef STATUS_SUCCESS |
30 | # define STATUS_SUCCESS ((NTSTATUS)0x00000000L) | |
31 | # endif | |
fa64e633 | 32 | # else |
fa64e633 | 33 | # include <wincrypt.h> |
0f113f3e MC |
34 | /* |
35 | * Intel hardware RNG CSP -- available from | |
c0722725 UM |
36 | * http://developer.intel.com/design/security/rng/redist_license.htm |
37 | */ | |
fa64e633 M |
38 | # define PROV_INTEL_SEC 22 |
39 | # define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider" | |
40 | # endif | |
c0722725 | 41 | |
6decf943 | 42 | size_t rand_pool_acquire_entropy(RAND_POOL *pool) |
c0722725 | 43 | { |
8389ec4b | 44 | # ifndef USE_BCRYPTGENRANDOM |
e56f956e | 45 | HCRYPTPROV hProvider; |
fa64e633 | 46 | # endif |
c16de9d8 DMSP |
47 | unsigned char *buffer; |
48 | size_t bytes_needed; | |
49 | size_t entropy_available = 0; | |
50 | ||
0f113f3e | 51 | |
8389ec4b | 52 | # ifdef OPENSSL_RAND_SEED_RDTSC |
c16de9d8 DMSP |
53 | entropy_available = rand_acquire_entropy_from_tsc(pool); |
54 | if (entropy_available > 0) | |
55 | return entropy_available; | |
8389ec4b | 56 | # endif |
c16de9d8 | 57 | |
8389ec4b | 58 | # ifdef OPENSSL_RAND_SEED_RDCPU |
c16de9d8 DMSP |
59 | entropy_available = rand_acquire_entropy_from_cpu(pool); |
60 | if (entropy_available > 0) | |
61 | return entropy_available; | |
8389ec4b RS |
62 | # endif |
63 | ||
64 | # ifdef USE_BCRYPTGENRANDOM | |
6decf943 DMSP |
65 | bytes_needed = rand_pool_bytes_needed(pool, 8 /*entropy_per_byte*/); |
66 | buffer = rand_pool_add_begin(pool, bytes_needed); | |
c16de9d8 DMSP |
67 | if (buffer != NULL) { |
68 | size_t bytes = 0; | |
69 | if (BCryptGenRandom(NULL, buffer, bytes_needed, | |
70 | BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) | |
71 | bytes = bytes_needed; | |
72 | ||
8e2bec9b RL |
73 | rand_pool_add_end(pool, bytes, 8 * bytes); |
74 | entropy_available = rand_pool_entropy_available(pool); | |
9ed79d8e | 75 | } |
c16de9d8 DMSP |
76 | if (entropy_available > 0) |
77 | return entropy_available; | |
fa64e633 | 78 | # else |
6decf943 DMSP |
79 | bytes_needed = rand_pool_bytes_needed(pool, 8 /*entropy_per_byte*/); |
80 | buffer = rand_pool_add_begin(pool, bytes_needed); | |
c16de9d8 DMSP |
81 | if (buffer != NULL) { |
82 | size_t bytes = 0; | |
83 | /* poll the CryptoAPI PRNG */ | |
84 | if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, | |
85 | CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { | |
86 | if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) | |
87 | bytes = bytes_needed; | |
88 | ||
89 | CryptReleaseContext(hProvider, 0); | |
0f113f3e | 90 | } |
c16de9d8 | 91 | |
8e2bec9b RL |
92 | rand_pool_add_end(pool, bytes, 8 * bytes); |
93 | entropy_available = rand_pool_entropy_available(pool); | |
0f113f3e | 94 | } |
c16de9d8 DMSP |
95 | if (entropy_available > 0) |
96 | return entropy_available; | |
97 | ||
6decf943 DMSP |
98 | bytes_needed = rand_pool_bytes_needed(pool, 8 /*entropy_per_byte*/); |
99 | buffer = rand_pool_add_begin(pool, bytes_needed); | |
c16de9d8 DMSP |
100 | if (buffer != NULL) { |
101 | size_t bytes = 0; | |
102 | /* poll the Pentium PRG with CryptoAPI */ | |
103 | if (CryptAcquireContextW(&hProvider, NULL, | |
104 | INTEL_DEF_PROV, PROV_INTEL_SEC, | |
105 | CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { | |
106 | if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) | |
107 | bytes = bytes_needed; | |
0f113f3e | 108 | |
c16de9d8 | 109 | CryptReleaseContext(hProvider, 0); |
0f113f3e | 110 | } |
8e2bec9b RL |
111 | rand_pool_add_end(pool, bytes, 8 * bytes); |
112 | entropy_available = rand_pool_entropy_available(pool); | |
0f113f3e | 113 | } |
c16de9d8 DMSP |
114 | if (entropy_available > 0) |
115 | return entropy_available; | |
fa64e633 | 116 | # endif |
0f113f3e | 117 | |
6decf943 | 118 | return rand_pool_entropy_available(pool); |
0f113f3e | 119 | } |
2ace287d | 120 | |
9ed79d8e | 121 | # if OPENSSL_API_COMPAT < 0x10100000L |
73241290 JY |
122 | int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) |
123 | { | |
124 | RAND_poll(); | |
125 | return RAND_status(); | |
126 | } | |
127 | ||
128 | void RAND_screen(void) | |
129 | { | |
130 | RAND_poll(); | |
131 | } | |
9ed79d8e | 132 | # endif |
73241290 | 133 | |
2ace287d | 134 | #endif |