/src/libgcrypt/random/random.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* random.c - Random number switch |
2 | | * Copyright (C) 2003, 2006, 2008, 2012 Free Software Foundation, Inc. |
3 | | * |
4 | | * This file is part of Libgcrypt. |
5 | | * |
6 | | * Libgcrypt is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as |
8 | | * published by the Free Software Foundation; either version 2.1 of |
9 | | * the License, or (at your option) any later version. |
10 | | * |
11 | | * Libgcrypt is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this program; if not, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | /* |
21 | | This module switches between different implementations of random |
22 | | number generators and provides a few help functions. |
23 | | */ |
24 | | |
25 | | #include <config.h> |
26 | | #include <stdio.h> |
27 | | #include <stdlib.h> |
28 | | #include <errno.h> |
29 | | #include <time.h> |
30 | | #include <sys/types.h> |
31 | | #include <unistd.h> |
32 | | #ifdef HAVE_SYSLOG |
33 | | # include <syslog.h> |
34 | | #endif /*HAVE_SYSLOG*/ |
35 | | #include <ctype.h> |
36 | | |
37 | | #include "g10lib.h" |
38 | | #include "random.h" |
39 | | #include "rand-internal.h" |
40 | | #include "cipher.h" /* For _gcry_sha1_hash_buffer(). */ |
41 | | |
42 | | /* The name of a file used to globally configure the RNG. */ |
43 | 0 | #define RANDOM_CONF_FILE "/etc/gcrypt/random.conf" |
44 | | |
45 | | |
46 | | /* If not NULL a progress function called from certain places and the |
47 | | opaque value passed along. Registered by |
48 | | _gcry_register_random_progress (). */ |
49 | | static void (*progress_cb) (void *,const char*,int,int, int ); |
50 | | static void *progress_cb_data; |
51 | | |
52 | | /* Flags indicating the requested RNG types. */ |
53 | | static struct |
54 | | { |
55 | | int standard; |
56 | | int fips; |
57 | | int system; |
58 | | } rng_types; |
59 | | |
60 | | |
61 | | /* This is the lock we use to protect the buffer used by the nonce |
62 | | generation. */ |
63 | | GPGRT_LOCK_DEFINE (nonce_buffer_lock); |
64 | | |
65 | | |
66 | | |
67 | | /* --- Functions --- */ |
68 | | |
69 | | |
70 | | /* Used to register a progress callback. This needs to be called |
71 | | before any threads are created. */ |
72 | | void |
73 | | _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), |
74 | | void *cb_data ) |
75 | 0 | { |
76 | 0 | progress_cb = cb; |
77 | 0 | progress_cb_data = cb_data; |
78 | 0 | } |
79 | | |
80 | | |
81 | | /* This progress function is currently used by the random modules to |
82 | | give hints on how much more entropy is required. */ |
83 | | void |
84 | | _gcry_random_progress (const char *what, int printchar, int current, int total) |
85 | 0 | { |
86 | 0 | if (progress_cb) |
87 | 0 | progress_cb (progress_cb_data, what, printchar, current, total); |
88 | 0 | } |
89 | | |
90 | | |
91 | | /* Read a file with configure options. The file is a simple text file |
92 | | * where empty lines and lines with the first non white-space |
93 | | * character being '#' are ignored. Supported configure options are: |
94 | | * |
95 | | * disable-jent - Disable the jitter based extra entropy generator. |
96 | | * This sets the RANDOM_CONF_DISABLE_JENT bit. |
97 | | * only-urandom - Always use /dev/urandom instead of /dev/random. |
98 | | * This sets the RANDOM_CONF_ONLY_URANDOM bit. |
99 | | * |
100 | | * The function returns a bit vector with flags read from the file. |
101 | | */ |
102 | | unsigned int |
103 | | _gcry_random_read_conf (void) |
104 | 0 | { |
105 | 0 | const char *fname = RANDOM_CONF_FILE; |
106 | 0 | FILE *fp; |
107 | 0 | char buffer[256]; |
108 | 0 | char *p, *pend; |
109 | 0 | int lnr = 0; |
110 | 0 | unsigned int result = 0; |
111 | |
|
112 | 0 | fp = fopen (fname, "r"); |
113 | 0 | if (!fp) |
114 | 0 | return result; |
115 | | |
116 | 0 | for (;;) |
117 | 0 | { |
118 | 0 | if (!fgets (buffer, sizeof buffer, fp)) |
119 | 0 | { |
120 | 0 | if (!feof (fp)) |
121 | 0 | { |
122 | 0 | #ifdef HAVE_SYSLOG |
123 | 0 | syslog (LOG_USER|LOG_WARNING, |
124 | 0 | "Libgcrypt warning: error reading '%s', line %d", |
125 | 0 | fname, lnr); |
126 | 0 | #endif /*HAVE_SYSLOG*/ |
127 | 0 | } |
128 | 0 | fclose (fp); |
129 | 0 | return result; |
130 | 0 | } |
131 | 0 | lnr++; |
132 | 0 | for (p=buffer; my_isascii (*p) && isspace (*p); p++) |
133 | 0 | ; |
134 | 0 | pend = strchr (p, '\n'); |
135 | 0 | if (pend) |
136 | 0 | *pend = 0; |
137 | 0 | pend = p + (*p? (strlen (p)-1):0); |
138 | 0 | for ( ;pend > p; pend--) |
139 | 0 | if (my_isascii (*pend) && isspace (*pend)) |
140 | 0 | *pend = 0; |
141 | 0 | if (!*p || *p == '#') |
142 | 0 | continue; |
143 | | |
144 | 0 | if (!strcmp (p, "disable-jent")) |
145 | 0 | result |= RANDOM_CONF_DISABLE_JENT; |
146 | 0 | else if (!strcmp (p, "only-urandom")) |
147 | 0 | result |= RANDOM_CONF_ONLY_URANDOM; |
148 | 0 | else |
149 | 0 | { |
150 | 0 | #ifdef HAVE_SYSLOG |
151 | 0 | syslog (LOG_USER|LOG_WARNING, |
152 | 0 | "Libgcrypt warning: unknown option in '%s', line %d", |
153 | 0 | fname, lnr); |
154 | 0 | #endif /*HAVE_SYSLOG*/ |
155 | 0 | } |
156 | 0 | } |
157 | 0 | } |
158 | | |
159 | | |
160 | | /* Set the preferred RNG type. This may be called at any time even |
161 | | before gcry_check_version. Thus we can't assume any thread system |
162 | | initialization. A type of 0 is used to indicate that any Libgcrypt |
163 | | initialization has been done.*/ |
164 | | void |
165 | | _gcry_set_preferred_rng_type (int type) |
166 | 1 | { |
167 | 1 | static int any_init; |
168 | | |
169 | 1 | if (!type) |
170 | 1 | { |
171 | 1 | any_init = 1; |
172 | 1 | } |
173 | 0 | else if (type == GCRY_RNG_TYPE_STANDARD) |
174 | 0 | { |
175 | 0 | rng_types.standard = 1; |
176 | 0 | } |
177 | 0 | else if (any_init) |
178 | 0 | { |
179 | | /* After any initialization has been done we only allow to |
180 | | upgrade to the standard RNG (handled above). All other |
181 | | requests are ignored. The idea is that the application needs |
182 | | to declare a preference for a weaker RNG as soon as possible |
183 | | and before any library sets a preference. We assume that a |
184 | | library which uses Libgcrypt calls an init function very |
185 | | early. This way --- even if the library gets initialized |
186 | | early by the application --- it is unlikely that it can |
187 | | select a lower priority RNG. |
188 | | |
189 | | This scheme helps to ensure that existing unmodified |
190 | | applications (e.g. gpg2), which don't known about the new RNG |
191 | | selection system, will continue to use the standard RNG and |
192 | | not be tricked by some library to use a lower priority RNG. |
193 | | There are some loopholes here but at least most GnuPG stuff |
194 | | should be save because it calls src_c{gcry_control |
195 | | (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits |
196 | | switching to a low priority RNG. |
197 | | */ |
198 | 0 | } |
199 | 0 | else if (type == GCRY_RNG_TYPE_FIPS) |
200 | 0 | { |
201 | 0 | rng_types.fips = 1; |
202 | 0 | } |
203 | 0 | else if (type == GCRY_RNG_TYPE_SYSTEM) |
204 | 0 | { |
205 | 0 | rng_types.system = 1; |
206 | 0 | } |
207 | 1 | } |
208 | | |
209 | | |
210 | | /* Initialize this random subsystem. If FULL is false, this function |
211 | | merely calls the basic initialization of the module and does not do |
212 | | anything more. Doing this is not really required but when running |
213 | | in a threaded environment we might get a race condition |
214 | | otherwise. */ |
215 | | void |
216 | | _gcry_random_initialize (int full) |
217 | 1 | { |
218 | 1 | if (fips_mode ()) |
219 | 0 | _gcry_rngdrbg_inititialize (full); |
220 | 1 | else if (rng_types.standard) |
221 | 0 | _gcry_rngcsprng_initialize (full); |
222 | 1 | else if (rng_types.fips) |
223 | 0 | _gcry_rngdrbg_inititialize (full); |
224 | 1 | else if (rng_types.system) |
225 | 0 | _gcry_rngsystem_initialize (full); |
226 | 1 | else |
227 | 1 | _gcry_rngcsprng_initialize (full); |
228 | 1 | } |
229 | | |
230 | | |
231 | | /* If possible close file descriptors used by the RNG. */ |
232 | | void |
233 | | _gcry_random_close_fds (void) |
234 | 0 | { |
235 | | /* Note that we can't do that directly because each random system |
236 | | has its own lock functions which need to be used for accessing |
237 | | the entropy gatherer. */ |
238 | |
|
239 | 0 | if (fips_mode ()) |
240 | 0 | _gcry_rngdrbg_close_fds (); |
241 | 0 | else if (rng_types.standard) |
242 | 0 | _gcry_rngcsprng_close_fds (); |
243 | 0 | else if (rng_types.fips) |
244 | 0 | _gcry_rngdrbg_close_fds (); |
245 | 0 | else if (rng_types.system) |
246 | 0 | _gcry_rngsystem_close_fds (); |
247 | 0 | else |
248 | 0 | _gcry_rngcsprng_close_fds (); |
249 | 0 | } |
250 | | |
251 | | |
252 | | /* Return the current RNG type. IGNORE_FIPS_MODE is a flag used to |
253 | | skip the test for FIPS. This is useful, so that we are able to |
254 | | return the type of the RNG even before we have setup FIPS mode |
255 | | (note that FIPS mode is enabled by default until it is switched off |
256 | | by the initialization). This is mostly useful for the regression |
257 | | test. */ |
258 | | int |
259 | | _gcry_get_rng_type (int ignore_fips_mode) |
260 | 0 | { |
261 | 0 | if (!ignore_fips_mode && fips_mode ()) |
262 | 0 | return GCRY_RNG_TYPE_FIPS; |
263 | 0 | else if (rng_types.standard) |
264 | 0 | return GCRY_RNG_TYPE_STANDARD; |
265 | 0 | else if (rng_types.fips) |
266 | 0 | return GCRY_RNG_TYPE_FIPS; |
267 | 0 | else if (rng_types.system) |
268 | 0 | return GCRY_RNG_TYPE_SYSTEM; |
269 | 0 | else |
270 | 0 | return GCRY_RNG_TYPE_STANDARD; |
271 | 0 | } |
272 | | |
273 | | |
274 | | void |
275 | | _gcry_random_dump_stats (void) |
276 | 0 | { |
277 | 0 | if (fips_mode ()) |
278 | 0 | _gcry_rngdrbg_dump_stats (); |
279 | 0 | else |
280 | 0 | _gcry_rngcsprng_dump_stats (); |
281 | 0 | _gcry_rndjent_dump_stats (); |
282 | 0 | } |
283 | | |
284 | | |
285 | | /* This function should be called during initialization and before |
286 | | initialization of this module to place the random pools into secure |
287 | | memory. */ |
288 | | void |
289 | | _gcry_secure_random_alloc (void) |
290 | 0 | { |
291 | 0 | if (fips_mode ()) |
292 | 0 | ; /* Not used; the FIPS RNG is always in secure mode. */ |
293 | 0 | else |
294 | 0 | _gcry_rngcsprng_secure_alloc (); |
295 | 0 | } |
296 | | |
297 | | |
298 | | /* This may be called before full initialization to degrade the |
299 | | quality of the RNG for the sake of a faster running test suite. */ |
300 | | void |
301 | | _gcry_enable_quick_random_gen (void) |
302 | 0 | { |
303 | 0 | if (fips_mode ()) |
304 | 0 | ; /* Not used. */ |
305 | 0 | else |
306 | 0 | _gcry_rngcsprng_enable_quick_gen (); |
307 | 0 | } |
308 | | |
309 | | |
310 | | /* This function returns true if no real RNG is available or the |
311 | | quality of the RNG has been degraded for test purposes. */ |
312 | | int |
313 | | _gcry_random_is_faked (void) |
314 | 0 | { |
315 | 0 | if (fips_mode ()) |
316 | 0 | return _gcry_rngdrbg_is_faked (); |
317 | 0 | else |
318 | 0 | return _gcry_rngcsprng_is_faked (); |
319 | 0 | } |
320 | | |
321 | | |
322 | | /* Add BUFLEN bytes from BUF to the internal random pool. QUALITY |
323 | | should be in the range of 0..100 to indicate the goodness of the |
324 | | entropy added, or -1 for goodness not known. */ |
325 | | gcry_err_code_t |
326 | | _gcry_random_add_bytes (const void *buf, size_t buflen, int quality) |
327 | 0 | { |
328 | 0 | if (fips_mode ()) |
329 | 0 | return 0; /* No need for this in fips mode. */ |
330 | 0 | else if (rng_types.standard) |
331 | 0 | return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality)); |
332 | 0 | else if (rng_types.fips) |
333 | 0 | return 0; |
334 | 0 | else if (rng_types.system) |
335 | 0 | return 0; |
336 | 0 | else /* default */ |
337 | 0 | return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality)); |
338 | 0 | } |
339 | | |
340 | | |
341 | | /* Helper function. */ |
342 | | static void |
343 | | do_randomize (void *buffer, size_t length, enum gcry_random_level level) |
344 | 1 | { |
345 | 1 | if (fips_mode ()) |
346 | 0 | _gcry_rngdrbg_randomize (buffer, length, level); |
347 | 1 | else if (rng_types.standard) |
348 | 0 | _gcry_rngcsprng_randomize (buffer, length, level); |
349 | 1 | else if (rng_types.fips) |
350 | 0 | _gcry_rngdrbg_randomize (buffer, length, level); |
351 | 1 | else if (rng_types.system) |
352 | 0 | _gcry_rngsystem_randomize (buffer, length, level); |
353 | 1 | else /* default */ |
354 | 1 | _gcry_rngcsprng_randomize (buffer, length, level); |
355 | 1 | } |
356 | | |
357 | | /* The public function to return random data of the quality LEVEL. |
358 | | Returns a pointer to a newly allocated and randomized buffer of |
359 | | LEVEL and NBYTES length. Caller must free the buffer. */ |
360 | | void * |
361 | | _gcry_random_bytes (size_t nbytes, enum gcry_random_level level) |
362 | 0 | { |
363 | 0 | void *buffer; |
364 | |
|
365 | 0 | buffer = xmalloc (nbytes); |
366 | 0 | do_randomize (buffer, nbytes, level); |
367 | 0 | return buffer; |
368 | 0 | } |
369 | | |
370 | | |
371 | | /* The public function to return random data of the quality LEVEL; |
372 | | this version of the function returns the random in a buffer allocated |
373 | | in secure memory. Caller must free the buffer. */ |
374 | | void * |
375 | | _gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) |
376 | 0 | { |
377 | 0 | void *buffer; |
378 | | |
379 | | /* Historical note (1.3.0--1.4.1): The buffer was only allocated |
380 | | in secure memory if the pool in random-csprng.c was also set to |
381 | | use secure memory. */ |
382 | 0 | buffer = xmalloc_secure (nbytes); |
383 | 0 | do_randomize (buffer, nbytes, level); |
384 | 0 | return buffer; |
385 | 0 | } |
386 | | |
387 | | |
388 | | /* Public function to fill the buffer with LENGTH bytes of |
389 | | cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is |
390 | | not very strong, GCRY_STRONG_RANDOM is strong enough for most |
391 | | usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but |
392 | | may be very slow. */ |
393 | | void |
394 | | _gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) |
395 | 1 | { |
396 | 1 | do_randomize (buffer, length, level); |
397 | 1 | } |
398 | | |
399 | | |
400 | | /* This function may be used to specify the file to be used as a seed |
401 | | file for the PRNG. This function should be called prior to the |
402 | | initialization of the random module. NAME may not be NULL. */ |
403 | | void |
404 | | _gcry_set_random_seed_file (const char *name) |
405 | 0 | { |
406 | 0 | if (fips_mode ()) |
407 | 0 | ; /* No need for this in fips mode. */ |
408 | 0 | else if (rng_types.standard) |
409 | 0 | _gcry_rngcsprng_set_seed_file (name); |
410 | 0 | else if (rng_types.fips) |
411 | 0 | ; |
412 | 0 | else if (rng_types.system) |
413 | 0 | ; |
414 | 0 | else /* default */ |
415 | 0 | _gcry_rngcsprng_set_seed_file (name); |
416 | 0 | } |
417 | | |
418 | | |
419 | | /* If a seed file has been setup, this function may be used to write |
420 | | back the random numbers entropy pool. */ |
421 | | void |
422 | | _gcry_update_random_seed_file (void) |
423 | 0 | { |
424 | 0 | if (fips_mode ()) |
425 | 0 | ; /* No need for this in fips mode. */ |
426 | 0 | else if (rng_types.standard) |
427 | 0 | _gcry_rngcsprng_update_seed_file (); |
428 | 0 | else if (rng_types.fips) |
429 | 0 | ; |
430 | 0 | else if (rng_types.system) |
431 | 0 | ; |
432 | 0 | else /* default */ |
433 | 0 | _gcry_rngcsprng_update_seed_file (); |
434 | 0 | } |
435 | | |
436 | | |
437 | | |
438 | | /* The fast random pool function as called at some places in |
439 | | libgcrypt. This is merely a wrapper to make sure that this module |
440 | | is initialized and to lock the pool. Note, that this function is a |
441 | | NOP unless a random function has been used or _gcry_initialize (1) |
442 | | has been used. We use this hack so that the internal use of this |
443 | | function in cipher_open and md_open won't start filling up the |
444 | | random pool, even if no random will be required by the process. */ |
445 | | void |
446 | | _gcry_fast_random_poll (void) |
447 | 132k | { |
448 | 132k | if (fips_mode ()) |
449 | 0 | ; /* No need for this in fips mode. */ |
450 | 132k | else if (rng_types.standard) |
451 | 0 | _gcry_rngcsprng_fast_poll (); |
452 | 132k | else if (rng_types.fips) |
453 | 0 | ; |
454 | 132k | else if (rng_types.system) |
455 | 0 | ; |
456 | 132k | else /* default */ |
457 | 132k | _gcry_rngcsprng_fast_poll (); |
458 | 132k | } |
459 | | |
460 | | |
461 | | |
462 | | /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ |
463 | | void |
464 | | _gcry_create_nonce (void *buffer, size_t length) |
465 | 1 | { |
466 | 1 | static unsigned char nonce_buffer[20+8]; |
467 | 1 | static int nonce_buffer_initialized = 0; |
468 | 1 | static volatile pid_t my_pid; /* The volatile is there to make sure the |
469 | | compiler does not optimize the code away |
470 | | in case the getpid function is badly |
471 | | attributed. */ |
472 | 1 | volatile pid_t apid; |
473 | 1 | unsigned char *p; |
474 | 1 | size_t n; |
475 | 1 | int err; |
476 | | |
477 | | /* First check whether we shall use the FIPS nonce generator. This |
478 | | is only done in FIPS mode, in all other modes, we use our own |
479 | | nonce generator which is seeded by the RNG actual in use. */ |
480 | 1 | if (fips_mode ()) |
481 | 0 | { |
482 | 0 | _gcry_rngdrbg_randomize (buffer, length, GCRY_WEAK_RANDOM); |
483 | 0 | return; |
484 | 0 | } |
485 | | |
486 | | /* This is the nonce generator, which formerly lived in |
487 | | random-csprng.c. It is now used by all RNG types except when in |
488 | | FIPS mode (not that this means it is also used if the FIPS RNG |
489 | | has been selected but we are not in fips mode). */ |
490 | | |
491 | | /* Make sure we are initialized. */ |
492 | 1 | _gcry_random_initialize (1); |
493 | | |
494 | | /* Acquire the nonce buffer lock. */ |
495 | 1 | err = gpgrt_lock_lock (&nonce_buffer_lock); |
496 | 1 | if (err) |
497 | 0 | log_fatal ("failed to acquire the nonce buffer lock: %s\n", |
498 | 0 | gpg_strerror (err)); |
499 | | |
500 | 1 | apid = getpid (); |
501 | | /* The first time initialize our buffer. */ |
502 | 1 | if (!nonce_buffer_initialized) |
503 | 1 | { |
504 | 1 | time_t atime = time (NULL); |
505 | 1 | pid_t xpid = apid; |
506 | | |
507 | 1 | my_pid = apid; |
508 | | |
509 | 1 | if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) |
510 | 0 | BUG (); |
511 | | |
512 | | /* Initialize the first 20 bytes with a reasonable value so that |
513 | | a failure of gcry_randomize won't affect us too much. Don't |
514 | | care about the uninitialized remaining bytes. */ |
515 | 1 | p = nonce_buffer; |
516 | 1 | memcpy (p, &xpid, sizeof xpid); |
517 | 1 | p += sizeof xpid; |
518 | 1 | memcpy (p, &atime, sizeof atime); |
519 | | |
520 | | /* Initialize the never changing private part of 64 bits. */ |
521 | 1 | _gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); |
522 | | |
523 | 1 | nonce_buffer_initialized = 1; |
524 | 1 | } |
525 | 0 | else if ( my_pid != apid ) |
526 | 0 | { |
527 | | /* We forked. Need to reseed the buffer - doing this for the |
528 | | private part should be sufficient. */ |
529 | 0 | do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); |
530 | | /* Update the pid so that we won't run into here again and |
531 | | again. */ |
532 | 0 | my_pid = apid; |
533 | 0 | } |
534 | | |
535 | | /* Create the nonce by hashing the entire buffer, returning the hash |
536 | | and updating the first 20 bytes of the buffer with this hash. */ |
537 | 2 | for (p = buffer; length > 0; length -= n, p += n) |
538 | 1 | { |
539 | 1 | _gcry_sha1_hash_buffer (nonce_buffer, |
540 | 1 | nonce_buffer, sizeof nonce_buffer); |
541 | 1 | n = length > 20? 20 : length; |
542 | 1 | memcpy (p, nonce_buffer, n); |
543 | 1 | } |
544 | | |
545 | | /* Release the nonce buffer lock. */ |
546 | 1 | err = gpgrt_lock_unlock (&nonce_buffer_lock); |
547 | 1 | if (err) |
548 | 0 | log_fatal ("failed to release the nonce buffer lock: %s\n", |
549 | 0 | gpg_strerror (err)); |
550 | 1 | } |
551 | | |
552 | | |
553 | | /* Run the self-tests for the RNG. This is currently only implemented |
554 | | for the FIPS generator. */ |
555 | | gpg_error_t |
556 | | _gcry_random_selftest (selftest_report_func_t report) |
557 | 0 | { |
558 | 0 | if (fips_mode ()) |
559 | 0 | return _gcry_rngdrbg_selftest (report); |
560 | 0 | else |
561 | 0 | return 0; /* No selftests yet. */ |
562 | 0 | } |