e34e1addbb48faf2b301421b005941fb3dd6bcc5
[libgcrypt.git] / cipher / random.c
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
23  * in Peter Gutmann's Paper: "Software Generation of Practically
24  * Strong Random Numbers".
25  */
26
27
28 #include <config.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <time.h>
40 #ifdef  HAVE_GETHRTIME
41 #include <sys/times.h>
42 #endif
43 #ifdef HAVE_GETTIMEOFDAY
44 #include <sys/times.h>
45 #endif
46 #ifdef HAVE_GETRUSAGE
47 #include <sys/resource.h>
48 #endif
49 #ifdef __MINGW32__
50 #include <process.h>
51 #endif
52 #include "g10lib.h"
53 #include "rmd.h"
54 #include "random.h"
55 #include "rand-internal.h"
56 //#include "dynload.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 unsigned char failsafe_digest[DIGESTLEN];
102 static int failsafe_digest_valid;
103
104 static int secure_alloc;
105 static int quick_test;
106 static int faked_rng;
107
108 static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
109 static int pool_is_locked; /* only used for assertion */
110
111 static byte *get_random_bytes( size_t nbytes, int level, int secure );
112 static void read_pool( byte *buffer, size_t length, int level );
113 static void add_randomness( const void *buffer, size_t length, int source );
114 static void random_poll(void);
115 static void do_fast_random_poll (void);
116 static void read_random_source( int requester, size_t length, int level);
117 static int gather_faked( void (*add)(const void*, size_t, int), int requester,
118                                                     size_t length, int level );
119
120 static struct {
121     ulong mixrnd;
122     ulong mixkey;
123     ulong slowpolls;
124     ulong fastpolls;
125     ulong getbytes1;
126     ulong ngetbytes1;
127     ulong getbytes2;
128     ulong ngetbytes2;
129     ulong addbytes;
130     ulong naddbytes;
131 } rndstats;
132
133 static void (*progress_cb) (void *,const char*,int,int, int );
134 static void *progress_cb_data;
135
136 /* Note, we assume that this function is used before any concurrent
137    access happens */
138 static void
139 initialize(void)
140 {
141   int err;
142
143   err = ath_mutex_init (&pool_lock);
144   if (err)
145     log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
146     
147   /* The data buffer is allocated somewhat larger, so that we can use
148     this extra space (which is allocated in secure memory) as a
149     temporary hash buffer */
150   rndpool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
151                          : gcry_xcalloc(1,POOLSIZE+BLOCKLEN);
152   keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
153                          : gcry_xcalloc(1,POOLSIZE+BLOCKLEN);
154   is_initialized = 1;
155
156   //_gcry_cipher_modules_constructor ();
157 }
158
159
160 /* Used to register a progress callback. */
161 void
162 _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
163                                 void *cb_data )
164 {
165   progress_cb = cb;
166   progress_cb_data = cb_data;
167 }
168
169
170 /* This progress function is currently used by the random modules to give hint
171    on how much more entropy is required. */
172 void
173 _gcry_random_progress (const char *what, int printchar, int current, int total)
174 {
175   if (progress_cb)
176     progress_cb (progress_cb_data, what, printchar, current, total);
177 }
178
179
180 /* Initialize this random subsystem.  This function memrely calls the
181    initialzies and does not do anything more.  Doing this is not
182    really required but when running in a threaded environment we might
183    get a race condition otherwise. */
184 void
185 _gcry_random_initialize ()
186 {
187   if (!is_initialized)
188     initialize ();
189 }
190
191 void
192 _gcry_random_dump_stats()
193 {
194     log_info (
195             "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
196             "              outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n",
197         POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
198                   rndstats.naddbytes, rndstats.addbytes,
199         rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
200                     rndstats.ngetbytes2, rndstats.getbytes2 );
201 }
202
203 void
204 _gcry_secure_random_alloc()
205 {
206     secure_alloc = 1;
207 }
208
209
210 int
211 _gcry_quick_random_gen( int onoff )
212 {
213     int last;
214
215     /* No need to lock it here because we are only initializing.  A
216        prerequisite of the entire code is that it has already been
217        initialized before any possible concurrent access */
218     read_random_source(0,0,0); /* init */
219     last = quick_test;
220     if( onoff != -1 )
221         quick_test = onoff;
222     return faked_rng? 1 : last;
223 }
224
225 int
226 _gcry_random_is_faked()
227 {
228     if( !is_initialized )
229         initialize();
230     return faked_rng || quick_test;
231 }
232
233 /****************
234  * Return a pointer to a randomized buffer of level 0 and LENGTH bits
235  * caller must free the buffer.
236  * Note: The returned value is rounded up to bytes.
237  */
238 static byte *
239 get_random_bytes( size_t nbytes, int level, int secure )
240 {
241     byte *buf, *p;
242     int err;
243
244     if( quick_test && level > 1 )
245         level = 1;
246     MASK_LEVEL(level);
247
248     err = ath_mutex_lock (&pool_lock);
249     if (err)
250       log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
251     pool_is_locked = 1;
252     if( level == 1 ) {
253         rndstats.getbytes1 += nbytes;
254         rndstats.ngetbytes1++;
255     }
256     else if( level >= 2 ) {
257         rndstats.getbytes2 += nbytes;
258         rndstats.ngetbytes2++;
259     }
260
261     buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes )
262                                  : gcry_xmalloc( nbytes );
263     for( p = buf; nbytes > 0; ) {
264         size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
265         read_pool( p, n, level );
266         nbytes -= n;
267         p += n;
268     }
269
270     pool_is_locked = 0;
271     err = ath_mutex_unlock (&pool_lock);
272     if (err)
273       log_fatal ("failed to release the pool lock: %s\n", strerror (err));
274     return buf;
275 }
276
277
278 /* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
279    should be in the range of 0..100 to indicate the goodness of the
280    entropy added, or -1 for goodness not known. 
281
282    Note, that this fucntion currently does nothing.
283 */
284 gcry_error_t
285 gcry_random_add_bytes (const void * buf, size_t buflen, int quality)
286 {
287   gcry_err_code_t err = GPG_ERR_NO_ERROR;
288
289   if (!buf || quality < -1 || quality > 100)
290     err = GPG_ERR_INV_ARG;
291   if (!buflen)
292     return 0; /* Shortcut this dummy case. */
293 #if 0
294   /* Before we actuall enbale this code, we need to lock the pool,
295      have a look at the quality and find a way to add them without
296      disturbing the real entropy (we have estimated). */
297   /*add_randomness( buf, buflen, 1 );*/
298 #endif
299   return err;
300 }   
301     
302
303 void *
304 gcry_random_bytes( size_t nbytes, enum gcry_random_level level )
305 {
306   if (!is_initialized)
307     initialize();
308   return get_random_bytes( nbytes, level, 0 );
309 }
310
311 void *
312 gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level )
313 {
314   if (!is_initialized)
315     initialize();
316   return get_random_bytes( nbytes, level, 1 );
317 }
318
319
320 /* Fill the buffer with LENGTH bytes of cryptographically strong
321    random bytes. level 0 is not very strong, 1 is strong enough for
322    most usage, 2 is good for key generation stuff but may be very
323    slow.  */
324 void
325 gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level)
326 {
327   byte *p;
328   int err;
329
330   if (!is_initialized)
331     initialize ();
332
333   if( quick_test && level > 1 )
334     level = 1;
335   MASK_LEVEL(level);
336
337   err = ath_mutex_lock (&pool_lock);
338   if (err)
339     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
340   pool_is_locked = 1;
341   if (level == 1)
342     {
343       rndstats.getbytes1 += length;
344       rndstats.ngetbytes1++;
345     }
346   else if (level >= 2)
347     {
348       rndstats.getbytes2 += length;
349       rndstats.ngetbytes2++;
350     }
351
352   for (p = buffer; length > 0;)
353     {
354       size_t n = length > POOLSIZE? POOLSIZE : length;
355       read_pool (p, n, level);
356       length -= n;
357       p += n;
358     }
359
360   pool_is_locked = 0;
361   err = ath_mutex_unlock (&pool_lock);
362   if (err)
363     log_fatal ("failed to release the pool lock: %s\n", strerror (err));
364 }
365
366
367
368
369 /*
370    Mix the pool:
371
372    |........blocks*20byte........|20byte|..44byte..|
373    <..44byte..>           <20byte> 
374         |                    |
375         |                    +------+
376         +---------------------------|----------+
377                                     v          v
378    |........blocks*20byte........|20byte|..44byte..|
379                                  <.....64bytes.....>   
380                                          |
381       +----------------------------------+
382      Hash
383       v
384    |.............................|20byte|..44byte..|
385    <20byte><20byte><..44byte..>
386       |                |
387       |                +---------------------+
388       +-----------------------------+        |
389                                     v        v
390    |.............................|20byte|..44byte..|
391                                  <.....64byte......>
392                                         |
393               +-------------------------+
394              Hash
395               v
396    |.............................|20byte|..44byte..|
397    <20byte><20byte><..44byte..>
398
399    and so on until we did this for all blocks. 
400
401  */
402 static void
403 mix_pool(byte *pool)
404 {
405     char *hashbuf = pool + POOLSIZE;
406     char *p, *pend;
407     int i, n;
408     RMD160_CONTEXT md;
409
410     assert (pool_is_locked);
411     _gcry_rmd160_init( &md );
412 #if DIGESTLEN != 20
413 #error must have a digest length of 20 for ripe-md-160
414 #endif
415     /* loop over the pool */
416     pend = pool + POOLSIZE;
417     memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
418     memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
419     _gcry_rmd160_mixblock( &md, hashbuf);
420     memcpy(pool, hashbuf, 20 );
421     if (failsafe_digest_valid && (char *)pool == rndpool)
422       {
423         for (i=0; i < 20; i++)
424           pool[i] ^= failsafe_digest[i];
425       }
426
427     p = pool;
428     for( n=1; n < POOLBLOCKS; n++ ) {
429         memcpy(hashbuf, p, DIGESTLEN );
430
431         p += DIGESTLEN;
432         if( p+DIGESTLEN+BLOCKLEN < pend )
433             memcpy(hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
434         else {
435             char *pp = p+DIGESTLEN;
436             for(i=DIGESTLEN; i < BLOCKLEN; i++ ) {
437                 if( pp >= pend )
438                     pp = pool;
439                 hashbuf[i] = *pp++;
440             }
441         }
442
443         _gcry_rmd160_mixblock( &md, hashbuf);
444         memcpy(p, hashbuf, 20 );
445     }
446     /* Hmmm: our hash implementation does only leave small parts (64
447        bytes) of the pool on the stack, so I thnik it ios okay not to
448        require secure memory here.  Before we use this pool, it gets
449        copied to the help buffer anyway. */
450     if ( (char*)pool == rndpool)
451       {
452         _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE);
453         failsafe_digest_valid = 1;
454       }
455     _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */
456 }
457
458 void
459 _gcry_set_random_seed_file( const char *name )
460 {
461     if( seed_file_name )
462         BUG();
463     seed_file_name = gcry_xstrdup( name );
464 }
465
466 /****************
467  * Read in a seed form the random_seed file
468  * and return true if this was successful
469  */
470 static int
471 read_seed_file (void)
472 {
473     int fd;
474     struct stat sb;
475     unsigned char buffer[POOLSIZE];
476     int n;
477
478     assert (pool_is_locked);
479     if( !seed_file_name )
480         return 0;
481
482 #ifdef HAVE_DOSISH_SYSTEM
483     fd = open( seed_file_name, O_RDONLY | O_BINARY );
484 #else
485     fd = open( seed_file_name, O_RDONLY );
486 #endif
487     if( fd == -1 && errno == ENOENT) {
488         allow_seed_file_update = 1;
489         return 0;
490     }
491
492     if( fd == -1 ) {
493         log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
494         return 0;
495     }
496     if( fstat( fd, &sb ) ) {
497         log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
498         close(fd);
499         return 0;
500     }
501     if( !S_ISREG(sb.st_mode) ) {
502         log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
503         close(fd);
504         return 0;
505     }
506     if( !sb.st_size ) {
507         log_info(_("note: random_seed file is empty\n") );
508         close(fd);
509         allow_seed_file_update = 1;
510         return 0;
511     }
512     if( sb.st_size != POOLSIZE ) {
513         log_info(_("warning: invalid size of random_seed file - not used\n") );
514         close(fd);
515         return 0;
516     }
517     do {
518         n = read( fd, buffer, POOLSIZE );
519     } while( n == -1 && errno == EINTR );
520     if( n != POOLSIZE ) {
521         log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
522         close(fd);/*NOTREACHED*/
523         return 0;
524     }
525
526     close(fd);
527
528     add_randomness( buffer, POOLSIZE, 0 );
529     /* add some minor entropy to the pool now (this will also force a mixing) */
530     {   pid_t x = getpid();
531         add_randomness( &x, sizeof(x), 0 );
532     }
533     {   time_t x = time(NULL);
534         add_randomness( &x, sizeof(x), 0 );
535     }
536     {   clock_t x = clock();
537         add_randomness( &x, sizeof(x), 0 );
538     }
539     /* And read a few bytes from our entropy source.  By using
540      * a level of 0 this will not block and might not return anything
541      * with some entropy drivers, however the rndlinux driver will use
542      * /dev/urandom and return some stuff - Do not read to much as we
543      * want to be friendly to the scare system entropy resource. */
544     read_random_source( 0, 16, 0 );
545
546     allow_seed_file_update = 1;
547     return 1;
548 }
549
550 void
551 _gcry_update_random_seed_file()
552 {
553   ulong *sp, *dp;
554   int fd, i;
555   int err;
556   
557   if ( !seed_file_name || !is_initialized || !pool_filled )
558     return;
559   if ( !allow_seed_file_update )
560     {
561       log_info(_("note: random_seed file not updated\n"));
562       return;
563     }
564
565   err = ath_mutex_lock (&pool_lock);
566   if (err)
567     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
568   pool_is_locked = 1;
569
570     /* copy the entropy pool to a scratch pool and mix both of them */
571   for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
572        i < POOLWORDS; i++, dp++, sp++ ) 
573     {
574       *dp = *sp + ADD_VALUE;
575     }
576   mix_pool(rndpool); rndstats.mixrnd++;
577   mix_pool(keypool); rndstats.mixkey++;
578
579 #ifdef HAVE_DOSISH_SYSTEM
580   fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
581              S_IRUSR|S_IWUSR );
582 #else
583   fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
584 #endif
585
586   if (fd == -1 )
587     log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
588   else 
589     {
590       do {
591         i = write (fd, keypool, POOLSIZE );
592       } while( i == -1 && errno == EINTR );
593     if (i != POOLSIZE) 
594       log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
595     if (close(fd))
596       log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
597     }
598
599   pool_is_locked = 0;
600   err = ath_mutex_unlock (&pool_lock);
601   if (err)
602     log_fatal ("failed to release the pool lock: %s\n", strerror (err));
603 }
604
605
606 static void
607 read_pool( byte *buffer, size_t length, int level )
608 {
609     int i;
610     ulong *sp, *dp;
611
612     assert (pool_is_locked);
613     if( length > POOLSIZE ) {
614         log_bug("too many random bits requested\n");
615     }
616
617     if( !pool_filled ) {
618         if( read_seed_file() )
619             pool_filled = 1;
620     }
621
622     /* For level 2 quality (key generation) we always make
623      * sure that the pool has been seeded enough initially */
624     if( level == 2 && !did_initial_extra_seeding ) {
625         size_t needed;
626
627         pool_balance = 0;
628         needed = length - pool_balance;
629         if( needed < POOLSIZE/2 )
630             needed = POOLSIZE/2;
631         else if( needed > POOLSIZE )
632             BUG();
633         read_random_source( 3, needed, 2 );
634         pool_balance += needed;
635         did_initial_extra_seeding=1;
636     }
637
638     /* for level 2 make sure that there is enough random in the pool */
639     if( level == 2 && pool_balance < length ) {
640         size_t needed;
641
642         if( pool_balance < 0 )
643             pool_balance = 0;
644         needed = length - pool_balance;
645         if( needed > POOLSIZE )
646             BUG();
647         read_random_source( 3, needed, 2 );
648         pool_balance += needed;
649     }
650
651     /* make sure the pool is filled */
652     while( !pool_filled )
653         random_poll();
654
655     /* always do a fast random poll - we have to use the unlocked version*/
656     do_fast_random_poll();
657
658     if( !level ) { /* no need for cryptographic strong random */
659         /* create a new pool */
660         for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
661                                     i < POOLWORDS; i++, dp++, sp++ )
662             *dp = *sp + ADD_VALUE;
663         /* must mix both pools */
664         mix_pool(rndpool); rndstats.mixrnd++;
665         mix_pool(keypool); rndstats.mixkey++;
666         memcpy( buffer, keypool, length );
667     }
668     else {
669         /* mix the pool (if add_randomness() didn't it) */
670         if( !just_mixed ) {
671             mix_pool(rndpool);
672             rndstats.mixrnd++;
673         }
674         /* create a new pool */
675         for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
676                                     i < POOLWORDS; i++, dp++, sp++ )
677             *dp = *sp + ADD_VALUE;
678         /* and mix both pools */
679         mix_pool(rndpool); rndstats.mixrnd++;
680         mix_pool(keypool); rndstats.mixkey++;
681         /* read the required data
682          * we use a readpoiter to read from a different postion each
683          * time */
684         while( length-- ) {
685             *buffer++ = keypool[pool_readpos++];
686             if( pool_readpos >= POOLSIZE )
687                 pool_readpos = 0;
688             pool_balance--;
689         }
690         if( pool_balance < 0 )
691             pool_balance = 0;
692         /* and clear the keypool */
693         memset( keypool, 0, POOLSIZE );
694     }
695 }
696
697
698 /****************
699  * Add LENGTH bytes of randomness from buffer to the pool.
700  * source may be used to specify the randomness source.
701  * Source is:
702  *      0 - used ony for initialization
703  *      1 - fast random poll function
704  *      2 - normal poll function
705  *      3 - used when level 2 random quality has been requested
706  *          to do an extra pool seed.
707  */
708 static void
709 add_randomness( const void *buffer, size_t length, int source )
710 {
711     const byte *p = buffer;
712
713     assert (pool_is_locked);
714     if( !is_initialized )
715         initialize();
716     rndstats.addbytes += length;
717     rndstats.naddbytes++;
718     while( length-- ) {
719         rndpool[pool_writepos++] ^= *p++;
720         if( pool_writepos >= POOLSIZE ) {
721             if( source > 1 )
722                 pool_filled = 1;
723             pool_writepos = 0;
724             mix_pool(rndpool); rndstats.mixrnd++;
725             just_mixed = !length;
726         }
727     }
728 }
729
730
731
732 static void
733 random_poll()
734 {
735     rndstats.slowpolls++;
736     read_random_source( 2, POOLSIZE/5, 1 );
737 }
738
739 static int (*
740 getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
741                              size_t, int)
742 {
743   static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int);
744   
745   if (fnc)
746     return fnc;
747
748 #if USE_RNDLINUX
749   if ( !access (NAME_OF_DEV_RANDOM, R_OK)
750        && !access (NAME_OF_DEV_URANDOM, R_OK))
751     {
752       fnc = _gcry_rndlinux_gather_random;
753       return fnc;
754     }
755 #endif
756
757 #if USE_RNDEGD
758   if ( _gcry_rndegd_connect_socket (1) != -1 )
759     {
760       fnc = _gcry_rndegd_gather_random;
761       return fnc;
762     }
763 #endif
764
765 #if USE_RNDUNIX
766   fnc = _gcry_rndunix_gather_random;
767   return fnc;
768 #endif
769
770 #if USE_RNDW32
771   fnc = _gcry_rndw32_gather_random;
772   return fnc;
773 #endif
774
775   log_fatal (_("no entropy gathering module detected\n"));
776
777   return NULL; /*NOTREACHED*/
778 }
779
780 static void (*
781 getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
782 {
783 #if USE_RNDW32
784   return _gcry_rndw32_gather_random_fast;
785 #endif
786   return NULL;
787 }
788
789
790 static void
791 do_fast_random_poll ()
792 {
793     static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
794     static int initialized = 0;
795
796     assert (pool_is_locked);
797     rndstats.fastpolls++;
798     if( !initialized ) {
799         if( !is_initialized )
800             initialize();
801         initialized = 1;
802         fnc = getfnc_fast_random_poll ();
803     }
804     if( fnc ) {
805         (*fnc)( add_randomness, 1 );
806         return;
807     }
808
809     /* fall back to the generic function */
810 #if HAVE_GETHRTIME
811     {   hrtime_t tv;
812         tv = gethrtime();
813         add_randomness( &tv, sizeof(tv), 1 );
814     }
815 #elif HAVE_GETTIMEOFDAY
816     {   struct timeval tv;
817         if( gettimeofday( &tv, NULL ) )
818             BUG();
819         add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
820         add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
821     }
822 #elif HAVE_CLOCK_GETTIME
823     {   struct timespec tv;
824         if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
825             BUG();
826         add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
827         add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
828     }
829 #else /* use times */
830 #ifndef HAVE_DOSISH_SYSTEM
831     {   struct tms buf;
832         times( &buf );
833         add_randomness( &buf, sizeof buf, 1 );
834     }
835 #endif
836 #endif
837 #ifdef HAVE_GETRUSAGE
838 #ifndef RUSAGE_SELF
839 #ifdef __GCC__
840         #warning There is no RUSAGE_SELF on this system
841 #endif
842 #else
843     {   
844         struct rusage buf;
845         /* QNX/Neutrino does return ENOSYS - so we just ignore it and
846          * add whatever is in buf.  In a chroot environment it might not
847          * work at all (i.e. because /proc/ is not accessible), so we better 
848          * ugnore all error codes and hope for the best
849          */
850         getrusage (RUSAGE_SELF, &buf );
851         add_randomness( &buf, sizeof buf, 1 );
852         memset( &buf, 0, sizeof buf );
853     }
854 #endif
855 #endif
856     /* time and clock are availabe on all systems - so
857      * we better do it just in case one of the above functions
858      * didn't work */
859     {   time_t x = time(NULL);
860         add_randomness( &x, sizeof(x), 1 );
861     }
862     {   clock_t x = clock();
863         add_randomness( &x, sizeof(x), 1 );
864     }
865 }
866
867
868 void
869 _gcry_fast_random_poll()
870 {
871   int err;
872
873   /* We have to make sure that the intialization is done because this
874      gatherer might be called before any other functions and it is not
875      sufficient to initialize it within do_fast_random_pool becuase we
876      want to use the mutex here. FIXME: Whe should initialize the mutex
877      using a global constructor independent from the initialization
878      of the pool. */
879   if (!is_initialized)
880     initialize ();
881   err = ath_mutex_lock (&pool_lock);
882   if (err)
883     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
884   pool_is_locked = 1;
885   do_fast_random_poll ();
886   pool_is_locked = 0;
887   err = ath_mutex_unlock (&pool_lock);
888   if (err)
889     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
890
891 }
892
893
894
895 static void
896 read_random_source( int requester, size_t length, int level )
897 {
898     static int (*fnc)(void (*)(const void*, size_t, int), int,
899                                                     size_t, int) = NULL;
900     if( !fnc ) {
901         if( !is_initialized )
902           initialize();
903         fnc = getfnc_gather_random ();
904         //fnc = ((GcryRandomSpec *) randoms_registered->spec)->add;
905         //fnc = _gcry_dynload_getfnc_gather_random();
906         if( !fnc ) {
907             faked_rng = 1;
908             fnc = gather_faked;
909         }
910         if( !requester && !length && !level )
911             return; /* init only */
912     }
913     if( (*fnc)( add_randomness, requester, length, level ) < 0 )
914         log_fatal("No way to gather entropy for the RNG\n");
915 }
916
917
918 static int
919 gather_faked( void (*add)(const void*, size_t, int), int requester,
920               size_t length, int level )
921 {
922     static int initialized=0;
923     size_t n;
924     char *buffer, *p;
925
926     if( !initialized ) {
927         log_info(_("WARNING: using insecure random number generator!!\n"));
928         /* we can't use tty_printf here - do we need this function at
929           all - does it really make sense or canit be viewed as a potential
930           security problem ? wk 17.11.99 */
931 #if 0
932         tty_printf(_("The random number generator is only a kludge to let\n"
933                    "it run - it is in no way a strong RNG!\n\n"
934                    "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
935 #endif
936         initialized=1;
937 #ifdef HAVE_RAND
938         srand( time(NULL)*getpid());
939 #else
940         srandom( time(NULL)*getpid());
941 #endif
942     }
943
944     p = buffer = gcry_xmalloc( length );
945     n = length;
946 #ifdef HAVE_RAND
947     while( n-- )
948         *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
949 #else
950     while( n-- )
951         *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
952 #endif
953     add_randomness( buffer, length, requester );
954     gcry_free(buffer);
955     return 0; /* okay */
956 }
957