* random.c (gcry_random_bytes,gcry_random_bytes_secure)
[libgcrypt.git] / cipher / random.c
1 /* random.c  -  random number generator
2  * Copyright (C) 1998, 2000, 2001, 2002 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 "mutex.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 {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } 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 DEFINE_LOCAL_MUTEX(pool_lock)
109 static int pool_is_locked; /* only 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
134 /* Note, we assume that this function is used before any concurrent
135    access happens */
136 static void
137 initialize(void)
138 {
139   int err;
140
141   err = mutex_init (pool_lock);
142   if (err)
143     log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
144     
145   /* The data buffer is allocated somewhat larger, so that we can use
146     this extra space (which is allocated in secure memory) as a
147     temporary hash buffer */
148   rndpool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
149                          : gcry_xcalloc(1,POOLSIZE+BLOCKLEN);
150   keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
151                          : gcry_xcalloc(1,POOLSIZE+BLOCKLEN);
152   is_initialized = 1;
153   _gcry_cipher_modules_constructor ();
154 }
155
156 static void
157 burn_stack (int bytes)
158 {
159     char buf[128];
160     
161     memset (buf, 0, sizeof buf);
162     bytes -= sizeof buf;
163     if (bytes > 0)
164         burn_stack (bytes);
165 }
166
167
168 void
169 _gcry_random_dump_stats()
170 {
171     fprintf(stderr,
172             "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
173             "              outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n",
174         POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
175                   rndstats.naddbytes, rndstats.addbytes,
176         rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
177                     rndstats.ngetbytes2, rndstats.getbytes2 );
178 }
179
180 void
181 _gcry_secure_random_alloc()
182 {
183     secure_alloc = 1;
184 }
185
186
187 int
188 _gcry_quick_random_gen( int onoff )
189 {
190     int last;
191
192     /* No need to lock it here because we are only initializing.  A
193        prerequisite of the entire code is that it has already been
194        initialized before any possible concurrent access */
195     read_random_source(0,0,0); /* init */
196     last = quick_test;
197     if( onoff != -1 )
198         quick_test = onoff;
199     return faked_rng? 1 : last;
200 }
201
202
203 /****************
204  * Fill the buffer with LENGTH bytes of cryptographically strong
205  * random bytes. level 0 is not very strong, 1 is strong enough
206  * for most usage, 2 is good for key generation stuff but may be very slow.
207  */
208 void
209 gcry_randomize( byte *buffer, size_t length, enum gcry_random_level level )
210 {
211   char *p;
212
213   if (!is_initialized)
214     initialize ();
215   p = get_random_bytes( length, level, 1 );
216   memcpy( buffer, p, length );
217   gcry_free(p);
218 }
219
220
221 int
222 _gcry_random_is_faked()
223 {
224     if( !is_initialized )
225         initialize();
226     return faked_rng || quick_test;
227 }
228
229 /****************
230  * Return a pointer to a randomized buffer of level 0 and LENGTH bits
231  * caller must free the buffer.
232  * Note: The returned value is rounded up to bytes.
233  */
234 static byte *
235 get_random_bytes( size_t nbytes, int level, int secure )
236 {
237     byte *buf, *p;
238     int err;
239
240     if( quick_test && level > 1 )
241         level = 1;
242     MASK_LEVEL(level);
243
244     err = mutex_lock (pool_lock);
245     if (err)
246       log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
247     pool_is_locked = 1;
248     if( level == 1 ) {
249         rndstats.getbytes1 += nbytes;
250         rndstats.ngetbytes1++;
251     }
252     else if( level >= 2 ) {
253         rndstats.getbytes2 += nbytes;
254         rndstats.ngetbytes2++;
255     }
256
257     buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes )
258                                  : gcry_xmalloc( nbytes );
259     for( p = buf; nbytes > 0; ) {
260         size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
261         read_pool( p, n, level );
262         nbytes -= n;
263         p += n;
264     }
265
266     pool_is_locked = 0;
267     err = mutex_unlock (pool_lock);
268     if (err)
269       log_fatal ("failed to release the pool lock: %s\n", strerror (err));
270     return buf;
271 }
272
273 void *
274 gcry_random_bytes( size_t nbytes, enum gcry_random_level level )
275 {
276   if (!is_initialized)
277     initialize();
278   return get_random_bytes( nbytes, level, 0 );
279 }
280
281 void *
282 gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level )
283 {
284   if (!is_initialized)
285     initialize();
286   return get_random_bytes( nbytes, level, 1 );
287 }
288
289
290 /*
291    Mix the pool:
292
293    |........blocks*20byte........|20byte|..44byte..|
294    <..44byte..>           <20byte> 
295         |                    |
296         |                    +------+
297         +---------------------------|----------+
298                                     v          v
299    |........blocks*20byte........|20byte|..44byte..|
300                                  <.....64bytes.....>   
301                                          |
302       +----------------------------------+
303      Hash
304       v
305    |.............................|20byte|..44byte..|
306    <20byte><20byte><..44byte..>
307       |                |
308       |                +---------------------+
309       +-----------------------------+        |
310                                     v        v
311    |.............................|20byte|..44byte..|
312                                  <.....64byte......>
313                                         |
314               +-------------------------+
315              Hash
316               v
317    |.............................|20byte|..44byte..|
318    <20byte><20byte><..44byte..>
319
320    and so on until we did this for all blocks. 
321
322  */
323 static void
324 mix_pool(byte *pool)
325 {
326     char *hashbuf = pool + POOLSIZE;
327     char *p, *pend;
328     int i, n;
329     RMD160_CONTEXT md;
330
331     assert (pool_is_locked);
332     _gcry_rmd160_init( &md );
333 #if DIGESTLEN != 20
334 #  error must have a digest length of 20 for ripe-md-160
335 #endif
336     /* loop over the pool */
337     pend = pool + POOLSIZE;
338     memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
339     memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
340     _gcry_rmd160_mixblock( &md, hashbuf);
341     memcpy(pool, hashbuf, 20 );
342     if (failsafe_digest_valid && (char *)pool == rndpool)
343       {
344         for (i=0; i < 20; i++)
345           pool[i] ^= failsafe_digest[i];
346       }
347
348     p = pool;
349     for( n=1; n < POOLBLOCKS; n++ ) {
350         memcpy(hashbuf, p, DIGESTLEN );
351
352         p += DIGESTLEN;
353         if( p+DIGESTLEN+BLOCKLEN < pend )
354             memcpy(hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
355         else {
356             char *pp = p+DIGESTLEN;
357             for(i=DIGESTLEN; i < BLOCKLEN; i++ ) {
358                 if( pp >= pend )
359                     pp = pool;
360                 hashbuf[i] = *pp++;
361             }
362         }
363
364         _gcry_rmd160_mixblock( &md, hashbuf);
365         memcpy(p, hashbuf, 20 );
366     }
367     /* Hmmm: our hash implementation does only leave small parts (64
368        bytes) of the pool on the stack, so I thnik it ios okay not to
369        require secure memory here.  Before we use this pool, it gets
370        copied to the help buffer anyway. */
371     if ( (char*)pool == rndpool)
372       {
373         _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE);
374         failsafe_digest_valid = 1;
375       }
376     burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */
377 }
378
379 void
380 _gcry_set_random_seed_file( const char *name )
381 {
382     if( seed_file_name )
383         BUG();
384     seed_file_name = gcry_xstrdup( name );
385 }
386
387 /****************
388  * Read in a seed form the random_seed file
389  * and return true if this was successful
390  */
391 static int
392 read_seed_file()
393 {
394     int fd;
395     struct stat sb;
396     unsigned char buffer[POOLSIZE];
397     int n;
398
399     assert (pool_is_locked);
400     if( !seed_file_name )
401         return 0;
402
403   #ifdef HAVE_DOSISH_SYSTEM
404     fd = open( seed_file_name, O_RDONLY | O_BINARY );
405   #else
406     fd = open( seed_file_name, O_RDONLY );
407   #endif
408     if( fd == -1 && errno == ENOENT) {
409         allow_seed_file_update = 1;
410         return 0;
411     }
412
413     if( fd == -1 ) {
414         log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
415         return 0;
416     }
417     if( fstat( fd, &sb ) ) {
418         log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
419         close(fd);
420         return 0;
421     }
422     if( !S_ISREG(sb.st_mode) ) {
423         log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
424         close(fd);
425         return 0;
426     }
427     if( !sb.st_size ) {
428         log_info(_("note: random_seed file is empty\n") );
429         close(fd);
430         allow_seed_file_update = 1;
431         return 0;
432     }
433     if( sb.st_size != POOLSIZE ) {
434         log_info(_("warning: invalid size of random_seed file - not used\n") );
435         close(fd);
436         return 0;
437     }
438     do {
439         n = read( fd, buffer, POOLSIZE );
440     } while( n == -1 && errno == EINTR );
441     if( n != POOLSIZE ) {
442         log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
443         close(fd);
444         return 0;
445     }
446
447     close(fd);
448
449     add_randomness( buffer, POOLSIZE, 0 );
450     /* add some minor entropy to the pool now (this will also force a mixing) */
451     {   pid_t x = getpid();
452         add_randomness( &x, sizeof(x), 0 );
453     }
454     {   time_t x = time(NULL);
455         add_randomness( &x, sizeof(x), 0 );
456     }
457     {   clock_t x = clock();
458         add_randomness( &x, sizeof(x), 0 );
459     }
460     /* And read a few bytes from our entropy source.  By using
461      * a level of 0 this will not block and might not return anything
462      * with some entropy drivers, however the rndlinux driver will use
463      * /dev/urandom and return some stuff - Do not read to much as we
464      * want to be friendly to the scare system entropy resource. */
465     read_random_source( 0, 16, 0 );
466
467     allow_seed_file_update = 1;
468     return 1;
469 }
470
471 void
472 _gcry_update_random_seed_file()
473 {
474   ulong *sp, *dp;
475   int fd, i;
476   int err;
477   
478   if ( !seed_file_name || !is_initialized || !pool_filled )
479     return;
480   if ( !allow_seed_file_update )
481     {
482       log_info(_("note: random_seed file not updated\n"));
483       return;
484     }
485
486   err = mutex_lock (pool_lock);
487   if (err)
488     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
489   pool_is_locked = 1;
490
491     /* copy the entropy pool to a scratch pool and mix both of them */
492   for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
493        i < POOLWORDS; i++, dp++, sp++ ) 
494     {
495       *dp = *sp + ADD_VALUE;
496     }
497   mix_pool(rndpool); rndstats.mixrnd++;
498   mix_pool(keypool); rndstats.mixkey++;
499
500 #ifdef HAVE_DOSISH_SYSTEM
501   fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
502              S_IRUSR|S_IWUSR );
503 #else
504   fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
505 #endif
506
507   if (fd == -1 )
508     log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
509   else 
510     {
511       do {
512         i = write (fd, keypool, POOLSIZE );
513       } while( i == -1 && errno == EINTR );
514     if (i != POOLSIZE) 
515       log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
516     if (close(fd))
517       log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
518     }
519
520   pool_is_locked = 0;
521   err = mutex_unlock (pool_lock);
522   if (err)
523     log_fatal ("failed to release the pool lock: %s\n", strerror (err));
524 }
525
526
527 static void
528 read_pool( byte *buffer, size_t length, int level )
529 {
530     int i;
531     ulong *sp, *dp;
532
533     assert (pool_is_locked);
534     if( length > POOLSIZE ) {
535         log_bug("too many random bits requested\n");
536     }
537
538     if( !pool_filled ) {
539         if( read_seed_file() )
540             pool_filled = 1;
541     }
542
543     /* For level 2 quality (key generation) we always make
544      * sure that the pool has been seeded enough initially */
545     if( level == 2 && !did_initial_extra_seeding ) {
546         size_t needed;
547
548         pool_balance = 0;
549         needed = length - pool_balance;
550         if( needed < POOLSIZE/2 )
551             needed = POOLSIZE/2;
552         else if( needed > POOLSIZE )
553             BUG();
554         read_random_source( 3, needed, 2 );
555         pool_balance += needed;
556         did_initial_extra_seeding=1;
557     }
558
559     /* for level 2 make sure that there is enough random in the pool */
560     if( level == 2 && pool_balance < length ) {
561         size_t needed;
562
563         if( pool_balance < 0 )
564             pool_balance = 0;
565         needed = length - pool_balance;
566         if( needed > POOLSIZE )
567             BUG();
568         read_random_source( 3, needed, 2 );
569         pool_balance += needed;
570     }
571
572     /* make sure the pool is filled */
573     while( !pool_filled )
574         random_poll();
575
576     /* always do a fast random poll - we have to use the unlocked version*/
577     do_fast_random_poll();
578
579     if( !level ) { /* no need for cryptographic strong random */
580         /* create a new pool */
581         for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
582                                     i < POOLWORDS; i++, dp++, sp++ )
583             *dp = *sp + ADD_VALUE;
584         /* must mix both pools */
585         mix_pool(rndpool); rndstats.mixrnd++;
586         mix_pool(keypool); rndstats.mixkey++;
587         memcpy( buffer, keypool, length );
588     }
589     else {
590         /* mix the pool (if add_randomness() didn't it) */
591         if( !just_mixed ) {
592             mix_pool(rndpool);
593             rndstats.mixrnd++;
594         }
595         /* create a new pool */
596         for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
597                                     i < POOLWORDS; i++, dp++, sp++ )
598             *dp = *sp + ADD_VALUE;
599         /* and mix both pools */
600         mix_pool(rndpool); rndstats.mixrnd++;
601         mix_pool(keypool); rndstats.mixkey++;
602         /* read the required data
603          * we use a readpoiter to read from a different postion each
604          * time */
605         while( length-- ) {
606             *buffer++ = keypool[pool_readpos++];
607             if( pool_readpos >= POOLSIZE )
608                 pool_readpos = 0;
609             pool_balance--;
610         }
611         if( pool_balance < 0 )
612             pool_balance = 0;
613         /* and clear the keypool */
614         memset( keypool, 0, POOLSIZE );
615     }
616 }
617
618
619 /****************
620  * Add LENGTH bytes of randomness from buffer to the pool.
621  * source may be used to specify the randomness source.
622  * Source is:
623  *      0 - used ony for initialization
624  *      1 - fast random poll function
625  *      2 - normal poll function
626  *      3 - used when level 2 random quality has been requested
627  *          to do an extra pool seed.
628  */
629 static void
630 add_randomness( const void *buffer, size_t length, int source )
631 {
632     const byte *p = buffer;
633
634     assert (pool_is_locked);
635     if( !is_initialized )
636         initialize();
637     rndstats.addbytes += length;
638     rndstats.naddbytes++;
639     while( length-- ) {
640         rndpool[pool_writepos++] ^= *p++;
641         if( pool_writepos >= POOLSIZE ) {
642             if( source > 1 )
643                 pool_filled = 1;
644             pool_writepos = 0;
645             mix_pool(rndpool); rndstats.mixrnd++;
646             just_mixed = !length;
647         }
648     }
649 }
650
651
652
653 static void
654 random_poll()
655 {
656     rndstats.slowpolls++;
657     read_random_source( 2, POOLSIZE/5, 1 );
658 }
659
660
661
662 static void
663 do_fast_random_poll ()
664 {
665     static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
666     static int initialized = 0;
667
668     assert (pool_is_locked);
669     rndstats.fastpolls++;
670     if( !initialized ) {
671         if( !is_initialized )
672             initialize();
673         initialized = 1;
674         fnc = _gcry_dynload_getfnc_fast_random_poll();
675     }
676     if( fnc ) {
677         (*fnc)( add_randomness, 1 );
678         return;
679     }
680
681     /* fall back to the generic function */
682   #if HAVE_GETHRTIME
683     {   hrtime_t tv;
684         tv = gethrtime();
685         add_randomness( &tv, sizeof(tv), 1 );
686     }
687   #elif HAVE_GETTIMEOFDAY
688     {   struct timeval tv;
689         if( gettimeofday( &tv, NULL ) )
690             BUG();
691         add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
692         add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
693     }
694   #elif HAVE_CLOCK_GETTIME
695     {   struct timespec tv;
696         if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
697             BUG();
698         add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
699         add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
700     }
701   #else /* use times */
702     #ifndef HAVE_DOSISH_SYSTEM
703     {   struct tms buf;
704         times( &buf );
705         add_randomness( &buf, sizeof buf, 1 );
706     }
707     #endif
708   #endif
709   #ifdef HAVE_GETRUSAGE
710     #ifndef RUSAGE_SELF
711       #ifdef __GCC__
712         #warning There is no RUSAGE_SELF on this system
713       #endif
714     #else
715     {   
716         struct rusage buf;
717         /* QNX/Neutrino does return ENOSYS - so we just ignore it and
718          * add whatever is in buf.  In a chroot environment it might not
719          * work at all (i.e. because /proc/ is not accessible), so we better 
720          * ugnore all error codes and hope for the best
721          */
722         getrusage (RUSAGE_SELF, &buf );
723         add_randomness( &buf, sizeof buf, 1 );
724         memset( &buf, 0, sizeof buf );
725     }
726     #endif
727   #endif
728     /* time and clock are availabe on all systems - so
729      * we better do it just in case one of the above functions
730      * didn't work */
731     {   time_t x = time(NULL);
732         add_randomness( &x, sizeof(x), 1 );
733     }
734     {   clock_t x = clock();
735         add_randomness( &x, sizeof(x), 1 );
736     }
737 }
738
739
740 void
741 _gcry_fast_random_poll()
742 {
743   int err;
744
745   /* We have to make sure that the intialization is done because this
746      gatherer might be called before any other functions and it is not
747      sufficient to initialize it within do_fast_random_pool becuase we
748      want to use the mutex here. FIXME: Weh should initialie the mutex
749      using a global constructore independent from the initialization
750      of the pool. */
751   if (!is_initialized)
752     initialize ();
753   err = mutex_lock (pool_lock);
754   if (err)
755     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
756   pool_is_locked = 1;
757   do_fast_random_poll ();
758   pool_is_locked = 0;
759   err = mutex_unlock (pool_lock);
760   if (err)
761     log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
762
763 }
764
765
766
767 static void
768 read_random_source( int requester, size_t length, int level )
769 {
770     static int (*fnc)(void (*)(const void*, size_t, int), int,
771                                                     size_t, int) = NULL;
772     if( !fnc ) {
773         if( !is_initialized )
774             initialize();
775         fnc = _gcry_dynload_getfnc_gather_random();
776         if( !fnc ) {
777             faked_rng = 1;
778             fnc = gather_faked;
779         }
780         if( !requester && !length && !level )
781             return; /* init only */
782     }
783     if( (*fnc)( add_randomness, requester, length, level ) < 0 )
784         log_fatal("No way to gather entropy for the RNG\n");
785 }
786
787
788 static int
789 gather_faked( void (*add)(const void*, size_t, int), int requester,
790               size_t length, int level )
791 {
792     static int initialized=0;
793     size_t n;
794     char *buffer, *p;
795
796     if( !initialized ) {
797         log_info(_("WARNING: using insecure random number generator!!\n"));
798         /* we can't use tty_printf here - do we need this function at
799           all - does it really make sense or canit be viewed as a potential
800           security problem ? wk 17.11.99 */
801 #if 0
802         tty_printf(_("The random number generator is only a kludge to let\n"
803                    "it run - it is in no way a strong RNG!\n\n"
804                    "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
805 #endif
806         initialized=1;
807 #ifdef HAVE_RAND
808         srand( time(NULL)*getpid());
809 #else
810         srandom( time(NULL)*getpid());
811 #endif
812     }
813
814     p = buffer = gcry_xmalloc( length );
815     n = length;
816 #ifdef HAVE_RAND
817     while( n-- )
818         *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
819 #else
820     while( n-- )
821         *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
822 #endif
823     add_randomness( buffer, length, requester );
824     gcry_free(buffer);
825     return 0; /* okay */
826 }
827