]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
f61f62ea | 2 | * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. |
dfeab068 | 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 | |
dfeab068 RE |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
dfeab068 | 11 | #include <time.h> |
b39fc560 | 12 | #include "internal/cryptlib.h" |
98186eb4 | 13 | #include <openssl/opensslconf.h> |
25f2138b | 14 | #include "crypto/rand.h" |
3c27208f | 15 | #include <openssl/engine.h> |
87975cfa | 16 | #include "internal/thread_once.h" |
706457b7 | 17 | #include "rand_local.h" |
20928ff6 | 18 | #include "e_os.h" |
dfeab068 | 19 | |
a2f27fd7 MC |
20 | #ifndef FIPS_MODE |
21 | # ifndef OPENSSL_NO_ENGINE | |
cb78486d | 22 | /* non-NULL if default_RAND_meth is ENGINE-provided */ |
da8fc25a RS |
23 | static ENGINE *funct_ref; |
24 | static CRYPTO_RWLOCK *rand_engine_lock; | |
a2f27fd7 | 25 | # endif |
da8fc25a RS |
26 | static CRYPTO_RWLOCK *rand_meth_lock; |
27 | static const RAND_METHOD *default_RAND_meth; | |
28 | static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; | |
c16de9d8 | 29 | |
e2d227bb | 30 | static int rand_inited = 0; |
a2f27fd7 MC |
31 | #endif /* FIPS_MODE */ |
32 | ||
8389ec4b RS |
33 | #ifdef OPENSSL_RAND_SEED_RDTSC |
34 | /* | |
35 | * IMPORTANT NOTE: It is not currently possible to use this code | |
9ed79d8e RS |
36 | * because we are not sure about the amount of randomness it provides. |
37 | * Some SP900 tests have been run, but there is internal skepticism. | |
8389ec4b RS |
38 | * So for now this code is not used. |
39 | */ | |
40 | # error "RDTSC enabled? Should not be possible!" | |
41 | ||
42 | /* | |
c16de9d8 DMSP |
43 | * Acquire entropy from high-speed clock |
44 | * | |
8389ec4b | 45 | * Since we get some randomness from the low-order bits of the |
c16de9d8 DMSP |
46 | * high-speed clock, it can help. |
47 | * | |
48 | * Returns the total entropy count, if it exceeds the requested | |
49 | * entropy count. Otherwise, returns an entropy count of 0. | |
8389ec4b | 50 | */ |
c16de9d8 | 51 | size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool) |
8389ec4b RS |
52 | { |
53 | unsigned char c; | |
54 | int i; | |
55 | ||
9ed79d8e RS |
56 | if ((OPENSSL_ia32cap_P[0] & (1 << 4)) != 0) { |
57 | for (i = 0; i < TSC_READ_COUNT; i++) { | |
58 | c = (unsigned char)(OPENSSL_rdtsc() & 0xFF); | |
6decf943 | 59 | rand_pool_add(pool, &c, 1, 4); |
9ed79d8e | 60 | } |
8389ec4b | 61 | } |
6decf943 | 62 | return rand_pool_entropy_available(pool); |
8389ec4b RS |
63 | } |
64 | #endif | |
65 | ||
66 | #ifdef OPENSSL_RAND_SEED_RDCPU | |
c16de9d8 DMSP |
67 | size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len); |
68 | size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len); | |
8389ec4b | 69 | |
c16de9d8 DMSP |
70 | /* |
71 | * Acquire entropy using Intel-specific cpu instructions | |
72 | * | |
73 | * Uses the RDSEED instruction if available, otherwise uses | |
74 | * RDRAND if available. | |
75 | * | |
76 | * For the differences between RDSEED and RDRAND, and why RDSEED | |
77 | * is the preferred choice, see https://goo.gl/oK3KcN | |
78 | * | |
79 | * Returns the total entropy count, if it exceeds the requested | |
80 | * entropy count. Otherwise, returns an entropy count of 0. | |
81 | */ | |
82 | size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool) | |
8389ec4b | 83 | { |
c16de9d8 DMSP |
84 | size_t bytes_needed; |
85 | unsigned char *buffer; | |
86 | ||
6ebb49f3 | 87 | bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
c16de9d8 | 88 | if (bytes_needed > 0) { |
6decf943 | 89 | buffer = rand_pool_add_begin(pool, bytes_needed); |
c16de9d8 DMSP |
90 | |
91 | if (buffer != NULL) { | |
8e2bec9b | 92 | /* Whichever comes first, use RDSEED, RDRAND or nothing */ |
c16de9d8 DMSP |
93 | if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) { |
94 | if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed) | |
8e2bec9b RL |
95 | == bytes_needed) { |
96 | rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); | |
97 | } | |
98 | } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) { | |
c16de9d8 | 99 | if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed) |
8e2bec9b RL |
100 | == bytes_needed) { |
101 | rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); | |
102 | } | |
103 | } else { | |
104 | rand_pool_add_end(pool, 0, 0); | |
c16de9d8 | 105 | } |
9ed79d8e | 106 | } |
8389ec4b RS |
107 | } |
108 | ||
6decf943 | 109 | return rand_pool_entropy_available(pool); |
8389ec4b RS |
110 | } |
111 | #endif | |
da8fc25a | 112 | |
75e2c877 RS |
113 | |
114 | /* | |
c16de9d8 DMSP |
115 | * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks()) |
116 | * | |
117 | * If the DRBG has a parent, then the required amount of entropy input | |
118 | * is fetched using the parent's RAND_DRBG_generate(). | |
75e2c877 | 119 | * |
c16de9d8 | 120 | * Otherwise, the entropy is polled from the system entropy sources |
6decf943 | 121 | * using rand_pool_acquire_entropy(). |
c16de9d8 DMSP |
122 | * |
123 | * If a random pool has been added to the DRBG using RAND_add(), then | |
124 | * its entropy will be used up first. | |
75e2c877 | 125 | */ |
c16de9d8 | 126 | size_t rand_drbg_get_entropy(RAND_DRBG *drbg, |
eb238134 KR |
127 | unsigned char **pout, |
128 | int entropy, size_t min_len, size_t max_len, | |
129 | int prediction_resistance) | |
75e2c877 | 130 | { |
c16de9d8 DMSP |
131 | size_t ret = 0; |
132 | size_t entropy_available = 0; | |
35503b7c KR |
133 | RAND_POOL *pool; |
134 | ||
b3d113ed | 135 | if (drbg->parent != NULL && drbg->strength > drbg->parent->strength) { |
35503b7c KR |
136 | /* |
137 | * We currently don't support the algorithm from NIST SP 800-90C | |
138 | * 10.1.2 to use a weaker DRBG as source | |
139 | */ | |
140 | RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY, RAND_R_PARENT_STRENGTH_TOO_WEAK); | |
141 | return 0; | |
142 | } | |
75e2c877 | 143 | |
31f32abb BE |
144 | if (drbg->seed_pool != NULL) { |
145 | pool = drbg->seed_pool; | |
3064b551 DMSP |
146 | pool->entropy_requested = entropy; |
147 | } else { | |
1372560f | 148 | pool = rand_pool_new(entropy, drbg->secure, min_len, max_len); |
21311777 BE |
149 | if (pool == NULL) |
150 | return 0; | |
75e2c877 RS |
151 | } |
152 | ||
b3d113ed | 153 | if (drbg->parent != NULL) { |
6ebb49f3 | 154 | size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); |
6decf943 | 155 | unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed); |
9d951a78 | 156 | |
c16de9d8 DMSP |
157 | if (buffer != NULL) { |
158 | size_t bytes = 0; | |
75e2c877 | 159 | |
2139145b | 160 | /* |
0768b38b DMSP |
161 | * Get random data from parent. Include our address as additional input, |
162 | * in order to provide some additional distinction between different | |
163 | * DRBG child instances. | |
2139145b | 164 | * Our lock is already held, but we need to lock our parent before |
3ce1c27b DMSP |
165 | * generating bits from it. (Note: taking the lock will be a no-op |
166 | * if locking if drbg->parent->lock == NULL.) | |
2139145b | 167 | */ |
812b1537 | 168 | rand_drbg_lock(drbg->parent); |
c16de9d8 DMSP |
169 | if (RAND_DRBG_generate(drbg->parent, |
170 | buffer, bytes_needed, | |
311276ff | 171 | prediction_resistance, |
0768b38b | 172 | (unsigned char *)&drbg, sizeof(drbg)) != 0) |
c16de9d8 | 173 | bytes = bytes_needed; |
a83dc59a BE |
174 | drbg->reseed_next_counter |
175 | = tsan_load(&drbg->parent->reseed_prop_counter); | |
812b1537 | 176 | rand_drbg_unlock(drbg->parent); |
75e2c877 | 177 | |
8e2bec9b RL |
178 | rand_pool_add_end(pool, bytes, 8 * bytes); |
179 | entropy_available = rand_pool_entropy_available(pool); | |
c16de9d8 | 180 | } |
0b14a5b7 | 181 | |
c16de9d8 DMSP |
182 | } else { |
183 | /* Get entropy by polling system entropy sources. */ | |
6decf943 | 184 | entropy_available = rand_pool_acquire_entropy(pool); |
75e2c877 RS |
185 | } |
186 | ||
c16de9d8 | 187 | if (entropy_available > 0) { |
6decf943 DMSP |
188 | ret = rand_pool_length(pool); |
189 | *pout = rand_pool_detach(pool); | |
6969a3f4 | 190 | } |
c16de9d8 | 191 | |
31f32abb | 192 | if (drbg->seed_pool == NULL) |
f9e43929 | 193 | rand_pool_free(pool); |
c16de9d8 | 194 | return ret; |
75e2c877 RS |
195 | } |
196 | ||
2b66fd57 | 197 | /* |
5bc6bcf8 | 198 | * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks()) |
60595292 | 199 | * |
2b66fd57 | 200 | */ |
5bc6bcf8 DMSP |
201 | void rand_drbg_cleanup_entropy(RAND_DRBG *drbg, |
202 | unsigned char *out, size_t outlen) | |
2b66fd57 | 203 | { |
1372560f BE |
204 | if (drbg->seed_pool == NULL) { |
205 | if (drbg->secure) | |
206 | OPENSSL_secure_clear_free(out, outlen); | |
207 | else | |
208 | OPENSSL_clear_free(out, outlen); | |
209 | } | |
5bc6bcf8 DMSP |
210 | } |
211 | ||
20928ff6 KR |
212 | /* |
213 | * Generate additional data that can be used for the drbg. The data does | |
214 | * not need to contain entropy, but it's useful if it contains at least | |
215 | * some bits that are unpredictable. | |
216 | * | |
217 | * Returns 0 on failure. | |
218 | * | |
219 | * On success it allocates a buffer at |*pout| and returns the length of | |
220 | * the data. The buffer should get freed using OPENSSL_secure_clear_free(). | |
221 | */ | |
54f3e855 | 222 | size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout) |
20928ff6 | 223 | { |
5bc6bcf8 | 224 | size_t ret = 0; |
20928ff6 | 225 | |
5bc6bcf8 DMSP |
226 | if (rand_pool_add_additional_data(pool) == 0) |
227 | goto err; | |
20928ff6 | 228 | |
5bc6bcf8 DMSP |
229 | ret = rand_pool_length(pool); |
230 | *pout = rand_pool_detach(pool); | |
20928ff6 | 231 | |
5bc6bcf8 | 232 | err: |
5bc6bcf8 | 233 | return ret; |
20928ff6 | 234 | } |
c16de9d8 | 235 | |
54f3e855 | 236 | void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out) |
75e2c877 | 237 | { |
54f3e855 | 238 | rand_pool_reattach(pool, out); |
ddc6a5c8 RS |
239 | } |
240 | ||
a2f27fd7 | 241 | #ifndef FIPS_MODE |
da8fc25a | 242 | DEFINE_RUN_ONCE_STATIC(do_rand_init) |
87975cfa | 243 | { |
a2f27fd7 | 244 | # ifndef OPENSSL_NO_ENGINE |
63ab5ea1 | 245 | rand_engine_lock = CRYPTO_THREAD_lock_new(); |
0e5c1a66 BE |
246 | if (rand_engine_lock == NULL) |
247 | return 0; | |
a2f27fd7 | 248 | # endif |
0e5c1a66 | 249 | |
63ab5ea1 | 250 | rand_meth_lock = CRYPTO_THREAD_lock_new(); |
0e5c1a66 | 251 | if (rand_meth_lock == NULL) |
a2f27fd7 | 252 | goto err; |
5bc6bcf8 | 253 | |
e2d227bb | 254 | if (!rand_pool_init()) |
a2f27fd7 | 255 | goto err; |
c7504aeb | 256 | |
e2d227bb | 257 | rand_inited = 1; |
0e5c1a66 BE |
258 | return 1; |
259 | ||
a2f27fd7 | 260 | err: |
0e5c1a66 BE |
261 | CRYPTO_THREAD_lock_free(rand_meth_lock); |
262 | rand_meth_lock = NULL; | |
a2f27fd7 | 263 | # ifndef OPENSSL_NO_ENGINE |
0e5c1a66 BE |
264 | CRYPTO_THREAD_lock_free(rand_engine_lock); |
265 | rand_engine_lock = NULL; | |
a2f27fd7 | 266 | # endif |
0e5c1a66 | 267 | return 0; |
87975cfa | 268 | } |
dfeab068 | 269 | |
da8fc25a RS |
270 | void rand_cleanup_int(void) |
271 | { | |
272 | const RAND_METHOD *meth = default_RAND_meth; | |
273 | ||
e2d227bb BE |
274 | if (!rand_inited) |
275 | return; | |
bc420ebe | 276 | |
da8fc25a RS |
277 | if (meth != NULL && meth->cleanup != NULL) |
278 | meth->cleanup(); | |
279 | RAND_set_rand_method(NULL); | |
bc420ebe | 280 | rand_pool_cleanup(); |
a2f27fd7 | 281 | # ifndef OPENSSL_NO_ENGINE |
da8fc25a | 282 | CRYPTO_THREAD_lock_free(rand_engine_lock); |
0e5c1a66 | 283 | rand_engine_lock = NULL; |
a2f27fd7 | 284 | # endif |
da8fc25a | 285 | CRYPTO_THREAD_lock_free(rand_meth_lock); |
0e5c1a66 | 286 | rand_meth_lock = NULL; |
e2d227bb | 287 | rand_inited = 0; |
75e2c877 RS |
288 | } |
289 | ||
a2f27fd7 | 290 | /* TODO(3.0): Do we need to handle this somehow in the FIPS module? */ |
c7504aeb | 291 | /* |
c2969ff6 | 292 | * RAND_close_seed_files() ensures that any seed file descriptors are |
c7504aeb P |
293 | * closed after use. |
294 | */ | |
295 | void RAND_keep_random_devices_open(int keep) | |
296 | { | |
ac765685 P |
297 | if (RUN_ONCE(&rand_init, do_rand_init)) |
298 | rand_pool_keep_random_devices_open(keep); | |
c7504aeb P |
299 | } |
300 | ||
75e2c877 | 301 | /* |
c16de9d8 DMSP |
302 | * RAND_poll() reseeds the default RNG using random input |
303 | * | |
304 | * The random input is obtained from polling various entropy | |
305 | * sources which depend on the operating system and are | |
306 | * configurable via the --with-rand-seed configure option. | |
307 | */ | |
308 | int RAND_poll(void) | |
309 | { | |
310 | int ret = 0; | |
311 | ||
c16de9d8 DMSP |
312 | const RAND_METHOD *meth = RAND_get_rand_method(); |
313 | ||
0402c90f DMSP |
314 | if (meth == NULL) |
315 | return 0; | |
316 | ||
c16de9d8 | 317 | if (meth == RAND_OpenSSL()) { |
a93ba405 DMSP |
318 | /* fill random pool and seed the master DRBG */ |
319 | RAND_DRBG *drbg = RAND_DRBG_get0_master(); | |
c16de9d8 DMSP |
320 | |
321 | if (drbg == NULL) | |
322 | return 0; | |
323 | ||
812b1537 | 324 | rand_drbg_lock(drbg); |
c16de9d8 | 325 | ret = rand_drbg_restart(drbg, NULL, 0, 0); |
812b1537 | 326 | rand_drbg_unlock(drbg); |
c16de9d8 DMSP |
327 | |
328 | return ret; | |
329 | ||
330 | } else { | |
a2f27fd7 MC |
331 | RAND_POOL *pool = NULL; |
332 | ||
c16de9d8 | 333 | /* fill random pool and seed the current legacy RNG */ |
1372560f | 334 | pool = rand_pool_new(RAND_DRBG_STRENGTH, 1, |
b3d113ed | 335 | (RAND_DRBG_STRENGTH + 7) / 8, |
3064b551 | 336 | RAND_POOL_MAX_LENGTH); |
c16de9d8 DMSP |
337 | if (pool == NULL) |
338 | return 0; | |
339 | ||
6decf943 | 340 | if (rand_pool_acquire_entropy(pool) == 0) |
c16de9d8 DMSP |
341 | goto err; |
342 | ||
343 | if (meth->add == NULL | |
6decf943 DMSP |
344 | || meth->add(rand_pool_buffer(pool), |
345 | rand_pool_length(pool), | |
346 | (rand_pool_entropy(pool) / 8.0)) == 0) | |
c16de9d8 DMSP |
347 | goto err; |
348 | ||
349 | ret = 1; | |
a2f27fd7 MC |
350 | |
351 | err: | |
352 | rand_pool_free(pool); | |
c16de9d8 DMSP |
353 | } |
354 | ||
c16de9d8 DMSP |
355 | return ret; |
356 | } | |
a2f27fd7 | 357 | #endif /* FIPS_MODE */ |
c16de9d8 | 358 | |
c16de9d8 DMSP |
359 | /* |
360 | * Allocate memory and initialize a new random pool | |
361 | */ | |
362 | ||
1372560f BE |
363 | RAND_POOL *rand_pool_new(int entropy_requested, int secure, |
364 | size_t min_len, size_t max_len) | |
75e2c877 | 365 | { |
c16de9d8 | 366 | RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); |
a6a66e45 | 367 | size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure); |
c16de9d8 DMSP |
368 | |
369 | if (pool == NULL) { | |
370 | RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); | |
3064b551 | 371 | return NULL; |
c16de9d8 DMSP |
372 | } |
373 | ||
374 | pool->min_len = min_len; | |
3064b551 DMSP |
375 | pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ? |
376 | RAND_POOL_MAX_LENGTH : max_len; | |
a6a66e45 P |
377 | pool->alloc_len = min_len < min_alloc_size ? min_alloc_size : min_len; |
378 | if (pool->alloc_len > pool->max_len) | |
379 | pool->alloc_len = pool->max_len; | |
c16de9d8 | 380 | |
1372560f | 381 | if (secure) |
a6a66e45 | 382 | pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len); |
1372560f | 383 | else |
a6a66e45 | 384 | pool->buffer = OPENSSL_zalloc(pool->alloc_len); |
1372560f | 385 | |
c16de9d8 DMSP |
386 | if (pool->buffer == NULL) { |
387 | RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); | |
388 | goto err; | |
389 | } | |
390 | ||
3064b551 | 391 | pool->entropy_requested = entropy_requested; |
1372560f | 392 | pool->secure = secure; |
c16de9d8 DMSP |
393 | |
394 | return pool; | |
395 | ||
396 | err: | |
397 | OPENSSL_free(pool); | |
398 | return NULL; | |
75e2c877 RS |
399 | } |
400 | ||
3064b551 DMSP |
401 | /* |
402 | * Attach new random pool to the given buffer | |
403 | * | |
404 | * This function is intended to be used only for feeding random data | |
405 | * provided by RAND_add() and RAND_seed() into the <master> DRBG. | |
406 | */ | |
407 | RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, | |
408 | size_t entropy) | |
409 | { | |
410 | RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); | |
411 | ||
412 | if (pool == NULL) { | |
413 | RANDerr(RAND_F_RAND_POOL_ATTACH, ERR_R_MALLOC_FAILURE); | |
414 | return NULL; | |
415 | } | |
416 | ||
417 | /* | |
418 | * The const needs to be cast away, but attached buffers will not be | |
419 | * modified (in contrary to allocated buffers which are zeroed and | |
420 | * freed in the end). | |
421 | */ | |
422 | pool->buffer = (unsigned char *) buffer; | |
423 | pool->len = len; | |
424 | ||
425 | pool->attached = 1; | |
426 | ||
a6a66e45 | 427 | pool->min_len = pool->max_len = pool->alloc_len = pool->len; |
3064b551 DMSP |
428 | pool->entropy = entropy; |
429 | ||
430 | return pool; | |
431 | } | |
432 | ||
c16de9d8 DMSP |
433 | /* |
434 | * Free |pool|, securely erasing its buffer. | |
435 | */ | |
6decf943 | 436 | void rand_pool_free(RAND_POOL *pool) |
c16de9d8 DMSP |
437 | { |
438 | if (pool == NULL) | |
439 | return; | |
440 | ||
3064b551 DMSP |
441 | /* |
442 | * Although it would be advisable from a cryptographical viewpoint, | |
443 | * we are not allowed to clear attached buffers, since they are passed | |
444 | * to rand_pool_attach() as `const unsigned char*`. | |
445 | * (see corresponding comment in rand_pool_attach()). | |
446 | */ | |
1372560f BE |
447 | if (!pool->attached) { |
448 | if (pool->secure) | |
a6a66e45 | 449 | OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); |
1372560f | 450 | else |
a6a66e45 | 451 | OPENSSL_clear_free(pool->buffer, pool->alloc_len); |
1372560f BE |
452 | } |
453 | ||
c16de9d8 DMSP |
454 | OPENSSL_free(pool); |
455 | } | |
456 | ||
457 | /* | |
458 | * Return the |pool|'s buffer to the caller (readonly). | |
459 | */ | |
6decf943 | 460 | const unsigned char *rand_pool_buffer(RAND_POOL *pool) |
c16de9d8 DMSP |
461 | { |
462 | return pool->buffer; | |
463 | } | |
464 | ||
465 | /* | |
466 | * Return the |pool|'s entropy to the caller. | |
467 | */ | |
6decf943 | 468 | size_t rand_pool_entropy(RAND_POOL *pool) |
c16de9d8 DMSP |
469 | { |
470 | return pool->entropy; | |
471 | } | |
472 | ||
473 | /* | |
474 | * Return the |pool|'s buffer length to the caller. | |
475 | */ | |
6decf943 | 476 | size_t rand_pool_length(RAND_POOL *pool) |
c16de9d8 DMSP |
477 | { |
478 | return pool->len; | |
479 | } | |
480 | ||
481 | /* | |
482 | * Detach the |pool| buffer and return it to the caller. | |
483 | * It's the responsibility of the caller to free the buffer | |
54f3e855 BE |
484 | * using OPENSSL_secure_clear_free() or to re-attach it |
485 | * again to the pool using rand_pool_reattach(). | |
c16de9d8 | 486 | */ |
6decf943 | 487 | unsigned char *rand_pool_detach(RAND_POOL *pool) |
c16de9d8 DMSP |
488 | { |
489 | unsigned char *ret = pool->buffer; | |
490 | pool->buffer = NULL; | |
f9e43929 | 491 | pool->entropy = 0; |
c16de9d8 DMSP |
492 | return ret; |
493 | } | |
494 | ||
54f3e855 BE |
495 | /* |
496 | * Re-attach the |pool| buffer. It is only allowed to pass | |
497 | * the |buffer| which was previously detached from the same pool. | |
498 | */ | |
499 | void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer) | |
500 | { | |
501 | pool->buffer = buffer; | |
502 | OPENSSL_cleanse(pool->buffer, pool->len); | |
503 | pool->len = 0; | |
504 | } | |
c16de9d8 DMSP |
505 | |
506 | /* | |
6ebb49f3 RL |
507 | * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one |
508 | * need to obtain at least |bits| bits of entropy? | |
c16de9d8 | 509 | */ |
6ebb49f3 RL |
510 | #define ENTROPY_TO_BYTES(bits, entropy_factor) \ |
511 | (((bits) * (entropy_factor) + 7) / 8) | |
c16de9d8 DMSP |
512 | |
513 | ||
514 | /* | |
515 | * Checks whether the |pool|'s entropy is available to the caller. | |
516 | * This is the case when entropy count and buffer length are high enough. | |
517 | * Returns | |
518 | * | |
519 | * |entropy| if the entropy count and buffer size is large enough | |
520 | * 0 otherwise | |
521 | */ | |
6decf943 | 522 | size_t rand_pool_entropy_available(RAND_POOL *pool) |
c16de9d8 | 523 | { |
3064b551 | 524 | if (pool->entropy < pool->entropy_requested) |
c16de9d8 DMSP |
525 | return 0; |
526 | ||
527 | if (pool->len < pool->min_len) | |
528 | return 0; | |
529 | ||
530 | return pool->entropy; | |
531 | } | |
532 | ||
533 | /* | |
534 | * Returns the (remaining) amount of entropy needed to fill | |
535 | * the random pool. | |
536 | */ | |
537 | ||
6decf943 | 538 | size_t rand_pool_entropy_needed(RAND_POOL *pool) |
c16de9d8 | 539 | { |
3064b551 DMSP |
540 | if (pool->entropy < pool->entropy_requested) |
541 | return pool->entropy_requested - pool->entropy; | |
c16de9d8 DMSP |
542 | |
543 | return 0; | |
544 | } | |
545 | ||
fa3eb248 BE |
546 | /* Increase the allocation size -- not usable for an attached pool */ |
547 | static int rand_pool_grow(RAND_POOL *pool, size_t len) | |
548 | { | |
549 | if (len > pool->alloc_len - pool->len) { | |
550 | unsigned char *p; | |
551 | const size_t limit = pool->max_len / 2; | |
552 | size_t newlen = pool->alloc_len; | |
553 | ||
554 | if (pool->attached || len > pool->max_len - pool->len) { | |
555 | RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_INTERNAL_ERROR); | |
556 | return 0; | |
557 | } | |
558 | ||
559 | do | |
560 | newlen = newlen < limit ? newlen * 2 : pool->max_len; | |
561 | while (len > newlen - pool->len); | |
562 | ||
563 | if (pool->secure) | |
564 | p = OPENSSL_secure_zalloc(newlen); | |
565 | else | |
566 | p = OPENSSL_zalloc(newlen); | |
567 | if (p == NULL) { | |
568 | RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_MALLOC_FAILURE); | |
569 | return 0; | |
570 | } | |
571 | memcpy(p, pool->buffer, pool->len); | |
572 | if (pool->secure) | |
573 | OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); | |
574 | else | |
575 | OPENSSL_clear_free(pool->buffer, pool->alloc_len); | |
576 | pool->buffer = p; | |
577 | pool->alloc_len = newlen; | |
578 | } | |
579 | return 1; | |
580 | } | |
581 | ||
c16de9d8 DMSP |
582 | /* |
583 | * Returns the number of bytes needed to fill the pool, assuming | |
6ebb49f3 | 584 | * the input has 1 / |entropy_factor| entropy bits per data bit. |
c16de9d8 DMSP |
585 | * In case of an error, 0 is returned. |
586 | */ | |
587 | ||
6ebb49f3 | 588 | size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor) |
c16de9d8 DMSP |
589 | { |
590 | size_t bytes_needed; | |
6decf943 | 591 | size_t entropy_needed = rand_pool_entropy_needed(pool); |
c16de9d8 | 592 | |
6ebb49f3 | 593 | if (entropy_factor < 1) { |
c16de9d8 DMSP |
594 | RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_ARGUMENT_OUT_OF_RANGE); |
595 | return 0; | |
596 | } | |
597 | ||
6ebb49f3 | 598 | bytes_needed = ENTROPY_TO_BYTES(entropy_needed, entropy_factor); |
c16de9d8 DMSP |
599 | |
600 | if (bytes_needed > pool->max_len - pool->len) { | |
601 | /* not enough space left */ | |
602 | RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_RANDOM_POOL_OVERFLOW); | |
603 | return 0; | |
604 | } | |
605 | ||
606 | if (pool->len < pool->min_len && | |
607 | bytes_needed < pool->min_len - pool->len) | |
608 | /* to meet the min_len requirement */ | |
609 | bytes_needed = pool->min_len - pool->len; | |
610 | ||
fa3eb248 BE |
611 | /* |
612 | * Make sure the buffer is large enough for the requested amount | |
613 | * of data. This guarantees that existing code patterns where | |
614 | * rand_pool_add_begin, rand_pool_add_end or rand_pool_add | |
615 | * are used to collect entropy data without any error handling | |
616 | * whatsoever, continue to be valid. | |
617 | * Furthermore if the allocation here fails once, make sure that | |
618 | * we don't fall back to a less secure or even blocking random source, | |
619 | * as that could happen by the existing code patterns. | |
620 | * This is not a concern for additional data, therefore that | |
621 | * is not needed if rand_pool_grow fails in other places. | |
622 | */ | |
623 | if (!rand_pool_grow(pool, bytes_needed)) { | |
624 | /* persistent error for this pool */ | |
625 | pool->max_len = pool->len = 0; | |
626 | return 0; | |
627 | } | |
628 | ||
c16de9d8 DMSP |
629 | return bytes_needed; |
630 | } | |
631 | ||
632 | /* Returns the remaining number of bytes available */ | |
6decf943 | 633 | size_t rand_pool_bytes_remaining(RAND_POOL *pool) |
75e2c877 | 634 | { |
c16de9d8 DMSP |
635 | return pool->max_len - pool->len; |
636 | } | |
637 | ||
638 | /* | |
639 | * Add random bytes to the random pool. | |
640 | * | |
641 | * It is expected that the |buffer| contains |len| bytes of | |
642 | * random input which contains at least |entropy| bits of | |
643 | * randomness. | |
644 | * | |
8e2bec9b | 645 | * Returns 1 if the added amount is adequate, otherwise 0 |
c16de9d8 | 646 | */ |
8e2bec9b RL |
647 | int rand_pool_add(RAND_POOL *pool, |
648 | const unsigned char *buffer, size_t len, size_t entropy) | |
c16de9d8 DMSP |
649 | { |
650 | if (len > pool->max_len - pool->len) { | |
651 | RANDerr(RAND_F_RAND_POOL_ADD, RAND_R_ENTROPY_INPUT_TOO_LONG); | |
652 | return 0; | |
653 | } | |
654 | ||
54f3e855 BE |
655 | if (pool->buffer == NULL) { |
656 | RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR); | |
657 | return 0; | |
658 | } | |
659 | ||
c16de9d8 | 660 | if (len > 0) { |
fa3eb248 BE |
661 | /* |
662 | * This is to protect us from accidentally passing the buffer | |
663 | * returned from rand_pool_add_begin. | |
664 | * The check for alloc_len makes sure we do not compare the | |
665 | * address of the end of the allocated memory to something | |
666 | * different, since that comparison would have an | |
667 | * indeterminate result. | |
668 | */ | |
669 | if (pool->alloc_len > pool->len && pool->buffer + pool->len == buffer) { | |
670 | RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR); | |
671 | return 0; | |
672 | } | |
673 | /* | |
674 | * We have that only for cases when a pool is used to collect | |
675 | * additional data. | |
676 | * For entropy data, as long as the allocation request stays within | |
677 | * the limits given by rand_pool_bytes_needed this rand_pool_grow | |
678 | * below is guaranteed to succeed, thus no allocation happens. | |
679 | */ | |
a6a66e45 P |
680 | if (!rand_pool_grow(pool, len)) |
681 | return 0; | |
c16de9d8 DMSP |
682 | memcpy(pool->buffer + pool->len, buffer, len); |
683 | pool->len += len; | |
684 | pool->entropy += entropy; | |
685 | } | |
686 | ||
8e2bec9b | 687 | return 1; |
c16de9d8 DMSP |
688 | } |
689 | ||
690 | /* | |
691 | * Start to add random bytes to the random pool in-place. | |
692 | * | |
693 | * Reserves the next |len| bytes for adding random bytes in-place | |
694 | * and returns a pointer to the buffer. | |
695 | * The caller is allowed to copy up to |len| bytes into the buffer. | |
696 | * If |len| == 0 this is considered a no-op and a NULL pointer | |
697 | * is returned without producing an error message. | |
698 | * | |
6decf943 | 699 | * After updating the buffer, rand_pool_add_end() needs to be called |
7fa8bcfe | 700 | * to finish the update operation (see next comment). |
c16de9d8 | 701 | */ |
6decf943 | 702 | unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len) |
c16de9d8 DMSP |
703 | { |
704 | if (len == 0) | |
705 | return NULL; | |
706 | ||
707 | if (len > pool->max_len - pool->len) { | |
708 | RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, RAND_R_RANDOM_POOL_OVERFLOW); | |
709 | return NULL; | |
710 | } | |
711 | ||
54f3e855 BE |
712 | if (pool->buffer == NULL) { |
713 | RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR); | |
b3d113ed | 714 | return NULL; |
54f3e855 BE |
715 | } |
716 | ||
fa3eb248 BE |
717 | /* |
718 | * As long as the allocation request stays within the limits given | |
719 | * by rand_pool_bytes_needed this rand_pool_grow below is guaranteed | |
720 | * to succeed, thus no allocation happens. | |
721 | * We have that only for cases when a pool is used to collect | |
722 | * additional data. Then the buffer might need to grow here, | |
723 | * and of course the caller is responsible to check the return | |
724 | * value of this function. | |
725 | */ | |
a6a66e45 P |
726 | if (!rand_pool_grow(pool, len)) |
727 | return NULL; | |
fa3eb248 | 728 | |
c16de9d8 DMSP |
729 | return pool->buffer + pool->len; |
730 | } | |
731 | ||
732 | /* | |
733 | * Finish to add random bytes to the random pool in-place. | |
734 | * | |
735 | * Finishes an in-place update of the random pool started by | |
6decf943 | 736 | * rand_pool_add_begin() (see previous comment). |
c16de9d8 DMSP |
737 | * It is expected that |len| bytes of random input have been added |
738 | * to the buffer which contain at least |entropy| bits of randomness. | |
739 | * It is allowed to add less bytes than originally reserved. | |
740 | */ | |
8e2bec9b | 741 | int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy) |
c16de9d8 | 742 | { |
fa3eb248 | 743 | if (len > pool->alloc_len - pool->len) { |
c16de9d8 DMSP |
744 | RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW); |
745 | return 0; | |
746 | } | |
747 | ||
748 | if (len > 0) { | |
749 | pool->len += len; | |
750 | pool->entropy += entropy; | |
751 | } | |
752 | ||
8e2bec9b | 753 | return 1; |
da8fc25a RS |
754 | } |
755 | ||
a2f27fd7 | 756 | #ifndef FIPS_MODE |
cb78486d | 757 | int RAND_set_rand_method(const RAND_METHOD *meth) |
0f113f3e | 758 | { |
da8fc25a | 759 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
760 | return 0; |
761 | ||
762 | CRYPTO_THREAD_write_lock(rand_meth_lock); | |
a2f27fd7 | 763 | # ifndef OPENSSL_NO_ENGINE |
7c96dbcd RS |
764 | ENGINE_finish(funct_ref); |
765 | funct_ref = NULL; | |
a2f27fd7 | 766 | # endif |
0f113f3e | 767 | default_RAND_meth = meth; |
87975cfa | 768 | CRYPTO_THREAD_unlock(rand_meth_lock); |
0f113f3e MC |
769 | return 1; |
770 | } | |
a2f27fd7 | 771 | #endif |
dfeab068 | 772 | |
a4a9d97a | 773 | const RAND_METHOD *RAND_get_rand_method(void) |
0f113f3e | 774 | { |
a2f27fd7 MC |
775 | #ifdef FIPS_MODE |
776 | return NULL; | |
777 | #else | |
87975cfa RL |
778 | const RAND_METHOD *tmp_meth = NULL; |
779 | ||
da8fc25a | 780 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
781 | return NULL; |
782 | ||
783 | CRYPTO_THREAD_write_lock(rand_meth_lock); | |
da8fc25a | 784 | if (default_RAND_meth == NULL) { |
a2f27fd7 | 785 | # ifndef OPENSSL_NO_ENGINE |
da8fc25a RS |
786 | ENGINE *e; |
787 | ||
788 | /* If we have an engine that can do RAND, use it. */ | |
789 | if ((e = ENGINE_get_default_RAND()) != NULL | |
790 | && (tmp_meth = ENGINE_get_RAND(e)) != NULL) { | |
0f113f3e | 791 | funct_ref = e; |
da8fc25a RS |
792 | default_RAND_meth = tmp_meth; |
793 | } else { | |
794 | ENGINE_finish(e); | |
75e2c877 | 795 | default_RAND_meth = &rand_meth; |
da8fc25a | 796 | } |
a2f27fd7 | 797 | # else |
75e2c877 | 798 | default_RAND_meth = &rand_meth; |
a2f27fd7 | 799 | # endif |
0f113f3e | 800 | } |
87975cfa RL |
801 | tmp_meth = default_RAND_meth; |
802 | CRYPTO_THREAD_unlock(rand_meth_lock); | |
803 | return tmp_meth; | |
a2f27fd7 | 804 | #endif |
0f113f3e | 805 | } |
cb78486d | 806 | |
a2f27fd7 | 807 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) |
cb78486d | 808 | int RAND_set_rand_engine(ENGINE *engine) |
0f113f3e MC |
809 | { |
810 | const RAND_METHOD *tmp_meth = NULL; | |
87975cfa | 811 | |
da8fc25a | 812 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
813 | return 0; |
814 | ||
da8fc25a | 815 | if (engine != NULL) { |
0f113f3e MC |
816 | if (!ENGINE_init(engine)) |
817 | return 0; | |
818 | tmp_meth = ENGINE_get_RAND(engine); | |
7c96dbcd | 819 | if (tmp_meth == NULL) { |
0f113f3e MC |
820 | ENGINE_finish(engine); |
821 | return 0; | |
822 | } | |
823 | } | |
87975cfa | 824 | CRYPTO_THREAD_write_lock(rand_engine_lock); |
0f113f3e MC |
825 | /* This function releases any prior ENGINE so call it first */ |
826 | RAND_set_rand_method(tmp_meth); | |
827 | funct_ref = engine; | |
87975cfa | 828 | CRYPTO_THREAD_unlock(rand_engine_lock); |
0f113f3e MC |
829 | return 1; |
830 | } | |
0b13e9f0 | 831 | #endif |
dfeab068 | 832 | |
6343829a | 833 | void RAND_seed(const void *buf, int num) |
0f113f3e MC |
834 | { |
835 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a | 836 | |
0402c90f | 837 | if (meth != NULL && meth->seed != NULL) |
0f113f3e MC |
838 | meth->seed(buf, num); |
839 | } | |
dfeab068 | 840 | |
da8fc25a | 841 | void RAND_add(const void *buf, int num, double randomness) |
0f113f3e MC |
842 | { |
843 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a | 844 | |
0402c90f | 845 | if (meth != NULL && meth->add != NULL) |
da8fc25a | 846 | meth->add(buf, num, randomness); |
0f113f3e | 847 | } |
eb952088 | 848 | |
ddc6a5c8 RS |
849 | /* |
850 | * This function is not part of RAND_METHOD, so if we're not using | |
851 | * the default method, then just call RAND_bytes(). Otherwise make | |
852 | * sure we're instantiated and use the private DRBG. | |
853 | */ | |
993ebac9 | 854 | int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) |
ddc6a5c8 | 855 | { |
0b14a5b7 | 856 | RAND_DRBG *drbg; |
a2f27fd7 | 857 | const RAND_METHOD *meth = RAND_get_rand_method(); |
ddc6a5c8 | 858 | |
0402c90f DMSP |
859 | if (meth != NULL && meth != RAND_OpenSSL()) { |
860 | if (meth->bytes != NULL) | |
861 | return meth->bytes(buf, num); | |
862 | RANDerr(RAND_F_RAND_PRIV_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED); | |
863 | return -1; | |
864 | } | |
ddc6a5c8 | 865 | |
6694e51d | 866 | drbg = OPENSSL_CTX_get0_private_drbg(ctx); |
0402c90f DMSP |
867 | if (drbg != NULL) |
868 | return RAND_DRBG_bytes(drbg, buf, num); | |
ddc6a5c8 | 869 | |
0402c90f | 870 | return 0; |
ddc6a5c8 RS |
871 | } |
872 | ||
6694e51d | 873 | int RAND_priv_bytes(unsigned char *buf, int num) |
0f113f3e | 874 | { |
993ebac9 | 875 | return RAND_priv_bytes_ex(NULL, buf, num); |
6694e51d MC |
876 | } |
877 | ||
993ebac9 | 878 | int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) |
6694e51d MC |
879 | { |
880 | RAND_DRBG *drbg; | |
0f113f3e | 881 | const RAND_METHOD *meth = RAND_get_rand_method(); |
da8fc25a | 882 | |
0402c90f | 883 | if (meth != NULL && meth != RAND_OpenSSL()) { |
6694e51d MC |
884 | if (meth->bytes != NULL) |
885 | return meth->bytes(buf, num); | |
886 | RANDerr(RAND_F_RAND_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED); | |
887 | return -1; | |
888 | } | |
889 | ||
890 | drbg = OPENSSL_CTX_get0_public_drbg(ctx); | |
0402c90f DMSP |
891 | if (drbg != NULL) |
892 | return RAND_DRBG_bytes(drbg, buf, num); | |
6694e51d | 893 | |
0402c90f | 894 | return 0; |
6694e51d MC |
895 | } |
896 | ||
897 | int RAND_bytes(unsigned char *buf, int num) | |
898 | { | |
993ebac9 | 899 | return RAND_bytes_ex(NULL, buf, num); |
0f113f3e | 900 | } |
dfeab068 | 901 | |
00db8c60 | 902 | #if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODE) |
6343829a | 903 | int RAND_pseudo_bytes(unsigned char *buf, int num) |
0f113f3e MC |
904 | { |
905 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a | 906 | |
0402c90f | 907 | if (meth != NULL && meth->pseudorand != NULL) |
0f113f3e | 908 | return meth->pseudorand(buf, num); |
0402c90f | 909 | RANDerr(RAND_F_RAND_PSEUDO_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED); |
da8fc25a | 910 | return -1; |
0f113f3e | 911 | } |
302d38e3 | 912 | #endif |
5eb8ca4d BM |
913 | |
914 | int RAND_status(void) | |
0f113f3e MC |
915 | { |
916 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a | 917 | |
0402c90f | 918 | if (meth != NULL && meth->status != NULL) |
0f113f3e MC |
919 | return meth->status(); |
920 | return 0; | |
921 | } |