Diffstat (limited to 'pwmanager/libcrypt/cipher/random.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/cipher/random.c | 1134 |
1 files changed, 1134 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/cipher/random.c b/pwmanager/libcrypt/cipher/random.c new file mode 100644 index 0000000..e0d04a4 --- a/dev/null +++ b/pwmanager/libcrypt/cipher/random.c | |||
@@ -0,0 +1,1134 @@ | |||
1 | /* random.c -random number generator | ||
2 | * Copyright (C) 1998, 2000, 2001, 2002, 2003 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, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
19 | */ | ||
20 | |||
21 | /**************** | ||
22 | * This random number generator is modelled after the one described in | ||
23 | * Peter Gutmann's paper: "Software Generation of Practically Strong | ||
24 | * Random Numbers". See also chapter 6 in his book "Cryptographic | ||
25 | * Security Architecture", New York, 2004, ISBN 0-387-95387-6. | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include <config.h> | ||
30 | #include <stdio.h> | ||
31 | #include <stdlib.h> | ||
32 | #include <assert.h> | ||
33 | #include <errno.h> | ||
34 | #include <string.h> | ||
35 | #include <sys/time.h> | ||
36 | #include <sys/types.h> | ||
37 | #include <sys/stat.h> | ||
38 | #include <unistd.h> | ||
39 | #include <fcntl.h> | ||
40 | #include <time.h> | ||
41 | #ifdefHAVE_GETHRTIME | ||
42 | #include <sys/times.h> | ||
43 | #endif | ||
44 | #ifdef HAVE_GETTIMEOFDAY | ||
45 | #include <sys/times.h> | ||
46 | #endif | ||
47 | #ifdef HAVE_GETRUSAGE | ||
48 | #include <sys/resource.h> | ||
49 | #endif | ||
50 | #ifdef __MINGW32__ | ||
51 | #include <process.h> | ||
52 | #endif | ||
53 | #include "g10lib.h" | ||
54 | #include "rmd.h" | ||
55 | #include "random.h" | ||
56 | #include "rand-internal.h" | ||
57 | #include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */ | ||
58 | #include "ath.h" | ||
59 | |||
60 | #ifndef RAND_MAX /* for SunOS */ | ||
61 | #define RAND_MAX 32767 | ||
62 | #endif | ||
63 | |||
64 | |||
65 | #if SIZEOF_UNSIGNED_LONG == 8 | ||
66 | #define ADD_VALUE 0xa5a5a5a5a5a5a5a5 | ||
67 | #elif SIZEOF_UNSIGNED_LONG == 4 | ||
68 | #define ADD_VALUE 0xa5a5a5a5 | ||
69 | #else | ||
70 | #error weird size for an unsigned long | ||
71 | #endif | ||
72 | |||
73 | #define BLOCKLEN 64 /* hash this amount of bytes */ | ||
74 | #define DIGESTLEN 20 /* into a digest of this length (rmd160) */ | ||
75 | /* poolblocks is the number of digests which make up the pool | ||
76 | * and poolsize must be a multiple of the digest length | ||
77 | * to make the AND operations faster, the size should also be | ||
78 | * a multiple of ulong | ||
79 | */ | ||
80 | #define POOLBLOCKS 30 | ||
81 | #define POOLSIZE (POOLBLOCKS*DIGESTLEN) | ||
82 | #if (POOLSIZE % SIZEOF_UNSIGNED_LONG) | ||
83 | #error Please make sure that poolsize is a multiple of ulong | ||
84 | #endif | ||
85 | #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG) | ||
86 | |||
87 | |||
88 | static int is_initialized; | ||
89 | #define MASK_LEVEL(a) do { (a) &= 3; } while(0) | ||
90 | static char *rndpool;/* allocated size is POOLSIZE+BLOCKLEN */ | ||
91 | static char *keypool;/* allocated size is POOLSIZE+BLOCKLEN */ | ||
92 | static size_t pool_readpos; | ||
93 | static size_t pool_writepos; | ||
94 | static int pool_filled; | ||
95 | static int pool_balance; | ||
96 | static int just_mixed; | ||
97 | static int did_initial_extra_seeding; | ||
98 | static char *seed_file_name; | ||
99 | static int allow_seed_file_update; | ||
100 | |||
101 | static int secure_alloc; | ||
102 | static int quick_test; | ||
103 | static int faked_rng; | ||
104 | |||
105 | static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER; | ||
106 | static int pool_is_locked; /* only used for assertion */ | ||
107 | |||
108 | static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER; | ||
109 | |||
110 | static byte *get_random_bytes( size_t nbytes, int level, int secure ); | ||
111 | static void read_pool( byte *buffer, size_t length, int level ); | ||
112 | static void add_randomness( const void *buffer, size_t length, int source ); | ||
113 | static void random_poll(void); | ||
114 | static void do_fast_random_poll (void); | ||
115 | static void read_random_source( int requester, size_t length, int level); | ||
116 | static int gather_faked( void (*add)(const void*, size_t, int), int requester, | ||
117 | size_t length, int level ); | ||
118 | |||
119 | static struct { | ||
120 | ulong mixrnd; | ||
121 | ulong mixkey; | ||
122 | ulong slowpolls; | ||
123 | ulong fastpolls; | ||
124 | ulong getbytes1; | ||
125 | ulong ngetbytes1; | ||
126 | ulong getbytes2; | ||
127 | ulong ngetbytes2; | ||
128 | ulong addbytes; | ||
129 | ulong naddbytes; | ||
130 | } rndstats; | ||
131 | |||
132 | static void (*progress_cb) (void *,const char*,int,int, int ); | ||
133 | static void *progress_cb_data; | ||
134 | |||
135 | /* Note, we assume that this function is used before any concurrent | ||
136 | access happens. */ | ||
137 | static void | ||
138 | initialize(void) | ||
139 | { | ||
140 | int err; | ||
141 | |||
142 | err = ath_mutex_init (&pool_lock); | ||
143 | if (err) | ||
144 | log_fatal ("failed to create the pool lock: %s\n", strerror (err) ); | ||
145 | |||
146 | err = ath_mutex_init (&nonce_buffer_lock); | ||
147 | if (err) | ||
148 | log_fatal ("failed to create the nonce buffer lock: %s\n", | ||
149 | strerror (err) ); | ||
150 | |||
151 | /* The data buffer is allocated somewhat larger, so that we can use | ||
152 | this extra space (which is allocated in secure memory) as a | ||
153 | temporary hash buffer */ | ||
154 | rndpool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) | ||
155 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); | ||
156 | keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) | ||
157 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); | ||
158 | is_initialized = 1; | ||
159 | |||
160 | } | ||
161 | |||
162 | |||
163 | /* Used to register a progress callback. */ | ||
164 | void | ||
165 | _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), | ||
166 | void *cb_data ) | ||
167 | { | ||
168 | progress_cb = cb; | ||
169 | progress_cb_data = cb_data; | ||
170 | } | ||
171 | |||
172 | |||
173 | /* This progress function is currently used by the random modules to give hint | ||
174 | on how much more entropy is required. */ | ||
175 | void | ||
176 | _gcry_random_progress (const char *what, int printchar, int current, int total) | ||
177 | { | ||
178 | if (progress_cb) | ||
179 | progress_cb (progress_cb_data, what, printchar, current, total); | ||
180 | } | ||
181 | |||
182 | |||
183 | /* Initialize this random subsystem. This function merely calls the | ||
184 | initialize and does not do anything more. Doing this is not really | ||
185 | required but when running in a threaded environment we might get a | ||
186 | race condition otherwise. */ | ||
187 | void | ||
188 | _gcry_random_initialize () | ||
189 | { | ||
190 | if (!is_initialized) | ||
191 | initialize (); | ||
192 | } | ||
193 | |||
194 | void | ||
195 | _gcry_random_dump_stats() | ||
196 | { | ||
197 | log_info ( | ||
198 | "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n" | ||
199 | " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n", | ||
200 | POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls, | ||
201 | rndstats.naddbytes, rndstats.addbytes, | ||
202 | rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, | ||
203 | rndstats.ngetbytes2, rndstats.getbytes2 ); | ||
204 | } | ||
205 | |||
206 | void | ||
207 | _gcry_secure_random_alloc() | ||
208 | { | ||
209 | secure_alloc = 1; | ||
210 | } | ||
211 | |||
212 | |||
213 | int | ||
214 | _gcry_quick_random_gen( int onoff ) | ||
215 | { | ||
216 | int last; | ||
217 | |||
218 | /* No need to lock it here because we are only initializing. A | ||
219 | prerequisite of the entire code is that it has already been | ||
220 | initialized before any possible concurrent access */ | ||
221 | read_random_source(0,0,0); /* init */ | ||
222 | last = quick_test; | ||
223 | if( onoff != -1 ) | ||
224 | quick_test = onoff; | ||
225 | return faked_rng? 1 : last; | ||
226 | } | ||
227 | |||
228 | int | ||
229 | _gcry_random_is_faked() | ||
230 | { | ||
231 | if( !is_initialized ) | ||
232 | initialize(); | ||
233 | return (faked_rng || quick_test); | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * Return a pointer to a randomized buffer of LEVEL and NBYTES length. | ||
238 | * Caller must free the buffer. | ||
239 | */ | ||
240 | static byte * | ||
241 | get_random_bytes ( size_t nbytes, int level, int secure) | ||
242 | { | ||
243 | byte *buf, *p; | ||
244 | int err; | ||
245 | |||
246 | /* First a hack toavoid the strong random using our regression test suite. */ | ||
247 | if (quick_test && level > 1) | ||
248 | level = 1; | ||
249 | |||
250 | /* Make sure the requested level is in range. */ | ||
251 | MASK_LEVEL(level); | ||
252 | |||
253 | /* Lock the pool. */ | ||
254 | err = ath_mutex_lock (&pool_lock); | ||
255 | if (err) | ||
256 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | ||
257 | pool_is_locked = 1; | ||
258 | |||
259 | /* Keep some statistics. */ | ||
260 | if (level >= 2) | ||
261 | { | ||
262 | rndstats.getbytes2 += nbytes; | ||
263 | rndstats.ngetbytes2++; | ||
264 | } | ||
265 | else | ||
266 | { | ||
267 | rndstats.getbytes1 += nbytes; | ||
268 | rndstats.ngetbytes1++; | ||
269 | } | ||
270 | |||
271 | /* Allocate the return buffer. */ | ||
272 | buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes ) | ||
273 | : gcry_xmalloc( nbytes ); | ||
274 | |||
275 | /* Fill that buffer with random. */ | ||
276 | for (p = buf; nbytes > 0; ) | ||
277 | { | ||
278 | size_t n; | ||
279 | |||
280 | n = nbytes > POOLSIZE? POOLSIZE : nbytes; | ||
281 | read_pool( p, n, level ); | ||
282 | nbytes -= n; | ||
283 | p += n; | ||
284 | } | ||
285 | |||
286 | /* Release the pool lock. */ | ||
287 | pool_is_locked = 0; | ||
288 | err = ath_mutex_unlock (&pool_lock); | ||
289 | if (err) | ||
290 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | ||
291 | |||
292 | /* Return the buffer. */ | ||
293 | return buf; | ||
294 | } | ||
295 | |||
296 | |||
297 | /* Add BUFLEN bytes from BUF to the internal random pool. QUALITY | ||
298 | should be in the range of 0..100 to indicate the goodness of the | ||
299 | entropy added, or -1 for goodness not known. | ||
300 | |||
301 | Note, that this function currently does nothing. | ||
302 | */ | ||
303 | gcry_error_t | ||
304 | gcry_random_add_bytes (const void * buf, size_t buflen, int quality) | ||
305 | { | ||
306 | gcry_err_code_t err = GPG_ERR_NO_ERROR; | ||
307 | |||
308 | if (!buf || quality < -1 || quality > 100) | ||
309 | err = GPG_ERR_INV_ARG; | ||
310 | if (!buflen) | ||
311 | return 0; /* Shortcut this dummy case. */ | ||
312 | #if 0 | ||
313 | /* Before we actuall enable this code, we need to lock the pool, | ||
314 | have a look at the quality and find a way to add them without | ||
315 | disturbing the real entropy (we have estimated). */ | ||
316 | /*add_randomness( buf, buflen, 1 );*/ | ||
317 | #endif | ||
318 | return err; | ||
319 | } | ||
320 | |||
321 | /* The public function to return random data of the quality LEVEL. */ | ||
322 | void * | ||
323 | gcry_random_bytes( size_t nbytes, enum gcry_random_level level ) | ||
324 | { | ||
325 | if (!is_initialized) | ||
326 | initialize(); | ||
327 | return get_random_bytes( nbytes, level, 0 ); | ||
328 | } | ||
329 | |||
330 | /* The public function to return random data of the quality LEVEL; | ||
331 | this version of the function retrun the random a buffer allocated | ||
332 | in secure memory. */ | ||
333 | void * | ||
334 | gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ) | ||
335 | { | ||
336 | if (!is_initialized) | ||
337 | initialize(); | ||
338 | return get_random_bytes( nbytes, level, 1 ); | ||
339 | } | ||
340 | |||
341 | |||
342 | /* Public function to fill the buffer with LENGTH bytes of | ||
343 | cryptographically strong random bytes. level 0 is not very strong, | ||
344 | 1 is strong enough for most usage, 2 is good for key generation | ||
345 | stuff but may be very slow. */ | ||
346 | void | ||
347 | gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level) | ||
348 | { | ||
349 | byte *p; | ||
350 | int err; | ||
351 | |||
352 | /* Make sure we are initialized. */ | ||
353 | if (!is_initialized) | ||
354 | initialize (); | ||
355 | |||
356 | /* Handle our hack used for regression tests of Libgcrypt. */ | ||
357 | if( quick_test && level > 1 ) | ||
358 | level = 1; | ||
359 | |||
360 | /* Make sure the level is okay. */ | ||
361 | MASK_LEVEL(level); | ||
362 | |||
363 | /* Acquire the pool lock. */ | ||
364 | err = ath_mutex_lock (&pool_lock); | ||
365 | if (err) | ||
366 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | ||
367 | pool_is_locked = 1; | ||
368 | |||
369 | /* Update the statistics. */ | ||
370 | if (level >= 2) | ||
371 | { | ||
372 | rndstats.getbytes2 += length; | ||
373 | rndstats.ngetbytes2++; | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | rndstats.getbytes1 += length; | ||
378 | rndstats.ngetbytes1++; | ||
379 | } | ||
380 | |||
381 | /* Read the random into the provided buffer. */ | ||
382 | for (p = buffer; length > 0;) | ||
383 | { | ||
384 | size_t n; | ||
385 | |||
386 | n = length > POOLSIZE? POOLSIZE : length; | ||
387 | read_pool (p, n, level); | ||
388 | length -= n; | ||
389 | p += n; | ||
390 | } | ||
391 | |||
392 | /* Release the pool lock. */ | ||
393 | pool_is_locked = 0; | ||
394 | err = ath_mutex_unlock (&pool_lock); | ||
395 | if (err) | ||
396 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | ||
397 | |||
398 | } | ||
399 | |||
400 | |||
401 | |||
402 | |||
403 | /* | ||
404 | Mix the pool: | ||
405 | |||
406 | |........blocks*20byte........|20byte|..44byte..| | ||
407 | <..44byte..> <20byte> | ||
408 | | | | ||
409 | | +------+ | ||
410 | +---------------------------|----------+ | ||
411 | v v | ||
412 | |........blocks*20byte........|20byte|..44byte..| | ||
413 | <.....64bytes.....> | ||
414 | | | ||
415 | +----------------------------------+ | ||
416 | Hash | ||
417 | v | ||
418 | |.............................|20byte|..44byte..| | ||
419 | <20byte><20byte><..44byte..> | ||
420 | | | | ||
421 | | +---------------------+ | ||
422 | +-----------------------------+ | | ||
423 | v v | ||
424 | |.............................|20byte|..44byte..| | ||
425 | <.....64byte......> | ||
426 | | | ||
427 | +-------------------------+ | ||
428 | Hash | ||
429 | v | ||
430 | |.............................|20byte|..44byte..| | ||
431 | <20byte><20byte><..44byte..> | ||
432 | |||
433 | and so on until we did this for all blocks. | ||
434 | |||
435 | To better protect against implementation errors in this code, we | ||
436 | xor a digest of the entire pool into the pool before mixing. | ||
437 | |||
438 | Note, that this function muts only be called with a locked pool. | ||
439 | */ | ||
440 | static void | ||
441 | mix_pool(byte *pool) | ||
442 | { | ||
443 | static unsigned char failsafe_digest[DIGESTLEN]; | ||
444 | static int failsafe_digest_valid; | ||
445 | |||
446 | char *hashbuf = pool + POOLSIZE; | ||
447 | char *p, *pend; | ||
448 | int i, n; | ||
449 | RMD160_CONTEXT md; | ||
450 | |||
451 | #if DIGESTLEN != 20 | ||
452 | #error must have a digest length of 20 for ripe-md-160 | ||
453 | #endif | ||
454 | |||
455 | assert (pool_is_locked); | ||
456 | _gcry_rmd160_init( &md ); | ||
457 | |||
458 | /* loop over the pool */ | ||
459 | pend = pool + POOLSIZE; | ||
460 | memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); | ||
461 | memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); | ||
462 | _gcry_rmd160_mixblock( &md, hashbuf); | ||
463 | memcpy(pool, hashbuf, 20 ); | ||
464 | |||
465 | if (failsafe_digest_valid && (char *)pool == rndpool) | ||
466 | { | ||
467 | for (i=0; i < 20; i++) | ||
468 | pool[i] ^= failsafe_digest[i]; | ||
469 | } | ||
470 | |||
471 | p = pool; | ||
472 | for (n=1; n < POOLBLOCKS; n++) | ||
473 | { | ||
474 | memcpy (hashbuf, p, DIGESTLEN); | ||
475 | |||
476 | p += DIGESTLEN; | ||
477 | if (p+DIGESTLEN+BLOCKLEN < pend) | ||
478 | memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); | ||
479 | else | ||
480 | { | ||
481 | char *pp = p + DIGESTLEN; | ||
482 | |||
483 | for (i=DIGESTLEN; i < BLOCKLEN; i++ ) | ||
484 | { | ||
485 | if ( pp >= pend ) | ||
486 | pp = pool; | ||
487 | hashbuf[i] = *pp++; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | _gcry_rmd160_mixblock( &md, hashbuf); | ||
492 | memcpy(p, hashbuf, 20 ); | ||
493 | } | ||
494 | |||
495 | /* Our hash implementation does only leave small parts (64 bytes) | ||
496 | of the pool on the stack, so it is okay not to require secure | ||
497 | memory here. Before we use this pool, it will be copied to the | ||
498 | help buffer anyway. */ | ||
499 | if ( (char*)pool == rndpool) | ||
500 | { | ||
501 | _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE); | ||
502 | failsafe_digest_valid = 1; | ||
503 | } | ||
504 | |||
505 | _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */ | ||
506 | } | ||
507 | |||
508 | |||
509 | void | ||
510 | _gcry_set_random_seed_file( const char *name ) | ||
511 | { | ||
512 | if (seed_file_name) | ||
513 | BUG (); | ||
514 | seed_file_name = gcry_xstrdup (name); | ||
515 | } | ||
516 | |||
517 | |||
518 | /* | ||
519 | Read in a seed form the random_seed file | ||
520 | and return true if this was successful. | ||
521 | */ | ||
522 | static int | ||
523 | read_seed_file (void) | ||
524 | { | ||
525 | int fd; | ||
526 | struct stat sb; | ||
527 | unsigned char buffer[POOLSIZE]; | ||
528 | int n; | ||
529 | |||
530 | assert (pool_is_locked); | ||
531 | |||
532 | if (!seed_file_name) | ||
533 | return 0; | ||
534 | |||
535 | #ifdef HAVE_DOSISH_SYSTEM | ||
536 | fd = open( seed_file_name, O_RDONLY | O_BINARY ); | ||
537 | #else | ||
538 | fd = open( seed_file_name, O_RDONLY ); | ||
539 | #endif | ||
540 | if( fd == -1 && errno == ENOENT) | ||
541 | { | ||
542 | allow_seed_file_update = 1; | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | if (fd == -1 ) | ||
547 | { | ||
548 | log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) ); | ||
549 | return 0; | ||
550 | } | ||
551 | if (fstat( fd, &sb ) ) | ||
552 | { | ||
553 | log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) ); | ||
554 | close(fd); | ||
555 | return 0; | ||
556 | } | ||
557 | if (!S_ISREG(sb.st_mode) ) | ||
558 | { | ||
559 | log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name ); | ||
560 | close(fd); | ||
561 | return 0; | ||
562 | } | ||
563 | if (!sb.st_size ) | ||
564 | { | ||
565 | log_info(_("note: random_seed file is empty\n") ); | ||
566 | close(fd); | ||
567 | allow_seed_file_update = 1; | ||
568 | return 0; | ||
569 | } | ||
570 | if (sb.st_size != POOLSIZE ) | ||
571 | { | ||
572 | log_info(_("warning: invalid size of random_seed file - not used\n") ); | ||
573 | close(fd); | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | do | ||
578 | { | ||
579 | n = read( fd, buffer, POOLSIZE ); | ||
580 | } | ||
581 | while (n == -1 && errno == EINTR ); | ||
582 | |||
583 | if (n != POOLSIZE) | ||
584 | { | ||
585 | log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); | ||
586 | close(fd);/*NOTREACHED*/ | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | close(fd); | ||
591 | |||
592 | add_randomness( buffer, POOLSIZE, 0 ); | ||
593 | /* add some minor entropy to the pool now (this will also force a mixing) */ | ||
594 | { | ||
595 | pid_t x = getpid(); | ||
596 | add_randomness( &x, sizeof(x), 0 ); | ||
597 | } | ||
598 | { | ||
599 | time_t x = time(NULL); | ||
600 | add_randomness( &x, sizeof(x), 0 ); | ||
601 | } | ||
602 | { | ||
603 | clock_t x = clock(); | ||
604 | add_randomness( &x, sizeof(x), 0 ); | ||
605 | } | ||
606 | |||
607 | /* And read a few bytes from our entropy source. By using a level | ||
608 | * of 0 this will not block and might not return anything with some | ||
609 | * entropy drivers, however the rndlinux driver will use | ||
610 | * /dev/urandom and return some stuff - Do not read to much as we | ||
611 | * want to be friendly to the scare system entropy resource. */ | ||
612 | read_random_source( 0, 16, 0 ); | ||
613 | |||
614 | allow_seed_file_update = 1; | ||
615 | return 1; | ||
616 | } | ||
617 | |||
618 | |||
619 | void | ||
620 | _gcry_update_random_seed_file() | ||
621 | { | ||
622 | ulong *sp, *dp; | ||
623 | int fd, i; | ||
624 | int err; | ||
625 | |||
626 | if ( !seed_file_name || !is_initialized || !pool_filled ) | ||
627 | return; | ||
628 | if ( !allow_seed_file_update ) | ||
629 | { | ||
630 | log_info(_("note: random_seed file not updated\n")); | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | err = ath_mutex_lock (&pool_lock); | ||
635 | if (err) | ||
636 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | ||
637 | pool_is_locked = 1; | ||
638 | |||
639 | /* copy the entropy pool to a scratch pool and mix both of them */ | ||
640 | for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; | ||
641 | i < POOLWORDS; i++, dp++, sp++ ) | ||
642 | { | ||
643 | *dp = *sp + ADD_VALUE; | ||
644 | } | ||
645 | mix_pool(rndpool); rndstats.mixrnd++; | ||
646 | mix_pool(keypool); rndstats.mixkey++; | ||
647 | |||
648 | #ifdef HAVE_DOSISH_SYSTEM | ||
649 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, | ||
650 | S_IRUSR|S_IWUSR ); | ||
651 | #else | ||
652 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); | ||
653 | #endif | ||
654 | |||
655 | if (fd == -1 ) | ||
656 | log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) ); | ||
657 | else | ||
658 | { | ||
659 | do | ||
660 | { | ||
661 | i = write (fd, keypool, POOLSIZE ); | ||
662 | } | ||
663 | while( i == -1 && errno == EINTR ); | ||
664 | if (i != POOLSIZE) | ||
665 | log_info (_("can't write `%s': %s\n"), | ||
666 | seed_file_name, strerror(errno) ); | ||
667 | if (close(fd)) | ||
668 | log_info(_("can't close `%s': %s\n"), | ||
669 | seed_file_name, strerror(errno) ); | ||
670 | } | ||
671 | |||
672 | pool_is_locked = 0; | ||
673 | err = ath_mutex_unlock (&pool_lock); | ||
674 | if (err) | ||
675 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | ||
676 | |||
677 | } | ||
678 | |||
679 | |||
680 | /* Read random out of the pool. This function is the core of the | ||
681 | public random fucntions. Note that Level 0 is not anymore handeld | ||
682 | special and in fact an alias for level 1. */ | ||
683 | static void | ||
684 | read_pool (byte *buffer, size_t length, int level) | ||
685 | { | ||
686 | int i; | ||
687 | unsigned long *sp, *dp; | ||
688 | volatile pid_t my_pid; /* The volatile is there to make sure the | ||
689 | compiler does not optimize the code away | ||
690 | in case the getpid function is badly | ||
691 | attributed. */ | ||
692 | |||
693 | retry: | ||
694 | /* Get our own pid, so that we can detect a fork. */ | ||
695 | my_pid = getpid (); | ||
696 | |||
697 | assert (pool_is_locked); | ||
698 | |||
699 | /* Our code does not allow to extract more than POOLSIZE. Better | ||
700 | check it here. */ | ||
701 | if (length > POOLSIZE) | ||
702 | { | ||
703 | log_bug("too many random bits requested\n"); | ||
704 | } | ||
705 | |||
706 | if (!pool_filled) | ||
707 | { | ||
708 | if (read_seed_file() ) | ||
709 | pool_filled = 1; | ||
710 | } | ||
711 | |||
712 | /* For level 2 quality (key generation) we always make sure that the | ||
713 | pool has been seeded enough initially. */ | ||
714 | if (level == 2 && !did_initial_extra_seeding) | ||
715 | { | ||
716 | size_t needed; | ||
717 | |||
718 | pool_balance = 0; | ||
719 | needed = length - pool_balance; | ||
720 | if (needed < POOLSIZE/2) | ||
721 | needed = POOLSIZE/2; | ||
722 | else if( needed > POOLSIZE ) | ||
723 | BUG (); | ||
724 | read_random_source (3, needed, 2); | ||
725 | pool_balance += needed; | ||
726 | did_initial_extra_seeding = 1; | ||
727 | } | ||
728 | |||
729 | /* For level 2 make sure that there is enough random in the pool. */ | ||
730 | if (level == 2 && pool_balance < length) | ||
731 | { | ||
732 | size_t needed; | ||
733 | |||
734 | if (pool_balance < 0) | ||
735 | pool_balance = 0; | ||
736 | needed = length - pool_balance; | ||
737 | if (needed > POOLSIZE) | ||
738 | BUG (); | ||
739 | read_random_source( 3, needed, 2 ); | ||
740 | pool_balance += needed; | ||
741 | } | ||
742 | |||
743 | /* make sure the pool is filled */ | ||
744 | while (!pool_filled) | ||
745 | random_poll(); | ||
746 | |||
747 | /* Always do a fast random poll (we have to use the unlocked version). */ | ||
748 | do_fast_random_poll(); | ||
749 | |||
750 | /* Mix the pool (if add_randomness() didn't it). */ | ||
751 | if (!just_mixed) | ||
752 | { | ||
753 | mix_pool(rndpool); | ||
754 | rndstats.mixrnd++; | ||
755 | } | ||
756 | |||
757 | /* Create a new pool. */ | ||
758 | for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; | ||
759 | i < POOLWORDS; i++, dp++, sp++ ) | ||
760 | *dp = *sp + ADD_VALUE; | ||
761 | |||
762 | /* Mix both pools. */ | ||
763 | mix_pool(rndpool); rndstats.mixrnd++; | ||
764 | mix_pool(keypool); rndstats.mixkey++; | ||
765 | |||
766 | /* Read the required data. We use a readpoiter to read from a | ||
767 | different position each time */ | ||
768 | while (length--) | ||
769 | { | ||
770 | *buffer++ = keypool[pool_readpos++]; | ||
771 | if (pool_readpos >= POOLSIZE) | ||
772 | pool_readpos = 0; | ||
773 | pool_balance--; | ||
774 | } | ||
775 | |||
776 | if (pool_balance < 0) | ||
777 | pool_balance = 0; | ||
778 | |||
779 | /* Clear the keypool. */ | ||
780 | memset (keypool, 0, POOLSIZE); | ||
781 | |||
782 | /* We need to detect whether a fork has happened. A fork might have | ||
783 | an identical pool and thus the child and the parent could emit | ||
784 | the very same random number. Obviously this can only happen when | ||
785 | running multi-threaded and the pool lock should even catch this. | ||
786 | However things do get wrong and thus we better check and retry it | ||
787 | here. We assume that the thread library has no other fatal | ||
788 | faults, though. | ||
789 | */ | ||
790 | if ( getpid () != my_pid ) | ||
791 | goto retry; | ||
792 | } | ||
793 | |||
794 | |||
795 | /* | ||
796 | * Add LENGTH bytes of randomness from buffer to the pool. | ||
797 | * source may be used to specify the randomness source. | ||
798 | * Source is: | ||
799 | *0 - used ony for initialization | ||
800 | *1 - fast random poll function | ||
801 | *2 - normal poll function | ||
802 | *3 - used when level 2 random quality has been requested | ||
803 | * to do an extra pool seed. | ||
804 | */ | ||
805 | static void | ||
806 | add_randomness( const void *buffer, size_t length, int source ) | ||
807 | { | ||
808 | const byte *p = buffer; | ||
809 | |||
810 | assert (pool_is_locked); | ||
811 | if (!is_initialized) | ||
812 | initialize (); | ||
813 | rndstats.addbytes += length; | ||
814 | rndstats.naddbytes++; | ||
815 | while (length-- ) | ||
816 | { | ||
817 | rndpool[pool_writepos++] ^= *p++; | ||
818 | if (pool_writepos >= POOLSIZE ) | ||
819 | { | ||
820 | if (source > 1) | ||
821 | pool_filled = 1; | ||
822 | pool_writepos = 0; | ||
823 | mix_pool(rndpool); rndstats.mixrnd++; | ||
824 | just_mixed = !length; | ||
825 | } | ||
826 | } | ||
827 | } | ||
828 | |||
829 | |||
830 | |||
831 | static void | ||
832 | random_poll() | ||
833 | { | ||
834 | rndstats.slowpolls++; | ||
835 | read_random_source (2, POOLSIZE/5, 1); | ||
836 | } | ||
837 | |||
838 | |||
839 | static int (* | ||
840 | getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, | ||
841 | size_t, int) | ||
842 | { | ||
843 | static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int); | ||
844 | |||
845 | if (fnc) | ||
846 | return fnc; | ||
847 | |||
848 | #if USE_RNDLINUX | ||
849 | if ( !access (NAME_OF_DEV_RANDOM, R_OK) | ||
850 | && !access (NAME_OF_DEV_URANDOM, R_OK)) | ||
851 | { | ||
852 | fnc = _gcry_rndlinux_gather_random; | ||
853 | return fnc; | ||
854 | } | ||
855 | #endif | ||
856 | |||
857 | #if USE_RNDEGD | ||
858 | if ( _gcry_rndegd_connect_socket (1) != -1 ) | ||
859 | { | ||
860 | fnc = _gcry_rndegd_gather_random; | ||
861 | return fnc; | ||
862 | } | ||
863 | #endif | ||
864 | |||
865 | #if USE_RNDUNIX | ||
866 | fnc = _gcry_rndunix_gather_random; | ||
867 | return fnc; | ||
868 | #endif | ||
869 | |||
870 | #if USE_RNDW32 | ||
871 | fnc = _gcry_rndw32_gather_random; | ||
872 | return fnc; | ||
873 | #endif | ||
874 | |||
875 | log_fatal (_("no entropy gathering module detected\n")); | ||
876 | |||
877 | return NULL; /*NOTREACHED*/ | ||
878 | } | ||
879 | |||
880 | static void (* | ||
881 | getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int) | ||
882 | { | ||
883 | #if USE_RNDW32 | ||
884 | return _gcry_rndw32_gather_random_fast; | ||
885 | #endif | ||
886 | return NULL; | ||
887 | } | ||
888 | |||
889 | |||
890 | static void | ||
891 | do_fast_random_poll (void) | ||
892 | { | ||
893 | static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; | ||
894 | static int initialized = 0; | ||
895 | |||
896 | assert (pool_is_locked); | ||
897 | |||
898 | rndstats.fastpolls++; | ||
899 | |||
900 | if (!initialized ) | ||
901 | { | ||
902 | if (!is_initialized ) | ||
903 | initialize(); | ||
904 | initialized = 1; | ||
905 | fnc = getfnc_fast_random_poll (); | ||
906 | } | ||
907 | |||
908 | if (fnc) | ||
909 | (*fnc)( add_randomness, 1 ); | ||
910 | |||
911 | /* Continue with the generic functions. */ | ||
912 | #if HAVE_GETHRTIME | ||
913 | { | ||
914 | hrtime_t tv; | ||
915 | tv = gethrtime(); | ||
916 | add_randomness( &tv, sizeof(tv), 1 ); | ||
917 | } | ||
918 | #elif HAVE_GETTIMEOFDAY | ||
919 | { | ||
920 | struct timeval tv; | ||
921 | if( gettimeofday( &tv, NULL ) ) | ||
922 | BUG(); | ||
923 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); | ||
924 | add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 ); | ||
925 | } | ||
926 | #elif HAVE_CLOCK_GETTIME | ||
927 | {struct timespec tv; | ||
928 | if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) | ||
929 | BUG(); | ||
930 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); | ||
931 | add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 ); | ||
932 | } | ||
933 | #else /* use times */ | ||
934 | # ifndef HAVE_DOSISH_SYSTEM | ||
935 | {struct tms buf; | ||
936 | times( &buf ); | ||
937 | add_randomness( &buf, sizeof buf, 1 ); | ||
938 | } | ||
939 | # endif | ||
940 | #endif | ||
941 | |||
942 | #ifdef HAVE_GETRUSAGE | ||
943 | # ifdef RUSAGE_SELF | ||
944 | { | ||
945 | struct rusage buf; | ||
946 | /* QNX/Neutrino does return ENOSYS - so we just ignore it and | ||
947 | * add whatever is in buf. In a chroot environment it might not | ||
948 | * work at all (i.e. because /proc/ is not accessible), so we better | ||
949 | * ugnore all error codes and hope for the best | ||
950 | */ | ||
951 | getrusage (RUSAGE_SELF, &buf ); | ||
952 | add_randomness( &buf, sizeof buf, 1 ); | ||
953 | memset( &buf, 0, sizeof buf ); | ||
954 | } | ||
955 | # else /*!RUSAGE_SELF*/ | ||
956 | # ifdef __GCC__ | ||
957 | # warning There is no RUSAGE_SELF on this system | ||
958 | # endif | ||
959 | # endif /*!RUSAGE_SELF*/ | ||
960 | #endif /*HAVE_GETRUSAGE*/ | ||
961 | |||
962 | /* time and clock are availabe on all systems - so we better do it | ||
963 | just in case one of the above functions didn't work */ | ||
964 | { | ||
965 | time_t x = time(NULL); | ||
966 | add_randomness( &x, sizeof(x), 1 ); | ||
967 | } | ||
968 | { | ||
969 | clock_t x = clock(); | ||
970 | add_randomness( &x, sizeof(x), 1 ); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | |||
975 | /* The fast random pool function as called at some places in | ||
976 | libgcrypt. This is merely a wrapper to make sure that this module | ||
977 | is initalized and to look the pool. */ | ||
978 | void | ||
979 | _gcry_fast_random_poll (void) | ||
980 | { | ||
981 | int err; | ||
982 | |||
983 | /* We have to make sure that the intialization is done because this | ||
984 | gatherer might be called before any other functions and it is not | ||
985 | sufficient to initialize it within do_fast_random_pool because we | ||
986 | want to use the mutex here. FIXME: Whe should initialize the | ||
987 | mutex using a global constructor independent from the | ||
988 | initialization of the pool. */ | ||
989 | if (!is_initialized) | ||
990 | initialize (); | ||
991 | err = ath_mutex_lock (&pool_lock); | ||
992 | if (err) | ||
993 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | ||
994 | pool_is_locked = 1; | ||
995 | |||
996 | do_fast_random_poll (); | ||
997 | |||
998 | pool_is_locked = 0; | ||
999 | err = ath_mutex_unlock (&pool_lock); | ||
1000 | if (err) | ||
1001 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | ||
1002 | |||
1003 | } | ||
1004 | |||
1005 | |||
1006 | |||
1007 | static void | ||
1008 | read_random_source( int requester, size_t length, int level ) | ||
1009 | { | ||
1010 | static int (*fnc)(void (*)(const void*, size_t, int), int, | ||
1011 | size_t, int) = NULL; | ||
1012 | if (!fnc ) | ||
1013 | { | ||
1014 | if (!is_initialized ) | ||
1015 | initialize(); | ||
1016 | |||
1017 | fnc = getfnc_gather_random (); | ||
1018 | |||
1019 | if (!fnc) | ||
1020 | { | ||
1021 | faked_rng = 1; | ||
1022 | fnc = gather_faked; | ||
1023 | } | ||
1024 | if (!requester && !length && !level) | ||
1025 | return; /* Just the init was requested. */ | ||
1026 | } | ||
1027 | |||
1028 | if ((*fnc)( add_randomness, requester, length, level ) < 0) | ||
1029 | log_fatal ("No way to gather entropy for the RNG\n"); | ||
1030 | } | ||
1031 | |||
1032 | |||
1033 | static int | ||
1034 | gather_faked( void (*add)(const void*, size_t, int), int requester, | ||
1035 | size_t length, int level ) | ||
1036 | { | ||
1037 | static int initialized=0; | ||
1038 | size_t n; | ||
1039 | char *buffer, *p; | ||
1040 | |||
1041 | if( !initialized ) { | ||
1042 | log_info(_("WARNING: using insecure random number generator!!\n")); | ||
1043 | /* we can't use tty_printf here - do we need this function at | ||
1044 | all - does it really make sense or canit be viewed as a potential | ||
1045 | security problem ? wk 17.11.99 */ | ||
1046 | #if 0 | ||
1047 | tty_printf(_("The random number generator is only a kludge to let\n" | ||
1048 | "it run - it is in no way a strong RNG!\n\n" | ||
1049 | "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n")); | ||
1050 | #endif | ||
1051 | initialized=1; | ||
1052 | #ifdef HAVE_RAND | ||
1053 | srand( time(NULL)*getpid()); | ||
1054 | #else | ||
1055 | srandom( time(NULL)*getpid()); | ||
1056 | #endif | ||
1057 | } | ||
1058 | |||
1059 | p = buffer = gcry_xmalloc( length ); | ||
1060 | n = length; | ||
1061 | #ifdef HAVE_RAND | ||
1062 | while( n-- ) | ||
1063 | *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); | ||
1064 | #else | ||
1065 | while( n-- ) | ||
1066 | *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); | ||
1067 | #endif | ||
1068 | add_randomness( buffer, length, requester ); | ||
1069 | gcry_free(buffer); | ||
1070 | return 0; /* okay */ | ||
1071 | } | ||
1072 | |||
1073 | |||
1074 | /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ | ||
1075 | void | ||
1076 | gcry_create_nonce (unsigned char *buffer, size_t length) | ||
1077 | { | ||
1078 | static unsigned char nonce_buffer[20+8]; | ||
1079 | static int nonce_buffer_initialized = 0; | ||
1080 | unsigned char *p; | ||
1081 | size_t n; | ||
1082 | int err; | ||
1083 | |||
1084 | /* Make sure we are initialized. */ | ||
1085 | if (!is_initialized) | ||
1086 | initialize (); | ||
1087 | |||
1088 | /* Acquire the nonce buffer lock. */ | ||
1089 | err = ath_mutex_lock (&nonce_buffer_lock); | ||
1090 | if (err) | ||
1091 | log_fatal ("failed to acquire the nonce buffer lock: %s\n", | ||
1092 | strerror (err)); | ||
1093 | |||
1094 | /* The first time intialize our buffer. */ | ||
1095 | if (!nonce_buffer_initialized) | ||
1096 | { | ||
1097 | pid_t apid = getpid (); | ||
1098 | time_t atime = time (NULL); | ||
1099 | |||
1100 | if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) | ||
1101 | BUG (); | ||
1102 | |||
1103 | /* Initialize the first 20 bytes with a reasonable value so that | ||
1104 | a failure of gcry_randomize won't affect us too much. Don't | ||
1105 | care about the uninitialized remaining bytes. */ | ||
1106 | p = nonce_buffer; | ||
1107 | memcpy (p, &apid, sizeof apid); | ||
1108 | p += sizeof apid; | ||
1109 | memcpy (p, &atime, sizeof atime); | ||
1110 | |||
1111 | /* Initialize the never changing private part of 64 bits. */ | ||
1112 | gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); | ||
1113 | |||
1114 | nonce_buffer_initialized = 1; | ||
1115 | } | ||
1116 | |||
1117 | /* Create the nonce by hashing the entire buffer, returning the hash | ||
1118 | and updating the first 20 bytes of the buffer with this hash. */ | ||
1119 | for (p = buffer; length > 0; length -= n, p += n) | ||
1120 | { | ||
1121 | _gcry_sha1_hash_buffer (nonce_buffer, | ||
1122 | nonce_buffer, sizeof nonce_buffer); | ||
1123 | n = length > 20? 20 : length; | ||
1124 | memcpy (p, nonce_buffer, n); | ||
1125 | } | ||
1126 | |||
1127 | |||
1128 | /* Release the nonce buffer lock. */ | ||
1129 | err = ath_mutex_unlock (&nonce_buffer_lock); | ||
1130 | if (err) | ||
1131 | log_fatal ("failed to release the nonce buffer lock: %s\n", | ||
1132 | strerror (err)); | ||
1133 | |||
1134 | } | ||