1
/* rand-unix.c - raw random number generator for unix like OSes
2
* Copyright (C) 1998 Free Software Foundation, Inc.
4
* This file is part of GNUPG.
6
* GNUPG 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
* GNUPG 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
28
#include <sys/types.h>
31
#include <sys/times.h>
33
#ifdef HAVE_GETTIMEOFDAY
34
#include <sys/times.h>
37
#include <sys/resource.h>
46
#include "rand-internal.h"
47
#ifdef USE_RAND_UNIX /* This file is only for real systems */
54
read_random_source( buf, POOLSIZE/5, 1 ); /* read /dev/urandom */
55
add_randomness( buf, POOLSIZE/5, 2);
56
memset( buf, 0, POOLSIZE/5);
66
add_randomness( &tv, sizeof(tv), 1 );
68
#elif HAVE_GETTIMEOFDAY
70
if( gettimeofday( &tv, NULL ) )
72
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
73
add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
78
add_randomness( &buf, sizeof buf, 1 );
83
if( getrusage( RUSAGE_SELF, &buf ) )
85
add_randomness( &buf, sizeof buf, 1 );
86
memset( &buf, 0, sizeof buf );
92
#ifdef HAVE_DEV_RANDOM /* we have the /dev/random devices */
95
* Used to open the Linux and xBSD /dev/random devices
98
open_device( const char *name, int minor )
103
fd = open( name, O_RDONLY );
105
log_fatal("can't open %s: %s\n", name, strerror(errno) );
106
if( fstat( fd, &sb ) )
107
log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
108
#if defined(__sparc__) && defined(__linux__)
109
#warning something is wrong with UltraPenguin /dev/random
111
if( !S_ISCHR(sb.st_mode) )
112
log_fatal("invalid random device!\n" );
119
read_random_source( byte *buffer, size_t length, int level )
121
static int fd_urandom = -1;
122
static int fd_random = -1;
128
if( fd_random == -1 )
129
fd_random = open_device( NAME_OF_DEV_RANDOM, 8 );
133
if( fd_urandom == -1 )
134
fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 );
146
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
150
"Not enough random bytes available. Please do some other work to give\n"
151
"the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
155
else if( rc == -1 ) {
156
tty_printf("select() error: %s\n", strerror(errno));
161
n = read(fd, buffer, length );
162
if( n >= 0 && n > length ) {
163
log_error("bogus read from random device (n=%d)\n", n );
166
} while( n == -1 && errno == EINTR );
168
log_fatal("read error on random device: %s\n", strerror(errno) );
169
assert( n <= length );
175
#else /* not HAVE_DEV_RANDOM */
179
* The real random data collector for Unix.
180
* this function runs in a loop, waiting for commands from ctrl_fd
181
* and normally starts a collection process, which outputs random
184
* Commands understand from ctrl_fd are single character:
185
* 'Q' = Quit the loop
186
* 'S' = Start a new collection process
189
collector( FILE *ctrlfp, FILE *outfp )
196
#endif /* no HAVE_DEV_RANDOM */
197
#endif /* USE_RAND_UNIX */