]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/rand/rand_lib.c
Fix typos in documentation
[thirdparty/openssl.git] / crypto / rand / rand_lib.c
CommitLineData
b1322259 1/*
f61f62ea 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
dfeab068 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
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>
63f483e1 14#include "internal/rand_int.h"
3c27208f 15#include <openssl/engine.h>
87975cfa 16#include "internal/thread_once.h"
da8fc25a 17#include "rand_lcl.h"
20928ff6 18#include "e_os.h"
dfeab068 19
0b13e9f0 20#ifndef OPENSSL_NO_ENGINE
cb78486d 21/* non-NULL if default_RAND_meth is ENGINE-provided */
da8fc25a
RS
22static ENGINE *funct_ref;
23static CRYPTO_RWLOCK *rand_engine_lock;
0b13e9f0 24#endif
da8fc25a
RS
25static CRYPTO_RWLOCK *rand_meth_lock;
26static const RAND_METHOD *default_RAND_meth;
27static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
c16de9d8 28
a35f607c 29int rand_fork_count;
87975cfa 30
5bc6bcf8
DMSP
31static CRYPTO_RWLOCK *rand_nonce_lock;
32static int rand_nonce_count;
33
8389ec4b
RS
34#ifdef OPENSSL_RAND_SEED_RDTSC
35/*
36 * IMPORTANT NOTE: It is not currently possible to use this code
9ed79d8e
RS
37 * because we are not sure about the amount of randomness it provides.
38 * Some SP900 tests have been run, but there is internal skepticism.
8389ec4b
RS
39 * So for now this code is not used.
40 */
41# error "RDTSC enabled? Should not be possible!"
42
43/*
c16de9d8
DMSP
44 * Acquire entropy from high-speed clock
45 *
8389ec4b 46 * Since we get some randomness from the low-order bits of the
c16de9d8
DMSP
47 * high-speed clock, it can help.
48 *
49 * Returns the total entropy count, if it exceeds the requested
50 * entropy count. Otherwise, returns an entropy count of 0.
8389ec4b 51 */
c16de9d8 52size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool)
8389ec4b
RS
53{
54 unsigned char c;
55 int i;
56
9ed79d8e
RS
57 if ((OPENSSL_ia32cap_P[0] & (1 << 4)) != 0) {
58 for (i = 0; i < TSC_READ_COUNT; i++) {
59 c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
6decf943 60 rand_pool_add(pool, &c, 1, 4);
9ed79d8e 61 }
8389ec4b 62 }
6decf943 63 return rand_pool_entropy_available(pool);
8389ec4b
RS
64}
65#endif
66
67#ifdef OPENSSL_RAND_SEED_RDCPU
c16de9d8
DMSP
68size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len);
69size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len);
8389ec4b
RS
70
71extern unsigned int OPENSSL_ia32cap_P[];
72
c16de9d8
DMSP
73/*
74 * Acquire entropy using Intel-specific cpu instructions
75 *
76 * Uses the RDSEED instruction if available, otherwise uses
77 * RDRAND if available.
78 *
79 * For the differences between RDSEED and RDRAND, and why RDSEED
80 * is the preferred choice, see https://goo.gl/oK3KcN
81 *
82 * Returns the total entropy count, if it exceeds the requested
83 * entropy count. Otherwise, returns an entropy count of 0.
84 */
85size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool)
8389ec4b 86{
c16de9d8
DMSP
87 size_t bytes_needed;
88 unsigned char *buffer;
89
6ebb49f3 90 bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
c16de9d8 91 if (bytes_needed > 0) {
6decf943 92 buffer = rand_pool_add_begin(pool, bytes_needed);
c16de9d8
DMSP
93
94 if (buffer != NULL) {
8e2bec9b 95 /* Whichever comes first, use RDSEED, RDRAND or nothing */
c16de9d8
DMSP
96 if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
97 if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed)
8e2bec9b
RL
98 == bytes_needed) {
99 rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
100 }
101 } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
c16de9d8 102 if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed)
8e2bec9b
RL
103 == bytes_needed) {
104 rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
105 }
106 } else {
107 rand_pool_add_end(pool, 0, 0);
c16de9d8 108 }
9ed79d8e 109 }
8389ec4b
RS
110 }
111
6decf943 112 return rand_pool_entropy_available(pool);
8389ec4b
RS
113}
114#endif
da8fc25a 115
75e2c877
RS
116
117/*
c16de9d8
DMSP
118 * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks())
119 *
120 * If the DRBG has a parent, then the required amount of entropy input
121 * is fetched using the parent's RAND_DRBG_generate().
75e2c877 122 *
c16de9d8 123 * Otherwise, the entropy is polled from the system entropy sources
6decf943 124 * using rand_pool_acquire_entropy().
c16de9d8
DMSP
125 *
126 * If a random pool has been added to the DRBG using RAND_add(), then
127 * its entropy will be used up first.
75e2c877 128 */
c16de9d8 129size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
eb238134
KR
130 unsigned char **pout,
131 int entropy, size_t min_len, size_t max_len,
132 int prediction_resistance)
75e2c877 133{
c16de9d8
DMSP
134 size_t ret = 0;
135 size_t entropy_available = 0;
35503b7c
KR
136 RAND_POOL *pool;
137
138 if (drbg->parent && drbg->strength > drbg->parent->strength) {
139 /*
140 * We currently don't support the algorithm from NIST SP 800-90C
141 * 10.1.2 to use a weaker DRBG as source
142 */
143 RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY, RAND_R_PARENT_STRENGTH_TOO_WEAK);
144 return 0;
145 }
75e2c877 146
6decf943 147 pool = rand_pool_new(entropy, min_len, max_len);
c16de9d8
DMSP
148 if (pool == NULL)
149 return 0;
150
151 if (drbg->pool) {
6decf943
DMSP
152 rand_pool_add(pool,
153 rand_pool_buffer(drbg->pool),
154 rand_pool_length(drbg->pool),
155 rand_pool_entropy(drbg->pool));
156 rand_pool_free(drbg->pool);
c16de9d8 157 drbg->pool = NULL;
75e2c877
RS
158 }
159
c16de9d8 160 if (drbg->parent) {
6ebb49f3 161 size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
6decf943 162 unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed);
9d951a78 163
c16de9d8
DMSP
164 if (buffer != NULL) {
165 size_t bytes = 0;
75e2c877 166
2139145b
BK
167 /*
168 * Get random from parent, include our state as additional input.
169 * Our lock is already held, but we need to lock our parent before
3ce1c27b
DMSP
170 * generating bits from it. (Note: taking the lock will be a no-op
171 * if locking if drbg->parent->lock == NULL.)
2139145b 172 */
812b1537 173 rand_drbg_lock(drbg->parent);
c16de9d8
DMSP
174 if (RAND_DRBG_generate(drbg->parent,
175 buffer, bytes_needed,
311276ff 176 prediction_resistance,
7c226dfc 177 NULL, 0) != 0)
c16de9d8 178 bytes = bytes_needed;
812b1537 179 rand_drbg_unlock(drbg->parent);
75e2c877 180
8e2bec9b
RL
181 rand_pool_add_end(pool, bytes, 8 * bytes);
182 entropy_available = rand_pool_entropy_available(pool);
c16de9d8 183 }
0b14a5b7 184
c16de9d8 185 } else {
311276ff
KR
186 if (prediction_resistance) {
187 /*
188 * We don't have any entropy sources that comply with the NIST
189 * standard to provide prediction resistance (see NIST SP 800-90C,
190 * Section 5.4).
191 */
192 RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY,
193 RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED);
63a65d16 194 goto err;
311276ff
KR
195 }
196
c16de9d8 197 /* Get entropy by polling system entropy sources. */
6decf943 198 entropy_available = rand_pool_acquire_entropy(pool);
75e2c877
RS
199 }
200
c16de9d8 201 if (entropy_available > 0) {
6decf943
DMSP
202 ret = rand_pool_length(pool);
203 *pout = rand_pool_detach(pool);
6969a3f4 204 }
c16de9d8 205
63a65d16 206 err:
6decf943 207 rand_pool_free(pool);
c16de9d8 208 return ret;
75e2c877
RS
209}
210
2b66fd57 211/*
5bc6bcf8 212 * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks())
60595292 213 *
2b66fd57 214 */
5bc6bcf8
DMSP
215void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
216 unsigned char *out, size_t outlen)
2b66fd57 217{
5bc6bcf8
DMSP
218 OPENSSL_secure_clear_free(out, outlen);
219}
220
221
222/*
223 * Implements the get_nonce() callback (see RAND_DRBG_set_callbacks())
224 *
225 */
226size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
227 unsigned char **pout,
228 int entropy, size_t min_len, size_t max_len)
229{
230 size_t ret = 0;
231 RAND_POOL *pool;
232
233 struct {
234 void * instance;
235 int count;
236 } data = { 0 };
237
238 pool = rand_pool_new(0, min_len, max_len);
239 if (pool == NULL)
240 return 0;
241
242 if (rand_pool_add_nonce_data(pool) == 0)
243 goto err;
244
245 data.instance = drbg;
246 CRYPTO_atomic_add(&rand_nonce_count, 1, &data.count, rand_nonce_lock);
247
248 if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0)
249 goto err;
250
251 ret = rand_pool_length(pool);
252 *pout = rand_pool_detach(pool);
253
254 err:
255 rand_pool_free(pool);
256
257 return ret;
258}
259
260/*
261 * Implements the cleanup_nonce() callback (see RAND_DRBG_set_callbacks())
262 *
263 */
264void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
265 unsigned char *out, size_t outlen)
266{
267 OPENSSL_secure_clear_free(out, outlen);
2b66fd57
P
268}
269
20928ff6
KR
270/*
271 * Generate additional data that can be used for the drbg. The data does
272 * not need to contain entropy, but it's useful if it contains at least
273 * some bits that are unpredictable.
274 *
275 * Returns 0 on failure.
276 *
277 * On success it allocates a buffer at |*pout| and returns the length of
278 * the data. The buffer should get freed using OPENSSL_secure_clear_free().
279 */
280size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len)
281{
5bc6bcf8 282 size_t ret = 0;
20928ff6 283 RAND_POOL *pool;
20928ff6 284
6decf943 285 pool = rand_pool_new(0, 0, max_len);
20928ff6
KR
286 if (pool == NULL)
287 return 0;
288
5bc6bcf8
DMSP
289 if (rand_pool_add_additional_data(pool) == 0)
290 goto err;
20928ff6 291
5bc6bcf8
DMSP
292 ret = rand_pool_length(pool);
293 *pout = rand_pool_detach(pool);
20928ff6 294
5bc6bcf8 295 err:
6decf943 296 rand_pool_free(pool);
20928ff6 297
5bc6bcf8 298 return ret;
20928ff6 299}
c16de9d8 300
5bc6bcf8 301void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen)
75e2c877 302{
c16de9d8 303 OPENSSL_secure_clear_free(out, outlen);
ddc6a5c8
RS
304}
305
3cb7c5cf 306void rand_fork(void)
a35f607c
RS
307{
308 rand_fork_count++;
309}
310
da8fc25a 311DEFINE_RUN_ONCE_STATIC(do_rand_init)
87975cfa
RL
312{
313#ifndef OPENSSL_NO_ENGINE
63ab5ea1 314 rand_engine_lock = CRYPTO_THREAD_lock_new();
0e5c1a66
BE
315 if (rand_engine_lock == NULL)
316 return 0;
87975cfa 317#endif
0e5c1a66 318
63ab5ea1 319 rand_meth_lock = CRYPTO_THREAD_lock_new();
0e5c1a66
BE
320 if (rand_meth_lock == NULL)
321 goto err1;
75e2c877 322
5bc6bcf8 323 rand_nonce_lock = CRYPTO_THREAD_lock_new();
0e5c1a66
BE
324 if (rand_nonce_lock == NULL)
325 goto err2;
5bc6bcf8 326
c7504aeb
P
327 if (!rand_pool_init())
328 goto err3;
329
0e5c1a66
BE
330 return 1;
331
c7504aeb
P
332err3:
333 rand_pool_cleanup();
0e5c1a66
BE
334err2:
335 CRYPTO_THREAD_lock_free(rand_meth_lock);
336 rand_meth_lock = NULL;
337err1:
338#ifndef OPENSSL_NO_ENGINE
339 CRYPTO_THREAD_lock_free(rand_engine_lock);
340 rand_engine_lock = NULL;
341#endif
342 return 0;
87975cfa 343}
dfeab068 344
da8fc25a
RS
345void rand_cleanup_int(void)
346{
347 const RAND_METHOD *meth = default_RAND_meth;
348
349 if (meth != NULL && meth->cleanup != NULL)
350 meth->cleanup();
c7504aeb 351 rand_pool_cleanup();
da8fc25a
RS
352 RAND_set_rand_method(NULL);
353#ifndef OPENSSL_NO_ENGINE
354 CRYPTO_THREAD_lock_free(rand_engine_lock);
0e5c1a66 355 rand_engine_lock = NULL;
da8fc25a
RS
356#endif
357 CRYPTO_THREAD_lock_free(rand_meth_lock);
0e5c1a66 358 rand_meth_lock = NULL;
5bc6bcf8 359 CRYPTO_THREAD_lock_free(rand_nonce_lock);
0e5c1a66 360 rand_nonce_lock = NULL;
75e2c877
RS
361}
362
c7504aeb
P
363/*
364 * RAND_close_seed_files() ensures that any seed file decriptors are
365 * closed after use.
366 */
367void RAND_keep_random_devices_open(int keep)
368{
369 rand_pool_keep_random_devices_open(keep);
370}
371
75e2c877 372/*
c16de9d8
DMSP
373 * RAND_poll() reseeds the default RNG using random input
374 *
375 * The random input is obtained from polling various entropy
376 * sources which depend on the operating system and are
377 * configurable via the --with-rand-seed configure option.
378 */
379int RAND_poll(void)
380{
381 int ret = 0;
382
383 RAND_POOL *pool = NULL;
384
385 const RAND_METHOD *meth = RAND_get_rand_method();
386
387 if (meth == RAND_OpenSSL()) {
a93ba405
DMSP
388 /* fill random pool and seed the master DRBG */
389 RAND_DRBG *drbg = RAND_DRBG_get0_master();
c16de9d8
DMSP
390
391 if (drbg == NULL)
392 return 0;
393
812b1537 394 rand_drbg_lock(drbg);
c16de9d8 395 ret = rand_drbg_restart(drbg, NULL, 0, 0);
812b1537 396 rand_drbg_unlock(drbg);
c16de9d8
DMSP
397
398 return ret;
399
400 } else {
401 /* fill random pool and seed the current legacy RNG */
6decf943 402 pool = rand_pool_new(RAND_DRBG_STRENGTH,
c16de9d8
DMSP
403 RAND_DRBG_STRENGTH / 8,
404 DRBG_MINMAX_FACTOR * (RAND_DRBG_STRENGTH / 8));
405 if (pool == NULL)
406 return 0;
407
6decf943 408 if (rand_pool_acquire_entropy(pool) == 0)
c16de9d8
DMSP
409 goto err;
410
411 if (meth->add == NULL
6decf943
DMSP
412 || meth->add(rand_pool_buffer(pool),
413 rand_pool_length(pool),
414 (rand_pool_entropy(pool) / 8.0)) == 0)
c16de9d8
DMSP
415 goto err;
416
417 ret = 1;
418 }
419
420err:
6decf943 421 rand_pool_free(pool);
c16de9d8
DMSP
422 return ret;
423}
424
c16de9d8
DMSP
425/*
426 * Allocate memory and initialize a new random pool
427 */
428
6decf943 429RAND_POOL *rand_pool_new(int entropy, size_t min_len, size_t max_len)
75e2c877 430{
c16de9d8
DMSP
431 RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
432
433 if (pool == NULL) {
434 RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
435 goto err;
436 }
437
438 pool->min_len = min_len;
439 pool->max_len = max_len;
440
441 pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
442 if (pool->buffer == NULL) {
443 RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
444 goto err;
445 }
446
447 pool->requested_entropy = entropy;
448
449 return pool;
450
451err:
452 OPENSSL_free(pool);
453 return NULL;
75e2c877
RS
454}
455
c16de9d8
DMSP
456/*
457 * Free |pool|, securely erasing its buffer.
458 */
6decf943 459void rand_pool_free(RAND_POOL *pool)
c16de9d8
DMSP
460{
461 if (pool == NULL)
462 return;
463
464 OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
465 OPENSSL_free(pool);
466}
467
468/*
469 * Return the |pool|'s buffer to the caller (readonly).
470 */
6decf943 471const unsigned char *rand_pool_buffer(RAND_POOL *pool)
c16de9d8
DMSP
472{
473 return pool->buffer;
474}
475
476/*
477 * Return the |pool|'s entropy to the caller.
478 */
6decf943 479size_t rand_pool_entropy(RAND_POOL *pool)
c16de9d8
DMSP
480{
481 return pool->entropy;
482}
483
484/*
485 * Return the |pool|'s buffer length to the caller.
486 */
6decf943 487size_t rand_pool_length(RAND_POOL *pool)
c16de9d8
DMSP
488{
489 return pool->len;
490}
491
492/*
493 * Detach the |pool| buffer and return it to the caller.
494 * It's the responsibility of the caller to free the buffer
495 * using OPENSSL_secure_clear_free().
496 */
6decf943 497unsigned char *rand_pool_detach(RAND_POOL *pool)
c16de9d8
DMSP
498{
499 unsigned char *ret = pool->buffer;
500 pool->buffer = NULL;
501 return ret;
502}
503
504
505/*
6ebb49f3
RL
506 * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one
507 * need to obtain at least |bits| bits of entropy?
c16de9d8 508 */
6ebb49f3
RL
509#define ENTROPY_TO_BYTES(bits, entropy_factor) \
510 (((bits) * (entropy_factor) + 7) / 8)
c16de9d8
DMSP
511
512
513/*
514 * Checks whether the |pool|'s entropy is available to the caller.
515 * This is the case when entropy count and buffer length are high enough.
516 * Returns
517 *
518 * |entropy| if the entropy count and buffer size is large enough
519 * 0 otherwise
520 */
6decf943 521size_t rand_pool_entropy_available(RAND_POOL *pool)
c16de9d8
DMSP
522{
523 if (pool->entropy < pool->requested_entropy)
524 return 0;
525
526 if (pool->len < pool->min_len)
527 return 0;
528
529 return pool->entropy;
530}
531
532/*
533 * Returns the (remaining) amount of entropy needed to fill
534 * the random pool.
535 */
536
6decf943 537size_t rand_pool_entropy_needed(RAND_POOL *pool)
c16de9d8
DMSP
538{
539 if (pool->entropy < pool->requested_entropy)
540 return pool->requested_entropy - pool->entropy;
541
542 return 0;
543}
544
545/*
546 * Returns the number of bytes needed to fill the pool, assuming
6ebb49f3 547 * the input has 1 / |entropy_factor| entropy bits per data bit.
c16de9d8
DMSP
548 * In case of an error, 0 is returned.
549 */
550
6ebb49f3 551size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor)
c16de9d8
DMSP
552{
553 size_t bytes_needed;
6decf943 554 size_t entropy_needed = rand_pool_entropy_needed(pool);
c16de9d8 555
6ebb49f3 556 if (entropy_factor < 1) {
c16de9d8
DMSP
557 RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_ARGUMENT_OUT_OF_RANGE);
558 return 0;
559 }
560
6ebb49f3 561 bytes_needed = ENTROPY_TO_BYTES(entropy_needed, entropy_factor);
c16de9d8
DMSP
562
563 if (bytes_needed > pool->max_len - pool->len) {
564 /* not enough space left */
565 RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_RANDOM_POOL_OVERFLOW);
566 return 0;
567 }
568
569 if (pool->len < pool->min_len &&
570 bytes_needed < pool->min_len - pool->len)
571 /* to meet the min_len requirement */
572 bytes_needed = pool->min_len - pool->len;
573
574 return bytes_needed;
575}
576
577/* Returns the remaining number of bytes available */
6decf943 578size_t rand_pool_bytes_remaining(RAND_POOL *pool)
75e2c877 579{
c16de9d8
DMSP
580 return pool->max_len - pool->len;
581}
582
583/*
584 * Add random bytes to the random pool.
585 *
586 * It is expected that the |buffer| contains |len| bytes of
587 * random input which contains at least |entropy| bits of
588 * randomness.
589 *
8e2bec9b 590 * Returns 1 if the added amount is adequate, otherwise 0
c16de9d8 591 */
8e2bec9b
RL
592int rand_pool_add(RAND_POOL *pool,
593 const unsigned char *buffer, size_t len, size_t entropy)
c16de9d8
DMSP
594{
595 if (len > pool->max_len - pool->len) {
596 RANDerr(RAND_F_RAND_POOL_ADD, RAND_R_ENTROPY_INPUT_TOO_LONG);
597 return 0;
598 }
599
600 if (len > 0) {
601 memcpy(pool->buffer + pool->len, buffer, len);
602 pool->len += len;
603 pool->entropy += entropy;
604 }
605
8e2bec9b 606 return 1;
c16de9d8
DMSP
607}
608
609/*
610 * Start to add random bytes to the random pool in-place.
611 *
612 * Reserves the next |len| bytes for adding random bytes in-place
613 * and returns a pointer to the buffer.
614 * The caller is allowed to copy up to |len| bytes into the buffer.
615 * If |len| == 0 this is considered a no-op and a NULL pointer
616 * is returned without producing an error message.
617 *
6decf943 618 * After updating the buffer, rand_pool_add_end() needs to be called
c16de9d8
DMSP
619 * to finish the udpate operation (see next comment).
620 */
6decf943 621unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
c16de9d8
DMSP
622{
623 if (len == 0)
624 return NULL;
625
626 if (len > pool->max_len - pool->len) {
627 RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, RAND_R_RANDOM_POOL_OVERFLOW);
628 return NULL;
629 }
630
631 return pool->buffer + pool->len;
632}
633
634/*
635 * Finish to add random bytes to the random pool in-place.
636 *
637 * Finishes an in-place update of the random pool started by
6decf943 638 * rand_pool_add_begin() (see previous comment).
c16de9d8
DMSP
639 * It is expected that |len| bytes of random input have been added
640 * to the buffer which contain at least |entropy| bits of randomness.
641 * It is allowed to add less bytes than originally reserved.
642 */
8e2bec9b 643int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
c16de9d8
DMSP
644{
645 if (len > pool->max_len - pool->len) {
646 RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
647 return 0;
648 }
649
650 if (len > 0) {
651 pool->len += len;
652 pool->entropy += entropy;
653 }
654
8e2bec9b 655 return 1;
da8fc25a
RS
656}
657
cb78486d 658int RAND_set_rand_method(const RAND_METHOD *meth)
0f113f3e 659{
da8fc25a 660 if (!RUN_ONCE(&rand_init, do_rand_init))
87975cfa
RL
661 return 0;
662
663 CRYPTO_THREAD_write_lock(rand_meth_lock);
0b13e9f0 664#ifndef OPENSSL_NO_ENGINE
7c96dbcd
RS
665 ENGINE_finish(funct_ref);
666 funct_ref = NULL;
0b13e9f0 667#endif
0f113f3e 668 default_RAND_meth = meth;
87975cfa 669 CRYPTO_THREAD_unlock(rand_meth_lock);
0f113f3e
MC
670 return 1;
671}
dfeab068 672
a4a9d97a 673const RAND_METHOD *RAND_get_rand_method(void)
0f113f3e 674{
87975cfa
RL
675 const RAND_METHOD *tmp_meth = NULL;
676
da8fc25a 677 if (!RUN_ONCE(&rand_init, do_rand_init))
87975cfa
RL
678 return NULL;
679
680 CRYPTO_THREAD_write_lock(rand_meth_lock);
da8fc25a 681 if (default_RAND_meth == NULL) {
0b13e9f0 682#ifndef OPENSSL_NO_ENGINE
da8fc25a
RS
683 ENGINE *e;
684
685 /* If we have an engine that can do RAND, use it. */
686 if ((e = ENGINE_get_default_RAND()) != NULL
687 && (tmp_meth = ENGINE_get_RAND(e)) != NULL) {
0f113f3e 688 funct_ref = e;
da8fc25a
RS
689 default_RAND_meth = tmp_meth;
690 } else {
691 ENGINE_finish(e);
75e2c877 692 default_RAND_meth = &rand_meth;
da8fc25a
RS
693 }
694#else
75e2c877 695 default_RAND_meth = &rand_meth;
0b13e9f0 696#endif
0f113f3e 697 }
87975cfa
RL
698 tmp_meth = default_RAND_meth;
699 CRYPTO_THREAD_unlock(rand_meth_lock);
700 return tmp_meth;
0f113f3e 701}
cb78486d 702
0b13e9f0 703#ifndef OPENSSL_NO_ENGINE
cb78486d 704int RAND_set_rand_engine(ENGINE *engine)
0f113f3e
MC
705{
706 const RAND_METHOD *tmp_meth = NULL;
87975cfa 707
da8fc25a 708 if (!RUN_ONCE(&rand_init, do_rand_init))
87975cfa
RL
709 return 0;
710
da8fc25a 711 if (engine != NULL) {
0f113f3e
MC
712 if (!ENGINE_init(engine))
713 return 0;
714 tmp_meth = ENGINE_get_RAND(engine);
7c96dbcd 715 if (tmp_meth == NULL) {
0f113f3e
MC
716 ENGINE_finish(engine);
717 return 0;
718 }
719 }
87975cfa 720 CRYPTO_THREAD_write_lock(rand_engine_lock);
0f113f3e
MC
721 /* This function releases any prior ENGINE so call it first */
722 RAND_set_rand_method(tmp_meth);
723 funct_ref = engine;
87975cfa 724 CRYPTO_THREAD_unlock(rand_engine_lock);
0f113f3e
MC
725 return 1;
726}
0b13e9f0 727#endif
dfeab068 728
6343829a 729void RAND_seed(const void *buf, int num)
0f113f3e
MC
730{
731 const RAND_METHOD *meth = RAND_get_rand_method();
da8fc25a
RS
732
733 if (meth->seed != NULL)
0f113f3e
MC
734 meth->seed(buf, num);
735}
dfeab068 736
da8fc25a 737void RAND_add(const void *buf, int num, double randomness)
0f113f3e
MC
738{
739 const RAND_METHOD *meth = RAND_get_rand_method();
da8fc25a
RS
740
741 if (meth->add != NULL)
742 meth->add(buf, num, randomness);
0f113f3e 743}
eb952088 744
ddc6a5c8
RS
745/*
746 * This function is not part of RAND_METHOD, so if we're not using
747 * the default method, then just call RAND_bytes(). Otherwise make
748 * sure we're instantiated and use the private DRBG.
749 */
750int RAND_priv_bytes(unsigned char *buf, int num)
751{
752 const RAND_METHOD *meth = RAND_get_rand_method();
0b14a5b7 753 RAND_DRBG *drbg;
2139145b 754 int ret;
ddc6a5c8
RS
755
756 if (meth != RAND_OpenSSL())
757 return RAND_bytes(buf, num);
758
a93ba405 759 drbg = RAND_DRBG_get0_private();
0b14a5b7 760 if (drbg == NULL)
ddc6a5c8 761 return 0;
ddc6a5c8 762
f61f62ea 763 ret = RAND_DRBG_bytes(drbg, buf, num);
2139145b 764 return ret;
ddc6a5c8
RS
765}
766
6343829a 767int RAND_bytes(unsigned char *buf, int num)
0f113f3e
MC
768{
769 const RAND_METHOD *meth = RAND_get_rand_method();
da8fc25a
RS
770
771 if (meth->bytes != NULL)
0f113f3e 772 return meth->bytes(buf, num);
0ea155fc 773 RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
da8fc25a 774 return -1;
0f113f3e 775}
dfeab068 776
98186eb4 777#if OPENSSL_API_COMPAT < 0x10100000L
6343829a 778int RAND_pseudo_bytes(unsigned char *buf, int num)
0f113f3e
MC
779{
780 const RAND_METHOD *meth = RAND_get_rand_method();
da8fc25a
RS
781
782 if (meth->pseudorand != NULL)
0f113f3e 783 return meth->pseudorand(buf, num);
da8fc25a 784 return -1;
0f113f3e 785}
302d38e3 786#endif
5eb8ca4d
BM
787
788int RAND_status(void)
0f113f3e
MC
789{
790 const RAND_METHOD *meth = RAND_get_rand_method();
da8fc25a
RS
791
792 if (meth->status != NULL)
0f113f3e
MC
793 return meth->status();
794 return 0;
795}