Line data Source code
1 : /* Copyright (c) 2001, Matej Pfajfar.
2 : * Copyright (c) 2001-2004, Roger Dingledine.
3 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * \file crypto_rand.c
9 : *
10 : * \brief Functions for initialising and seeding (pseudo-)random
11 : * number generators, and working with randomness.
12 : **/
13 :
14 : #define CRYPTO_RAND_PRIVATE
15 :
16 : #include "lib/crypt_ops/crypto_rand.h"
17 :
18 : #ifdef _WIN32
19 : #include <windows.h>
20 : #include <wincrypt.h>
21 : #endif /* defined(_WIN32) */
22 :
23 : #include "lib/container/smartlist.h"
24 : #include "lib/crypt_ops/compat_openssl.h"
25 : #include "lib/crypt_ops/crypto_util.h"
26 : #include "lib/encoding/binascii.h"
27 : #include "lib/intmath/weakrng.h"
28 : #include "lib/log/log.h"
29 : #include "lib/log/util_bug.h"
30 : #include "lib/malloc/malloc.h"
31 : #include "lib/sandbox/sandbox.h"
32 : #include "lib/string/compat_string.h"
33 : #include "lib/string/util_string.h"
34 : #include "lib/testsupport/testsupport.h"
35 : #include "lib/fs/files.h"
36 :
37 : #include "lib/defs/digest_sizes.h"
38 : #include "lib/crypt_ops/crypto_digest.h"
39 : #include "lib/ctime/di_ops.h"
40 :
41 : #ifdef ENABLE_NSS
42 : #include "lib/crypt_ops/crypto_nss_mgt.h"
43 : #endif
44 :
45 : #ifdef ENABLE_OPENSSL
46 : DISABLE_GCC_WARNING("-Wredundant-decls")
47 : #include <openssl/rand.h>
48 : #include <openssl/sha.h>
49 : ENABLE_GCC_WARNING("-Wredundant-decls")
50 : #endif /* defined(ENABLE_OPENSSL) */
51 :
52 : #ifdef ENABLE_NSS
53 : #include <pk11pub.h>
54 : #include <secerr.h>
55 : #include <prerror.h>
56 : #endif
57 :
58 : #if __GNUC__ && GCC_VERSION >= 402
59 : #if GCC_VERSION >= 406
60 : #pragma GCC diagnostic pop
61 : #else
62 : #pragma GCC diagnostic warning "-Wredundant-decls"
63 : #endif
64 : #endif /* __GNUC__ && GCC_VERSION >= 402 */
65 :
66 : #ifdef HAVE_FCNTL_H
67 : #include <fcntl.h>
68 : #endif
69 : #ifdef HAVE_SYS_FCNTL_H
70 : #include <sys/fcntl.h>
71 : #endif
72 : #ifdef HAVE_SYS_STAT_H
73 : #include <sys/stat.h>
74 : #endif
75 : #ifdef HAVE_UNISTD_H
76 : #include <unistd.h>
77 : #endif
78 : #ifdef HAVE_SYS_SYSCALL_H
79 : #include <sys/syscall.h>
80 : #endif
81 : #ifdef HAVE_SYS_RANDOM_H
82 : #include <sys/random.h>
83 : #endif
84 :
85 : #include <string.h>
86 : #include <errno.h>
87 :
88 : /**
89 : * How many bytes of entropy we add at once.
90 : *
91 : * This is how much entropy OpenSSL likes to add right now, so maybe it will
92 : * work for us too.
93 : **/
94 : #define ADD_ENTROPY 32
95 :
96 : /**
97 : * Longest recognized DNS query.
98 : **/
99 : #define MAX_DNS_LABEL_SIZE 63
100 :
101 : /**
102 : * Largest strong entropy request permitted.
103 : **/
104 : #define MAX_STRONGEST_RAND_SIZE 256
105 :
106 : /**
107 : * Set the seed of the weak RNG to a random value.
108 : **/
109 : void
110 7 : crypto_seed_weak_rng(tor_weak_rng_t *rng)
111 : {
112 7 : unsigned seed;
113 7 : crypto_rand((void*)&seed, sizeof(seed));
114 7 : tor_init_weak_random(rng, seed);
115 7 : }
116 :
117 : #ifdef TOR_UNIT_TESTS
118 : int break_strongest_rng_syscall = 0;
119 : int break_strongest_rng_fallback = 0;
120 : #endif
121 :
122 : /**
123 : * Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
124 : * via system calls, storing it into <b>out</b>. Return 0 on success, -1 on
125 : * failure. A maximum request size of 256 bytes is imposed.
126 : **/
127 : static int
128 8549 : crypto_strongest_rand_syscall(uint8_t *out, size_t out_len)
129 : {
130 8549 : tor_assert(out_len <= MAX_STRONGEST_RAND_SIZE);
131 :
132 : /* We only log at notice-level here because in the case that this function
133 : * fails the crypto_strongest_rand_raw() caller will log with a warning-level
134 : * message and let crypto_strongest_rand() error out and finally terminating
135 : * Tor with an assertion error.
136 : */
137 :
138 : #ifdef TOR_UNIT_TESTS
139 8549 : if (break_strongest_rng_syscall)
140 : return -1;
141 : #endif
142 :
143 : #if defined(_WIN32)
144 : static int provider_set = 0;
145 : static HCRYPTPROV provider;
146 :
147 : if (!provider_set) {
148 : if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
149 : CRYPT_VERIFYCONTEXT)) {
150 : log_notice(LD_CRYPTO, "Unable to set Windows CryptoAPI provider [1].");
151 : return -1;
152 : }
153 : provider_set = 1;
154 : }
155 : if (!CryptGenRandom(provider, out_len, out)) {
156 : log_notice(LD_CRYPTO, "Unable get entropy from the Windows CryptoAPI.");
157 : return -1;
158 : }
159 :
160 : return 0;
161 : #elif defined(__linux__) && defined(SYS_getrandom)
162 8448 : static int getrandom_works = 1; /* Be optimistic about our chances... */
163 :
164 : /* getrandom() isn't as straightforward as getentropy(), and has
165 : * no glibc wrapper.
166 : *
167 : * As far as I can tell from getrandom(2) and the source code, the
168 : * requests we issue will always succeed (though it will block on the
169 : * call if /dev/urandom isn't seeded yet), since we are NOT specifying
170 : * GRND_NONBLOCK and the request is <= 256 bytes.
171 : *
172 : * The manpage is unclear on what happens if a signal interrupts the call
173 : * while the request is blocked due to lack of entropy....
174 : *
175 : * We optimistically assume that getrandom() is available and functional
176 : * because it is the way of the future, and 2 branch mispredicts pale in
177 : * comparison to the overheads involved with failing to open
178 : * /dev/srandom followed by opening and reading from /dev/urandom.
179 : */
180 8448 : if (PREDICT_LIKELY(getrandom_works)) {
181 : long ret;
182 : /* A flag of '0' here means to read from '/dev/urandom', and to
183 : * block if insufficient entropy is available to service the
184 : * request.
185 : */
186 : const unsigned int flags = 0;
187 8448 : do {
188 8448 : ret = syscall(SYS_getrandom, out, out_len, flags);
189 8448 : } while (ret == -1 && ((errno == EINTR) ||(errno == EAGAIN)));
190 :
191 8448 : if (PREDICT_UNLIKELY(ret == -1)) {
192 : /* LCOV_EXCL_START we can't actually make the syscall fail in testing. */
193 : tor_assert(errno != EAGAIN);
194 : tor_assert(errno != EINTR);
195 :
196 : /* Useful log message for errno. */
197 : if (errno == ENOSYS) {
198 : log_notice(LD_CRYPTO, "Can't get entropy from getrandom()."
199 : " You are running a version of Tor built to support"
200 : " getrandom(), but the kernel doesn't implement this"
201 : " function--probably because it is too old?"
202 : " Trying fallback method instead.");
203 : } else {
204 : log_notice(LD_CRYPTO, "Can't get entropy from getrandom(): %s."
205 : " Trying fallback method instead.",
206 : strerror(errno));
207 : }
208 :
209 : getrandom_works = 0; /* Don't bother trying again. */
210 : return -1;
211 : /* LCOV_EXCL_STOP */
212 : }
213 :
214 8448 : tor_assert(ret == (long)out_len);
215 : return 0;
216 : }
217 :
218 : return -1; /* getrandom() previously failed unexpectedly. */
219 : #elif defined(HAVE_GETENTROPY)
220 : /* getentropy() is what Linux's getrandom() wants to be when it grows up.
221 : * the only gotcha is that requests are limited to 256 bytes.
222 : */
223 : return getentropy(out, out_len);
224 : #else
225 : (void) out;
226 : #endif /* defined(_WIN32) || ... */
227 :
228 : /* This platform doesn't have a supported syscall based random. */
229 : return -1;
230 : }
231 :
232 : /**
233 : * Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
234 : * via the per-platform fallback mechanism, storing it into <b>out</b>.
235 : * Return 0 on success, -1 on failure. A maximum request size of 256 bytes
236 : * is imposed.
237 : **/
238 : static int
239 101 : crypto_strongest_rand_fallback(uint8_t *out, size_t out_len)
240 : {
241 : #ifdef TOR_UNIT_TESTS
242 101 : if (break_strongest_rng_fallback)
243 : return -1;
244 : #endif
245 :
246 : #ifdef _WIN32
247 : /* Windows exclusively uses crypto_strongest_rand_syscall(). */
248 : (void)out;
249 : (void)out_len;
250 : return -1;
251 : #else /* !defined(_WIN32) */
252 : static const char *filenames[] = {
253 : "/dev/srandom", "/dev/urandom", "/dev/random", NULL
254 : };
255 : int fd, i;
256 : size_t n;
257 :
258 200 : for (i = 0; filenames[i]; ++i) {
259 200 : log_debug(LD_FS, "Considering %s as entropy source", filenames[i]);
260 200 : fd = open(sandbox_intern_string(filenames[i]), O_RDONLY, 0);
261 200 : if (fd<0) continue;
262 100 : log_info(LD_CRYPTO, "Reading entropy from \"%s\"", filenames[i]);
263 100 : n = read_all_from_fd(fd, (char*)out, out_len);
264 100 : close(fd);
265 100 : if (n != out_len) {
266 : /* LCOV_EXCL_START
267 : * We can't make /dev/foorandom actually fail. */
268 : log_notice(LD_CRYPTO,
269 : "Error reading from entropy source %s (read only %lu bytes).",
270 : filenames[i],
271 : (unsigned long)n);
272 : return -1;
273 : /* LCOV_EXCL_STOP */
274 : }
275 :
276 : return 0;
277 : }
278 :
279 : return -1;
280 : #endif /* defined(_WIN32) */
281 : }
282 :
283 : /**
284 : * Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
285 : * storing it into <b>out</b>. Return 0 on success, -1 on failure. A maximum
286 : * request size of 256 bytes is imposed.
287 : **/
288 : STATIC int
289 8549 : crypto_strongest_rand_raw(uint8_t *out, size_t out_len)
290 : {
291 8549 : static const size_t sanity_min_size = 16;
292 8549 : static const int max_attempts = 3;
293 8549 : tor_assert(out_len <= MAX_STRONGEST_RAND_SIZE);
294 :
295 : /* For buffers >= 16 bytes (128 bits), we sanity check the output by
296 : * zero filling the buffer and ensuring that it actually was at least
297 : * partially modified.
298 : *
299 : * Checking that any individual byte is non-zero seems like it would
300 : * fail too often (p = out_len * 1/256) for comfort, but this is an
301 : * "adjust according to taste" sort of check.
302 : */
303 8549 : memwipe(out, 0, out_len);
304 8549 : for (int i = 0; i < max_attempts; i++) {
305 : /* Try to use the syscall/OS favored mechanism to get strong entropy. */
306 8549 : if (crypto_strongest_rand_syscall(out, out_len) != 0) {
307 : /* Try to use the less-favored mechanism to get strong entropy. */
308 101 : if (crypto_strongest_rand_fallback(out, out_len) != 0) {
309 : /* Welp, we tried. Hopefully the calling code terminates the process
310 : * since we're basically boned without good entropy.
311 : */
312 1 : log_warn(LD_CRYPTO,
313 : "Cannot get strong entropy: no entropy source found.");
314 1 : return -1;
315 : }
316 : }
317 :
318 8548 : if ((out_len < sanity_min_size) || !safe_mem_is_zero((char*)out, out_len))
319 8548 : return 0;
320 : }
321 :
322 : /* LCOV_EXCL_START
323 : *
324 : * We tried max_attempts times to fill a buffer >= 128 bits long,
325 : * and each time it returned all '0's. Either the system entropy
326 : * source is busted, or the user should go out and buy a ticket to
327 : * every lottery on the planet.
328 : */
329 : log_warn(LD_CRYPTO, "Strong OS entropy returned all zero buffer.");
330 :
331 : return -1;
332 : /* LCOV_EXCL_STOP */
333 : }
334 :
335 : /**
336 : * Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
337 : * storing it into <b>out</b>.
338 : **/
339 : void
340 2671 : crypto_strongest_rand(uint8_t *out, size_t out_len)
341 : {
342 2671 : crypto_strongest_rand_(out, out_len);
343 2671 : }
344 :
345 : /**
346 : * Try to get <b>out_len</b> bytes of the strongest entropy we can generate,
347 : * storing it into <b>out</b>. (Mockable version.)
348 : **/
349 2670 : MOCK_IMPL(void,
350 : crypto_strongest_rand_,(uint8_t *out, size_t out_len))
351 : {
352 : #define DLEN DIGEST512_LEN
353 :
354 : /* We're going to hash DLEN bytes from the system RNG together with some
355 : * bytes from the PRNGs from our crypto librar(y/ies), in order to yield
356 : * DLEN bytes.
357 : */
358 2670 : uint8_t inp[DLEN*3];
359 2670 : uint8_t tmp[DLEN];
360 2670 : tor_assert(out);
361 2870 : while (out_len) {
362 2770 : memset(inp, 0, sizeof(inp));
363 : #ifdef ENABLE_OPENSSL
364 2770 : RAND_bytes(inp, DLEN);
365 : #endif
366 : #ifdef ENABLE_NSS
367 : PK11_GenerateRandom(inp+DLEN, DLEN);
368 : #endif
369 2770 : if (crypto_strongest_rand_raw(inp+DLEN*2, DLEN) < 0) {
370 : // LCOV_EXCL_START
371 : log_err(LD_CRYPTO, "Failed to load strong entropy when generating an "
372 : "important key. Exiting.");
373 : /* Die with an assertion so we get a stack trace. */
374 : tor_assert(0);
375 : // LCOV_EXCL_STOP
376 : }
377 2770 : if (out_len >= DLEN) {
378 200 : crypto_digest512((char*)out, (char*)inp, sizeof(inp), DIGEST_SHA512);
379 200 : out += DLEN;
380 200 : out_len -= DLEN;
381 : } else {
382 2570 : crypto_digest512((char*)tmp, (char*)inp, sizeof(inp), DIGEST_SHA512);
383 2570 : memcpy(out, tmp, out_len);
384 : break;
385 : }
386 : }
387 2670 : memwipe(tmp, 0, sizeof(tmp));
388 2670 : memwipe(inp, 0, sizeof(inp));
389 : #undef DLEN
390 2670 : }
391 :
392 : #ifdef ENABLE_OPENSSL
393 : /**
394 : * Seed OpenSSL's random number generator with bytes from the operating
395 : * system. Return 0 on success, -1 on failure.
396 : **/
397 : static int
398 5578 : crypto_seed_openssl_rng(void)
399 : {
400 5578 : int rand_poll_ok = 0, load_entropy_ok = 0;
401 5578 : uint8_t buf[ADD_ENTROPY];
402 :
403 : /* OpenSSL has a RAND_poll function that knows about more kinds of
404 : * entropy than we do. We'll try calling that, *and* calling our own entropy
405 : * functions. If one succeeds, we'll accept the RNG as seeded. */
406 5578 : rand_poll_ok = RAND_poll();
407 5578 : if (rand_poll_ok == 0)
408 : log_warn(LD_CRYPTO, "RAND_poll() failed."); // LCOV_EXCL_LINE
409 :
410 5578 : load_entropy_ok = !crypto_strongest_rand_raw(buf, sizeof(buf));
411 5578 : if (load_entropy_ok) {
412 5578 : RAND_seed(buf, sizeof(buf));
413 : }
414 :
415 5578 : memwipe(buf, 0, sizeof(buf));
416 :
417 5578 : if ((rand_poll_ok || load_entropy_ok) && RAND_status() == 1)
418 : return 0;
419 : else
420 0 : return -1;
421 : }
422 : #endif /* defined(ENABLE_OPENSSL) */
423 :
424 : #ifdef ENABLE_NSS
425 : /**
426 : * Seed OpenSSL's random number generator with bytes from the operating
427 : * system. Return 0 on success, -1 on failure.
428 : **/
429 : static int
430 : crypto_seed_nss_rng(void)
431 : {
432 : uint8_t buf[ADD_ENTROPY];
433 :
434 : int load_entropy_ok = !crypto_strongest_rand_raw(buf, sizeof(buf));
435 : if (load_entropy_ok) {
436 : if (PK11_RandomUpdate(buf, sizeof(buf)) != SECSuccess) {
437 : load_entropy_ok = 0;
438 : }
439 : }
440 :
441 : memwipe(buf, 0, sizeof(buf));
442 :
443 : return load_entropy_ok ? 0 : -1;
444 : }
445 : #endif /* defined(ENABLE_NSS) */
446 :
447 : /**
448 : * Seed the RNG for any and all crypto libraries that we're using with bytes
449 : * from the operating system. Return 0 on success, -1 on failure.
450 : */
451 : int
452 5578 : crypto_seed_rng(void)
453 : {
454 5578 : int seeded = 0;
455 : #ifdef ENABLE_NSS
456 : if (crypto_seed_nss_rng() < 0)
457 : return -1;
458 : ++seeded;
459 : #endif
460 : #ifdef ENABLE_OPENSSL
461 5578 : if (crypto_seed_openssl_rng() < 0)
462 0 : return -1;
463 5578 : ++seeded;
464 : #endif
465 : tor_assert(seeded);
466 : return 0;
467 : }
468 :
469 : /**
470 : * Write <b>n</b> bytes of strong random data to <b>to</b>. Supports mocking
471 : * for unit tests.
472 : *
473 : * This function is not allowed to fail; if it would fail to generate strong
474 : * entropy, it must terminate the process instead.
475 : **/
476 402918 : MOCK_IMPL(void,
477 : crypto_rand, (char *to, size_t n))
478 : {
479 402918 : crypto_rand_unmocked(to, n);
480 402918 : }
481 :
482 : /**
483 : * Write <b>n</b> bytes of strong random data to <b>to</b>. Most callers
484 : * will want crypto_rand instead.
485 : *
486 : * This function is not allowed to fail; if it would fail to generate strong
487 : * entropy, it must terminate the process instead.
488 : **/
489 : void
490 402920 : crypto_rand_unmocked(char *to, size_t n)
491 : {
492 402920 : if (n == 0)
493 : return;
494 :
495 402900 : tor_assert(n < INT_MAX);
496 402900 : tor_assert(to);
497 :
498 : #ifdef ENABLE_NSS
499 : SECStatus s = PK11_GenerateRandom((unsigned char*)to, (int)n);
500 : if (s != SECSuccess) {
501 : /* NSS rather sensibly might refuse to generate huge amounts of random
502 : * data at once. Unfortunately, our unit test do this in a couple of
503 : * places. To solve this issue, we use our XOF to stretch a shorter
504 : * output when a longer one is needed.
505 : *
506 : * Yes, this is secure. */
507 :
508 : /* This is longer than it needs to be; 1600 bits == 200 bytes is the
509 : * state-size of SHA3. */
510 : #define BUFLEN 512
511 : tor_assert(PR_GetError() == SEC_ERROR_INVALID_ARGS && n > BUFLEN);
512 : unsigned char buf[BUFLEN];
513 : s = PK11_GenerateRandom(buf, BUFLEN);
514 : tor_assert(s == SECSuccess);
515 : crypto_xof_t *xof = crypto_xof_new();
516 : crypto_xof_add_bytes(xof, buf, BUFLEN);
517 : crypto_xof_squeeze_bytes(xof, (unsigned char *)to, n);
518 : crypto_xof_free(xof);
519 : memwipe(buf, 0, BUFLEN);
520 :
521 : #undef BUFLEN
522 : }
523 : #else /* !defined(ENABLE_NSS) */
524 402900 : int r = RAND_bytes((unsigned char*)to, (int)n);
525 : /* We consider a PRNG failure non-survivable. Let's assert so that we get a
526 : * stack trace about where it happened.
527 : */
528 402900 : tor_assert(r >= 0);
529 : #endif /* defined(ENABLE_NSS) */
530 : }
531 :
532 : /**
533 : * Draw an unsigned 32-bit integer uniformly at random.
534 : */
535 : uint32_t
536 0 : crypto_rand_u32(void)
537 : {
538 0 : uint32_t rand;
539 0 : crypto_rand((void*)&rand, sizeof(rand));
540 0 : return rand;
541 : }
542 :
543 : /**
544 : * Generate and return a new random hostname starting with <b>prefix</b>,
545 : * ending with <b>suffix</b>, and containing no fewer than
546 : * <b>min_rand_len</b> and no more than <b>max_rand_len</b> random base32
547 : * characters. Does not check for failure.
548 : *
549 : * Clip <b>max_rand_len</b> to MAX_DNS_LABEL_SIZE.
550 : **/
551 : char *
552 341 : crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix,
553 : const char *suffix)
554 : {
555 341 : char *result, *rand_bytes;
556 341 : int randlen, rand_bytes_len;
557 341 : size_t resultlen, prefixlen;
558 :
559 341 : if (max_rand_len > MAX_DNS_LABEL_SIZE)
560 : max_rand_len = MAX_DNS_LABEL_SIZE;
561 341 : if (min_rand_len > max_rand_len)
562 : min_rand_len = max_rand_len;
563 :
564 341 : randlen = crypto_rand_int_range(min_rand_len, max_rand_len+1);
565 :
566 341 : prefixlen = strlen(prefix);
567 341 : resultlen = prefixlen + strlen(suffix) + randlen + 16;
568 :
569 341 : rand_bytes_len = ((randlen*5)+7)/8;
570 341 : if (rand_bytes_len % 5)
571 254 : rand_bytes_len += 5 - (rand_bytes_len%5);
572 341 : rand_bytes = tor_malloc(rand_bytes_len);
573 341 : crypto_rand(rand_bytes, rand_bytes_len);
574 :
575 341 : result = tor_malloc(resultlen);
576 341 : memcpy(result, prefix, prefixlen);
577 341 : base32_encode(result+prefixlen, resultlen-prefixlen,
578 : rand_bytes, rand_bytes_len);
579 341 : tor_free(rand_bytes);
580 341 : strlcpy(result+prefixlen+randlen, suffix, resultlen-(prefixlen+randlen));
581 :
582 341 : return result;
583 : }
584 :
585 : /**
586 : * Return a randomly chosen element of <b>sl</b>; or NULL if <b>sl</b>
587 : * is empty.
588 : **/
589 : void *
590 312 : smartlist_choose(const smartlist_t *sl)
591 : {
592 312 : int len = smartlist_len(sl);
593 312 : if (len)
594 300 : return smartlist_get(sl,crypto_rand_int(len));
595 : return NULL; /* no elements to choose from */
596 : }
597 :
598 : /**
599 : * Scramble the elements of <b>sl</b> into a random order.
600 : **/
601 : void
602 61 : smartlist_shuffle(smartlist_t *sl)
603 : {
604 61 : int i;
605 : /* From the end of the list to the front, choose at random from the
606 : positions we haven't looked at yet, and swap that position into the
607 : current position. Remember to give "no swap" the same probability as
608 : any other swap. */
609 903 : for (i = smartlist_len(sl)-1; i > 0; --i) {
610 842 : int j = crypto_rand_int(i+1);
611 842 : smartlist_swap(sl, i, j);
612 : }
613 61 : }
614 :
615 : /** Make sure that openssl is using its default PRNG. Return 1 if we had to
616 : * adjust it; 0 otherwise. */
617 : int
618 11090 : crypto_force_rand_ssleay(void)
619 : {
620 : #ifdef ENABLE_OPENSSL
621 11090 : RAND_METHOD *default_method;
622 11090 : default_method = RAND_OpenSSL();
623 11090 : if (RAND_get_rand_method() != default_method) {
624 1 : log_notice(LD_CRYPTO, "It appears that one of our engines has provided "
625 : "a replacement the OpenSSL RNG. Resetting it to the default "
626 : "implementation.");
627 1 : RAND_set_rand_method(default_method);
628 1 : return 1;
629 : }
630 : #endif /* defined(ENABLE_OPENSSL) */
631 : return 0;
632 : }
|