]>
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 DMSP |
21 | /* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */ |
22 | # if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 | |
8389ec4b | 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 | |
6ebb49f3 | 65 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 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, | |
c2e33a05 | 70 | BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) |
c16de9d8 DMSP |
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 |
6ebb49f3 | 79 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 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, | |
c2e33a05 | 85 | CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { |
c16de9d8 DMSP |
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 | ||
6ebb49f3 | 98 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 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 | |
5bc6bcf8 DMSP |
121 | |
122 | int rand_pool_add_nonce_data(RAND_POOL *pool) | |
123 | { | |
124 | struct { | |
125 | DWORD pid; | |
126 | DWORD tid; | |
127 | FILETIME time; | |
678d2681 P |
128 | } data; |
129 | ||
130 | /* Erase the entire structure including any padding */ | |
131 | memset(&data, 0, sizeof(data)); | |
5bc6bcf8 DMSP |
132 | |
133 | /* | |
134 | * Add process id, thread id, and a high resolution timestamp to | |
135 | * ensure that the nonce is unique whith high probability for | |
136 | * different process instances. | |
137 | */ | |
138 | data.pid = GetCurrentProcessId(); | |
139 | data.tid = GetCurrentThreadId(); | |
140 | GetSystemTimeAsFileTime(&data.time); | |
141 | ||
142 | return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); | |
143 | } | |
144 | ||
145 | int rand_pool_add_additional_data(RAND_POOL *pool) | |
146 | { | |
147 | struct { | |
148 | DWORD tid; | |
149 | LARGE_INTEGER time; | |
678d2681 P |
150 | } data; |
151 | ||
152 | /* Erase the entire structure including any padding */ | |
153 | memset(&data, 0, sizeof(data)); | |
5bc6bcf8 DMSP |
154 | |
155 | /* | |
156 | * Add some noise from the thread id and a high resolution timer. | |
157 | * The thread id adds a little randomness if the drbg is accessed | |
158 | * concurrently (which is the case for the <master> drbg). | |
159 | */ | |
160 | data.tid = GetCurrentThreadId(); | |
161 | QueryPerformanceCounter(&data.time); | |
162 | return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); | |
163 | } | |
164 | ||
fcd2d5a6 | 165 | # if !OPENSSL_API_1_1_0 |
73241290 JY |
166 | int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) |
167 | { | |
168 | RAND_poll(); | |
169 | return RAND_status(); | |
170 | } | |
171 | ||
172 | void RAND_screen(void) | |
173 | { | |
174 | RAND_poll(); | |
175 | } | |
9ed79d8e | 176 | # endif |
73241290 | 177 | |
c7504aeb P |
178 | int rand_pool_init(void) |
179 | { | |
180 | return 1; | |
181 | } | |
182 | ||
183 | void rand_pool_cleanup(void) | |
184 | { | |
185 | } | |
186 | ||
187 | void rand_pool_keep_random_devices_open(int keep) | |
188 | { | |
189 | } | |
190 | ||
2ace287d | 191 | #endif |