~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to cipher/rand-unix.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Urlichs
  • Date: 2006-01-24 04:31:42 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060124043142-pbg192or6qxv3yk2
Tags: 1.9.20-1
* New Upstream version. Closes:#306890,#344530
  * Closes:#320490: gpg-protect-tool fails to decrypt PKCS-12 files 
* Depend on libopensc2-dev, not -1-. Closes:#348106

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* rand-unix.c  -  raw random number generator for unix like OSes
 
2
 *      Copyright (C) 1998 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GNUPG.
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
 
 
22
#include <config.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <assert.h>
 
26
#include <errno.h>
 
27
#include <sys/time.h>
 
28
#include <sys/types.h>
 
29
#include <sys/stat.h>
 
30
#ifdef  HAVE_GETHRTIME
 
31
  #include <sys/times.h>
 
32
#endif
 
33
#ifdef HAVE_GETTIMEOFDAY
 
34
  #include <sys/times.h>
 
35
#endif
 
36
#ifdef HAVE_GETRUSAGE
 
37
  #include <sys/resource.h>
 
38
#endif
 
39
#include <string.h>
 
40
#include <unistd.h>
 
41
#include <fcntl.h>
 
42
#include "util.h"
 
43
#include "rmd.h"
 
44
#include "ttyio.h"
 
45
#include "i18n.h"
 
46
#include "rand-internal.h"
 
47
#ifdef USE_RAND_UNIX  /* This file is only for real systems */
 
48
 
 
49
 
 
50
void
 
51
random_poll()
 
52
{
 
53
    char buf[POOLSIZE/5];
 
54
    read_random_source( buf, POOLSIZE/5, 1 ); /* read /dev/urandom */
 
55
    add_randomness( buf, POOLSIZE/5, 2);
 
56
    memset( buf, 0, POOLSIZE/5);
 
57
}
 
58
 
 
59
 
 
60
void
 
61
fast_random_poll()
 
62
{
 
63
  #if HAVE_GETHRTIME
 
64
    {   hrtime_t tv;
 
65
        tv = gethrtime();
 
66
        add_randomness( &tv, sizeof(tv), 1 );
 
67
    }
 
68
  #elif HAVE_GETTIMEOFDAY
 
69
    {   struct timeval tv;
 
70
        if( gettimeofday( &tv, NULL ) )
 
71
            BUG();
 
72
        add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
 
73
        add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
 
74
    }
 
75
  #else /* use times */
 
76
    {   struct tms buf;
 
77
        times( &buf );
 
78
        add_randomness( &buf, sizeof buf, 1 );
 
79
    }
 
80
  #endif
 
81
  #ifdef HAVE_GETRUSAGE
 
82
    {   struct rusage buf;
 
83
        if( getrusage( RUSAGE_SELF, &buf ) )
 
84
            BUG();
 
85
        add_randomness( &buf, sizeof buf, 1 );
 
86
        memset( &buf, 0, sizeof buf );
 
87
    }
 
88
  #endif
 
89
}
 
90
 
 
91
 
 
92
#ifdef HAVE_DEV_RANDOM  /* we have the /dev/random devices */
 
93
 
 
94
/****************
 
95
 * Used to open the Linux and xBSD /dev/random devices
 
96
 */
 
97
static int
 
98
open_device( const char *name, int minor )
 
99
{
 
100
    int fd;
 
101
    struct stat sb;
 
102
 
 
103
    fd = open( name, O_RDONLY );
 
104
    if( fd == -1 )
 
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
 
110
  #else
 
111
    if( !S_ISCHR(sb.st_mode) )
 
112
        log_fatal("invalid random device!\n" );
 
113
  #endif
 
114
    return fd;
 
115
}
 
116
 
 
117
 
 
118
void
 
119
read_random_source( byte *buffer, size_t length, int level )
 
120
{
 
121
    static int fd_urandom = -1;
 
122
    static int fd_random = -1;
 
123
    int fd;
 
124
    int n;
 
125
    int warn=0;
 
126
 
 
127
    if( level >= 2 ) {
 
128
        if( fd_random == -1 )
 
129
            fd_random = open_device( NAME_OF_DEV_RANDOM, 8 );
 
130
        fd = fd_random;
 
131
    }
 
132
    else {
 
133
        if( fd_urandom == -1 )
 
134
            fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 );
 
135
        fd = fd_urandom;
 
136
    }
 
137
    do {
 
138
        fd_set rfds;
 
139
        struct timeval tv;
 
140
        int rc;
 
141
 
 
142
        FD_ZERO(&rfds);
 
143
        FD_SET(fd, &rfds);
 
144
        tv.tv_sec = 3;
 
145
        tv.tv_usec = 0;
 
146
        if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
 
147
            if( !warn )
 
148
                tty_printf( _(
 
149
"\n"
 
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 );
 
152
            warn = 1;
 
153
            continue;
 
154
        }
 
155
        else if( rc == -1 ) {
 
156
            tty_printf("select() error: %s\n", strerror(errno));
 
157
            continue;
 
158
        }
 
159
 
 
160
        do {
 
161
            n = read(fd, buffer, length );
 
162
            if( n >= 0 && n > length ) {
 
163
                log_error("bogus read from random device (n=%d)\n", n );
 
164
                n = length;
 
165
            }
 
166
        } while( n == -1 && errno == EINTR );
 
167
        if( n == -1 )
 
168
            log_fatal("read error on random device: %s\n", strerror(errno) );
 
169
        assert( n <= length );
 
170
        buffer += n;
 
171
        length -= n;
 
172
    } while( length );
 
173
}
 
174
 
 
175
#else /* not HAVE_DEV_RANDOM */
 
176
 
 
177
 
 
178
/****************
 
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
 
182
 * bytes to out_fd.
 
183
 *
 
184
 * Commands understand from ctrl_fd are single character:
 
185
 *  'Q' = Quit the loop
 
186
 *  'S' = Start a new collection process
 
187
 */
 
188
static void
 
189
collector( FILE *ctrlfp, FILE *outfp )
 
190
{
 
191
 
 
192
 
 
193
 
 
194
}
 
195
 
 
196
#endif /* no HAVE_DEV_RANDOM */
 
197
#endif /* USE_RAND_UNIX */