1 /* random.c - random number generator
2 * Copyright (c) 1997 by Werner Koch (dd9jn)
4 * This file is part of G10.
6 * G10 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * G10 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 General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #include <sys/types.h>
36 byte buffer[100]; /* fixme: should be allocated with m_alloc_secure()*/
39 static struct cache cache[3];
40 #define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0)
43 static void fill_buffer( byte *buffer, size_t length, int level );
46 * Fill the buffer with LENGTH bytes of cryptologic strong
47 * random bytes. level 0 is not very strong, 1 is strong enough
48 * for most usage, 2 is good for key generation stuff but may be very slow.
51 randomize_buffer( byte *buffer, size_t length, int level )
53 for( ; length; length-- )
54 *buffer++ = get_random_byte(level);
59 get_random_byte( int level )
62 if( !cache[level].len ) {
63 fill_buffer(cache[level].buffer, DIM(cache[level].buffer), level );
64 cache[level].len = DIM(cache[level].buffer);
67 return cache[level].buffer[--cache[level].len];
72 #ifdef HAVE_DEV_RANDOM
75 open_device( const char *name, int minor )
80 fd = open( name, O_RDONLY );
82 log_fatal("can't open %s: %s\n", name, strerror(errno) );
83 if( fstat( fd, &sb ) )
84 log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
85 if( !S_ISCHR(sb.st_mode)
87 || (sb.st_rdev >> 8) != 1
88 || (sb.st_rdev & 0xff) != minor
91 log_fatal("invalid random device!\n" );
97 fill_buffer( byte *buffer, size_t length, int level )
100 static int fd_urandom = -1;
101 static int fd_random = -1;
107 if( fd_random == -1 )
108 fd_random = open_device( "/dev/random", 8 );
112 if( fd_urandom == -1 )
113 fd_urandom = open_device( "/dev/urandom", 9 );
127 if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
130 "\nNot enough random bytes available. Please do some other work to give
131 the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
135 else if( rc == -1 ) {
136 tty_printf("select() error: %s\n", strerror(errno));
140 assert( length < 200 );
142 n = read(fd, buffer, length );
143 } while( n == -1 && errno == EINTR );
145 log_fatal("read error on random device: %s\n", strerror(errno) );
146 assert( n <= length );
152 #else /* not HAVE_DEV_RANDOM */
156 fill_buffer( byte *buffer, size_t length, int level )
158 static int initialized=0;
161 log_info("warning: using insecure random number generator!!\n");
162 tty_printf("The random number generator is only a kludge to let\n"
163 "it compile - it is in no way a strong RNG!\n\n"
164 "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
166 srand(make_timestamp()*getpid());
170 *buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);