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