]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
6decf943 | 2 | * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. |
2ace287d | 3 | * |
0db63de9 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
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> |
2621e640 | 21 | /* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */ |
d3a1128b BE |
22 | # if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \ |
23 | && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 | |
8389ec4b | 24 | # define USE_BCRYPTGENRANDOM |
0814afcf M |
25 | # endif |
26 | ||
8389ec4b | 27 | # ifdef USE_BCRYPTGENRANDOM |
fa64e633 M |
28 | # include <bcrypt.h> |
29 | # pragma comment(lib, "bcrypt.lib") | |
6191fc86 M |
30 | # ifndef STATUS_SUCCESS |
31 | # define STATUS_SUCCESS ((NTSTATUS)0x00000000L) | |
32 | # endif | |
fa64e633 | 33 | # else |
fa64e633 | 34 | # include <wincrypt.h> |
0f113f3e MC |
35 | /* |
36 | * Intel hardware RNG CSP -- available from | |
c0722725 UM |
37 | * http://developer.intel.com/design/security/rng/redist_license.htm |
38 | */ | |
fa64e633 M |
39 | # define PROV_INTEL_SEC 22 |
40 | # define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider" | |
41 | # endif | |
c0722725 | 42 | |
6decf943 | 43 | size_t rand_pool_acquire_entropy(RAND_POOL *pool) |
c0722725 | 44 | { |
8389ec4b | 45 | # ifndef USE_BCRYPTGENRANDOM |
e56f956e | 46 | HCRYPTPROV hProvider; |
fa64e633 | 47 | # endif |
c16de9d8 DMSP |
48 | unsigned char *buffer; |
49 | size_t bytes_needed; | |
50 | size_t entropy_available = 0; | |
51 | ||
0f113f3e | 52 | |
8389ec4b | 53 | # ifdef OPENSSL_RAND_SEED_RDTSC |
c16de9d8 DMSP |
54 | entropy_available = rand_acquire_entropy_from_tsc(pool); |
55 | if (entropy_available > 0) | |
56 | return entropy_available; | |
8389ec4b | 57 | # endif |
c16de9d8 | 58 | |
8389ec4b | 59 | # ifdef OPENSSL_RAND_SEED_RDCPU |
c16de9d8 DMSP |
60 | entropy_available = rand_acquire_entropy_from_cpu(pool); |
61 | if (entropy_available > 0) | |
62 | return entropy_available; | |
8389ec4b RS |
63 | # endif |
64 | ||
65 | # ifdef USE_BCRYPTGENRANDOM | |
6ebb49f3 | 66 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 67 | buffer = rand_pool_add_begin(pool, bytes_needed); |
c16de9d8 DMSP |
68 | if (buffer != NULL) { |
69 | size_t bytes = 0; | |
70 | if (BCryptGenRandom(NULL, buffer, bytes_needed, | |
c2e33a05 | 71 | BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) |
c16de9d8 DMSP |
72 | bytes = bytes_needed; |
73 | ||
8e2bec9b RL |
74 | rand_pool_add_end(pool, bytes, 8 * bytes); |
75 | entropy_available = rand_pool_entropy_available(pool); | |
9ed79d8e | 76 | } |
c16de9d8 DMSP |
77 | if (entropy_available > 0) |
78 | return entropy_available; | |
fa64e633 | 79 | # else |
6ebb49f3 | 80 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 81 | buffer = rand_pool_add_begin(pool, bytes_needed); |
c16de9d8 DMSP |
82 | if (buffer != NULL) { |
83 | size_t bytes = 0; | |
84 | /* poll the CryptoAPI PRNG */ | |
85 | if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, | |
c2e33a05 | 86 | CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { |
c16de9d8 DMSP |
87 | if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) |
88 | bytes = bytes_needed; | |
89 | ||
90 | CryptReleaseContext(hProvider, 0); | |
0f113f3e | 91 | } |
c16de9d8 | 92 | |
8e2bec9b RL |
93 | rand_pool_add_end(pool, bytes, 8 * bytes); |
94 | entropy_available = rand_pool_entropy_available(pool); | |
0f113f3e | 95 | } |
c16de9d8 DMSP |
96 | if (entropy_available > 0) |
97 | return entropy_available; | |
98 | ||
6ebb49f3 | 99 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 100 | buffer = rand_pool_add_begin(pool, bytes_needed); |
c16de9d8 DMSP |
101 | if (buffer != NULL) { |
102 | size_t bytes = 0; | |
103 | /* poll the Pentium PRG with CryptoAPI */ | |
104 | if (CryptAcquireContextW(&hProvider, NULL, | |
105 | INTEL_DEF_PROV, PROV_INTEL_SEC, | |
106 | CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { | |
107 | if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) | |
108 | bytes = bytes_needed; | |
0f113f3e | 109 | |
c16de9d8 | 110 | CryptReleaseContext(hProvider, 0); |
0f113f3e | 111 | } |
8e2bec9b RL |
112 | rand_pool_add_end(pool, bytes, 8 * bytes); |
113 | entropy_available = rand_pool_entropy_available(pool); | |
0f113f3e | 114 | } |
c16de9d8 DMSP |
115 | if (entropy_available > 0) |
116 | return entropy_available; | |
fa64e633 | 117 | # endif |
0f113f3e | 118 | |
6decf943 | 119 | return rand_pool_entropy_available(pool); |
0f113f3e | 120 | } |
2ace287d | 121 | |
5bc6bcf8 DMSP |
122 | |
123 | int rand_pool_add_nonce_data(RAND_POOL *pool) | |
124 | { | |
125 | struct { | |
126 | DWORD pid; | |
127 | DWORD tid; | |
128 | FILETIME time; | |
678d2681 P |
129 | } data; |
130 | ||
131 | /* Erase the entire structure including any padding */ | |
132 | memset(&data, 0, sizeof(data)); | |
5bc6bcf8 DMSP |
133 | |
134 | /* | |
135 | * Add process id, thread id, and a high resolution timestamp to | |
136 | * ensure that the nonce is unique whith high probability for | |
137 | * different process instances. | |
138 | */ | |
139 | data.pid = GetCurrentProcessId(); | |
140 | data.tid = GetCurrentThreadId(); | |
141 | GetSystemTimeAsFileTime(&data.time); | |
142 | ||
143 | return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); | |
144 | } | |
145 | ||
146 | int rand_pool_add_additional_data(RAND_POOL *pool) | |
147 | { | |
148 | struct { | |
149 | DWORD tid; | |
150 | LARGE_INTEGER time; | |
678d2681 P |
151 | } data; |
152 | ||
153 | /* Erase the entire structure including any padding */ | |
154 | memset(&data, 0, sizeof(data)); | |
5bc6bcf8 DMSP |
155 | |
156 | /* | |
157 | * Add some noise from the thread id and a high resolution timer. | |
158 | * The thread id adds a little randomness if the drbg is accessed | |
159 | * concurrently (which is the case for the <master> drbg). | |
160 | */ | |
161 | data.tid = GetCurrentThreadId(); | |
162 | QueryPerformanceCounter(&data.time); | |
163 | return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); | |
164 | } | |
165 | ||
57ca171a | 166 | # if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE) |
73241290 JY |
167 | int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) |
168 | { | |
169 | RAND_poll(); | |
170 | return RAND_status(); | |
171 | } | |
172 | ||
173 | void RAND_screen(void) | |
174 | { | |
175 | RAND_poll(); | |
176 | } | |
9ed79d8e | 177 | # endif |
73241290 | 178 | |
c7504aeb P |
179 | int rand_pool_init(void) |
180 | { | |
181 | return 1; | |
182 | } | |
183 | ||
184 | void rand_pool_cleanup(void) | |
185 | { | |
186 | } | |
187 | ||
188 | void rand_pool_keep_random_devices_open(int keep) | |
189 | { | |
190 | } | |
191 | ||
2ace287d | 192 | #endif |