1 /****************************************************************************
2 * *
3 * *
4 * Unix Randomness-Gathering Code *
5 * *
6 * Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999. *
7 * Heavily modified for GnuPG by Werner Koch *
8 * *
9 * *
10 ****************************************************************************/
11
12 /* This module is part of the cryptlib continuously seeded pseudorandom
13 number generator. For usage conditions, see lib_rand.c
14
15 [Here is the notice from lib_rand.c:]
16
17 This module and the misc/rnd*.c modules represent the cryptlib
18 continuously seeded pseudorandom number generator (CSPRNG) as described in
19 my 1998 Usenix Security Symposium paper "The generation of random numbers
20 for cryptographic purposes".
21
22 The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
23 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
24 modules and use in source and binary forms, with or without modification,
25 are permitted provided that the following conditions are met:
26
27 1. Redistributions of source code must retain the above copyright notice
28 and this permission notice in its entirety.
29
30 2. Redistributions in binary form must reproduce the copyright notice in
31 the documentation and/or other materials provided with the distribution.
32
33 3. A copy of any bugfixes or enhancements made must be provided to the
34 author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
35 baseline version of the code.
36
37 ALTERNATIVELY, the code may be distributed under the terms of the
38 GNU Lesser General Public License, version 2.1 or any later version
39 published by the Free Software Foundation, in which case the
40 provisions of the GNU LGPL are required INSTEAD OF the above
41 restrictions.
42
43 Although not required under the terms of the LGPL, it would still be
44 nice if you could make any changes available to the author to allow
45 a consistent code base to be maintained. */
46 /*************************************************************************
47 The above alternative was changed from GPL to LGPL on 2007-08-22 with
48 permission from Peter Gutmann:
49 ==========
50 From: pgut001 <pgut001@cs.auckland.ac.nz>
51 Subject: Re: LGPL for the windows entropy gatherer
52 To: wk@gnupg.org
53 Date: Wed, 22 Aug 2007 03:05:42 +1200
54
55 Hi,
56
57 >As of now libgcrypt is GPL under Windows due to that module and some people
58 >would really like to see it under LGPL too. Can you do such a license change
59 >to LGPL version 2? Note that LGPL give the user the option to relicense it
60 >under GPL, so the change would be pretty easy and backwar compatible.
61
62 Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
63 code as well, but Ian asked for LGPL as an option so as of the next release
64 I'll have LGPL in there. You can consider it to be retroactive, so your
65 current version will be LGPLd as well.
66
67 Peter.
68 ==========
69 From: pgut001 <pgut001@cs.auckland.ac.nz>
70 Subject: Re: LGPL for the windows entropy gatherer
71 To: wk@gnupg.org
72 Date: Wed, 22 Aug 2007 20:50:08 +1200
73
74 >Would you mind to extend this also to the Unix entropy gatherer which is
75 >still used on systems without /dev/random and when EGD is not installed? That
76 >would be the last GPLed piece in Libgcrypt.
77
78 Sure, it covers the entire entropy-gathering subsystem.
79
80 Peter.
81 =========
82 */
83
84 /* General includes */
85
86 #include <config.h>
87 #include <stdlib.h>
88 #include <stdio.h>
89 #ifdef HAVE_STDINT_H
90 # include <stdint.h>
91 #endif
92 #include <string.h>
93
94 /* OS-specific includes */
95
96 #ifdef __osf__
97 /* Somewhere in the morass of system-specific cruft which OSF/1 pulls in
98 * via the following includes are various endianness defines, so we
99 * undefine the cryptlib ones, which aren't really needed for this module
100 * anyway */
101 #undef BIG_ENDIAN
102 #undef LITTLE_ENDIAN
103 #endif /* __osf__ */
104
105 #include <unistd.h>
106 #include <fcntl.h>
107 #include <pwd.h>
108 #ifndef __QNX__
109 #include <sys/errno.h>
110 #include <sys/ipc.h>
111 #endif /* __QNX__ */
112 #include <sys/time.h> /* SCO and SunOS need this before resource.h */
113 #ifndef __QNX__
114 #include <sys/resource.h>
115 #endif /* __QNX__ */
116 #if defined( _AIX ) || defined( __QNX__ )
117 #include <sys/select.h>
118 #endif /* _AIX */
119 #ifndef __QNX__
120 #include <sys/shm.h>
121 #include <signal.h>
122 #include <sys/signal.h>
123 #endif /* __QNX__ */
124 #include <sys/stat.h>
125 #include <sys/types.h> /* Verschiedene komische Typen */
126 #if defined( __hpux ) && ( OS_VERSION == 9 )
127 #include <vfork.h>
128 #endif /* __hpux 9.x, after that it's in unistd.h */
129 #include <sys/wait.h>
130 /* #include <kitchensink.h> */
131 #ifdef __QNX__
132 #include <signal.h>
133 #include <process.h>
134 #endif /* __QNX__ */
135 #include <errno.h>
136
137 #include "types.h" /* for byte and u32 typedefs */
138 #include "g10lib.h"
139 #include "rand-internal.h"
140
141 #ifndef EAGAIN
142 #define EAGAIN EWOULDBLOCK
143 #endif
144 #ifndef STDIN_FILENO
145 #define STDIN_FILENO 0
146 #endif
147 #ifndef STDOUT_FILENO
148 #define STDOUT_FILENO 1
149 #endif
150 #ifndef STDERR_FILENO
151 #define STDERR_FILENO 2
152 #endif
153
154 #define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
155
156 /* The structure containing information on random-data sources. Each
157 * record contains the source and a relative estimate of its usefulness
158 * (weighting) which is used to scale the number of kB of output from the
159 * source (total = data_bytes / usefulness). Usually the weighting is in the
160 * range 1-3 (or 0 for especially useless sources), resulting in a usefulness
161 * rating of 1...3 for each kB of source output (or 0 for the useless
162 * sources).
163 *
164 * If the source is constantly changing (certain types of network statistics
165 * have this characteristic) but the amount of output is small, the weighting
166 * is given as a negative value to indicate that the output should be treated
167 * as if a minimum of 1K of output had been obtained. If the source produces
168 * a lot of output then the scale factor is fractional, resulting in a
169 * usefulness rating of < 1 for each kB of source output.
170 *
171 * In order to provide enough randomness to satisfy the requirements for a
172 * slow poll, we need to accumulate at least 20 points of usefulness (a
173 * typical system should get about 30 points).
174 *
175 * Some potential options are missed out because of special considerations.
176 * pstat -i and pstat -f can produce amazing amounts of output (the record
177 * is 600K on an Oracle server) which floods the buffer and doesn't yield
178 * anything useful (apart from perhaps increasing the entropy of the vmstat
179 * output a bit), so we don't bother with this. pstat in general produces
180 * quite a bit of output, but it doesn't change much over time, so it gets
181 * very low weightings. netstat -s produces constantly-changing output but
182 * also produces quite a bit of it, so it only gets a weighting of 2 rather
183 * than 3. The same holds for netstat -in, which gets 1 rather than 2.
184 *
185 * Some binaries are stored in different locations on different systems so
186 * alternative paths are given for them. The code sorts out which one to
187 * run by itself, once it finds an exectable somewhere it moves on to the
188 * next source. The sources are arranged roughly in their order of
189 * usefulness, occasionally sources which provide a tiny amount of
190 * relatively useless data are placed ahead of ones which provide a large
191 * amount of possibly useful data because another 100 bytes can't hurt, and
192 * it means the buffer won't be swamped by one or two high-output sources.
193 * All the high-output sources are clustered towards the end of the list
194 * for this reason. Some binaries are checked for in a certain order, for
195 * example under Slowaris /usr/ucb/ps understands aux as an arg, but the
196 * others don't. Some systems have conditional defines enabling alternatives
197 * to commands which don't understand the usual options but will provide
198 * enough output (in the form of error messages) to look like they're the
199 * real thing, causing alternative options to be skipped (we can't check the
200 * return either because some commands return peculiar, non-zero status even
201 * when they're working correctly).
202 *
203 * In order to maximise use of the buffer, the code performs a form of run-
204 * length compression on its input where a repeated sequence of bytes is
205 * replaced by the occurrence count mod 256. Some commands output an awful
206 * lot of whitespace, this measure greatly increases the amount of data we
207 * can fit in the buffer.
208 *
209 * When we scale the weighting using the SC() macro, some preprocessors may
210 * give a division by zero warning for the most obvious expression
211 * 'weight ? 1024 / weight : 0' (and gcc 2.7.2.2 dies with a division by zero
212 * trap), so we define a value SC_0 which evaluates to zero when fed to
213 * '1024 / SC_0' */
214
215 #define SC( weight ) ( 1024 / weight ) /* Scale factor */
216 #define SC_0 16384 /* SC( SC_0 ) evaluates to 0 */
217
218 static struct RI {
219 const char *path; /* Path to check for existence of source */
220 const char *arg; /* Args for source */
221 const int usefulness; /* Usefulness of source */
222 FILE *pipe; /* Pipe to source as FILE * */
223 int pipeFD; /* Pipe to source as FD */
224 pid_t pid; /* pid of child for waitpid() */
225 int length; /* Quantity of output produced */
226 const int hasAlternative; /* Whether source has alt.location */
227 } dataSources[] = {
228
229 { "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1 },
230 { "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
231 { "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1 },
232 { "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
233 { "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
234 { "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1 },
235 { "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
236 { "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
237 { "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
238 { "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
239 { "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
240 { "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
241 { "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
242 { "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
243 { "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
244 { "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
245 { "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
246 { "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
247 { "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
248 { "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
249 { "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
250 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
251 SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
252 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
253 SC(-1), NULL, 0, 0, 0, 0 }, /* UDP out */
254 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
255 SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
256 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
257 SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
258 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
259 SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
260 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
261 SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
262 { "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
263 { "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1 },
264 { "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0 },
265 { "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1 },
266 { "/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0 },
267 { "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
268 { "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
269 { "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
270 { "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
271 { "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1 },
272 { "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0 },
273 { "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
274 { "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
275 { "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
276 { "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
277 { "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
278 { "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0 },
279 #if defined( __sgi ) || defined( __hpux )
280 { "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1 },
281 #endif /* __sgi || __hpux */
282 { "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
283 { "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
284 { "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
285 { "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0 }, /*QNX*/
286 { "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
287 { "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
288 /* Unreliable source, depends on system usage */
289 { "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1 },
290 { "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0 },
291 { "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1 },
292 { "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0 },
293 { "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1 },
294 { "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0 },
295 { "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1 },
296 { "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0 },
297 { "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
298 { "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
299 /* pstat is your friend */
300 { "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1 },
301 #ifdef __sgi
302 { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
303 #endif /* __sgi */
304 #ifdef __hpux
305 { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
306 #endif /* __hpux */
307 { "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0 },
308 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
309 SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
310 { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
311 SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
312 { "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
313 { "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
314 { "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
315 { "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
316 { "/usr/sbin/ripquery", "-nw 1 127.0.0.1",
317 SC(0.1), NULL, 0, 0, 0, 0 },
318 { "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
319 { "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
320 { "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
321 { "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
322 /* This is very environment-dependent. If network traffic is low, it'll
323 * probably time out before delivering 5 packets, which is OK because
324 * it'll probably be fixed stuff like ARP anyway */
325 { "/usr/sbin/advfsstat", "-b usr_domain",
326 SC(SC_0), NULL, 0, 0, 0, 0},
327 { "/usr/sbin/advfsstat", "-l 2 usr_domain",
328 SC(0.5), NULL, 0, 0, 0, 0},
329 { "/usr/sbin/advfsstat", "-p usr_domain",
330 SC(SC_0), NULL, 0, 0, 0, 0},
331 /* This is a complex and screwball program. Some systems have things
332 * like rX_dmn, x = integer, for RAID systems, but the statistics are
333 * pretty dodgy */
334 #ifdef __QNXNTO__
335 { "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
336 NULL, 0, 0, 0, 0 },
337 #endif
338 #if 0
339 /* The following aren't enabled since they're somewhat slow and not very
340 * unpredictable, however they give an indication of the sort of sources
341 * you can use (for example the finger might be more useful on a
342 * firewalled internal network) */
343 { "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
344 { "/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
345 SC(0.9), NULL, 0, 0, 0, 0 },
346 { "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
347 #endif /* 0 */
348 { NULL, NULL, 0, NULL, 0, 0, 0, 0 }
349 };
350
351 static byte *gather_buffer; /* buffer for gathering random noise */
352 static int gather_buffer_size; /* size of the memory buffer */
353 static uid_t gatherer_uid;
354
355 /* The message structure used to communicate with the parent */
356 typedef struct {
357 int usefulness; /* usefulness of data */
358 int ndata; /* valid bytes in data */
359 char data[500]; /* gathered data */
360 } GATHER_MSG;
361
362 #ifndef HAVE_WAITPID
363 static pid_t
waitpid(pid_t pid,int * statptr,int options)364 waitpid(pid_t pid, int *statptr, int options)
365 {
366 #ifdef HAVE_WAIT4
367 return wait4(pid, statptr, options, NULL);
368 #else
369 /* If wait4 is also not available, try wait3 for SVR3 variants */
370 /* Less ideal because can't actually request a specific pid */
371 /* For that reason, first check to see if pid is for an */
372 /* existing process. */
373 int tmp_pid, dummystat;;
374 if (kill(pid, 0) == -1) {
375 errno = ECHILD;
376 return -1;
377 }
378 if (statptr == NULL)
379 statptr = &dummystat;
380 while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
381 (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
382 ;
383 return tmp_pid;
384 #endif
385 }
386 #endif
387
388 /* Under SunOS popen() doesn't record the pid of the child process. When
389 * pclose() is called, instead of calling waitpid() for the correct child, it
390 * calls wait() repeatedly until the right child is reaped. The problem is
391 * that this reaps any other children that happen to have died at that
392 * moment, and when their pclose() comes along, the process hangs forever.
393 * The fix is to use a wrapper for popen()/pclose() which saves the pid in
394 * the dataSources structure (code adapted from GNU-libc's popen() call).
395 *
396 * Aut viam inveniam aut faciam */
397
398 static FILE *
my_popen(struct RI * entry)399 my_popen(struct RI *entry)
400 {
401 int pipedes[2];
402 FILE *stream;
403
404 /* Create the pipe */
405 if (pipe(pipedes) < 0)
406 return (NULL);
407
408 /* Fork off the child ("vfork() is like an OS orgasm. All OS's want to
409 * do it, but most just end up faking it" - Chris Wedgwood). If your OS
410 * supports it, you should try to use vfork() here because it's somewhat
411 * more efficient */
412 #if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \
413 defined(__hpux)
414 entry->pid = vfork();
415 #else /* */
416 entry->pid = fork();
417 #endif /* Unixen which have vfork() */
418 if (entry->pid == (pid_t) - 1) {
419 /* The fork failed */
420 close(pipedes[0]);
421 close(pipedes[1]);
422 return (NULL);
423 }
424
425 if (entry->pid == (pid_t) 0) {
426 struct passwd *passwd;
427
428 /* We are the child. Make the read side of the pipe be stdout */
429 if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
430 exit(127);
431
432 /* Now that everything is set up, give up our permissions to make
433 * sure we don't read anything sensitive. If the getpwnam() fails,
434 * we default to -1, which is usually nobody */
435 if (gatherer_uid == (uid_t)-1 && \
436 (passwd = getpwnam("nobody")) != NULL)
437 gatherer_uid = passwd->pw_uid;
438
439 setuid(gatherer_uid);
440
441 /* Close the pipe descriptors */
442 close(pipedes[STDIN_FILENO]);
443 close(pipedes[STDOUT_FILENO]);
444
445 /* Try and exec the program */
446 execl(entry->path, entry->path, entry->arg, NULL);
447
448 /* Die if the exec failed */
449 exit(127);
450 }
451
452 /* We are the parent. Close the irrelevant side of the pipe and open
453 * the relevant side as a new stream. Mark our side of the pipe to
454 * close on exec, so new children won't see it */
455 close(pipedes[STDOUT_FILENO]);
456
457 #ifdef FD_CLOEXEC
458 fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
459 #endif
460
461 stream = fdopen(pipedes[STDIN_FILENO], "r");
462
463 if (stream == NULL) {
464 int savedErrno = errno;
465
466 /* The stream couldn't be opened or the child structure couldn't be
467 * allocated. Kill the child and close the other side of the pipe */
468 kill(entry->pid, SIGKILL);
469 if (stream == NULL)
470 close(pipedes[STDOUT_FILENO]);
471 else
472 fclose(stream);
473
474 waitpid(entry->pid, NULL, 0);
475
476 entry->pid = 0;
477 errno = savedErrno;
478 return (NULL);
479 }
480
481 return (stream);
482 }
483
484 static int
my_pclose(struct RI * entry)485 my_pclose(struct RI *entry)
486 {
487 int status = 0;
488
489 if (fclose(entry->pipe))
490 return (-1);
491
492 /* We ignore the return value from the process because some
493 programs return funny values which would result in the input
494 being discarded even if they executed successfully. This isn't
495 a problem because the result data size threshold will filter
496 out any programs which exit with a usage message without
497 producing useful output. */
498 if (waitpid(entry->pid, NULL, 0) != entry->pid)
499 status = -1;
500
501 entry->pipe = NULL;
502 entry->pid = 0;
503 return (status);
504 }
505
506
507 /* Unix slow poll (without special support for Linux)
508 *
509 * If a few of the randomness sources create a large amount of output then
510 * the slowPoll() stops once the buffer has been filled (but before all the
511 * randomness sources have been sucked dry) so that the 'usefulness' factor
512 * remains below the threshold. For this reason the gatherer buffer has to
513 * be fairly sizeable on moderately loaded systems. This is something of a
514 * bug since the usefulness should be influenced by the amount of output as
515 * well as the source type */
516
517
518 static int
slow_poll(FILE * dbgfp,int dbgall,size_t * nbytes)519 slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
520 {
521 int moreSources;
522 struct timeval tv;
523 fd_set fds;
524 #if defined( __hpux )
525 size_t maxFD = 0;
526 #else
527 int maxFD = 0;
528 #endif /* OS-specific brokenness */
529 int bufPos, i, usefulness = 0;
530 int last_so_far = 0;
531 int any_need_entropy = 0;
532 int delay;
533 int rc;
534
535 /* Fire up each randomness source */
536 FD_ZERO(&fds);
537 for (i = 0; dataSources[i].path != NULL; i++) {
538 /* Since popen() is a fairly heavy function, we check to see whether
539 * the executable exists before we try to run it */
540 if (access(dataSources[i].path, X_OK)) {
541 if( dbgfp && dbgall )
542 fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
543 dataSources[i].hasAlternative ?
544 ", has alternatives" : "");
545 dataSources[i].pipe = NULL;
546 }
547 else
548 dataSources[i].pipe = my_popen(&dataSources[i]);
549
550 if (dataSources[i].pipe != NULL) {
551 dataSources[i].pipeFD = fileno(dataSources[i].pipe);
552 if (dataSources[i].pipeFD > maxFD)
553 maxFD = dataSources[i].pipeFD;
554
555 #ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */
556 fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK);
557 #else
558 #error O_NONBLOCK is missing
559 #endif
560 /* FIXME: We need to make sure that the fd is less than
561 FD_SETSIZE. */
562 FD_SET(dataSources[i].pipeFD, &fds);
563 dataSources[i].length = 0;
564
565 /* If there are alternatives for this command, don't try and
566 * execute them */
567 while (dataSources[i].hasAlternative) {
568 if( dbgfp && dbgall )
569 fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
570 i++;
571 }
572 }
573 }
574
575
576 /* Suck all the data we can get from each of the sources */
577 bufPos = 0;
578 moreSources = 1;
579 delay = 0; /* Return immediately (well, after 100ms) the first time. */
580 while (moreSources && bufPos <= gather_buffer_size) {
581 /* Wait for data to become available from any of the sources, with a
582 * timeout of 10 seconds. This adds even more randomness since data
583 * becomes available in a nondeterministic fashion. Kudos to HP's QA
584 * department for managing to ship a select() which breaks its own
585 * prototype */
586 tv.tv_sec = delay;
587 tv.tv_usec = delay? 0 : 100000;
588
589 #if defined( __hpux ) && ( OS_VERSION == 9 )
590 rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv);
591 #else /* */
592 rc = select(maxFD + 1, &fds, NULL, NULL, &tv);
593 #endif /* __hpux */
594 if (rc == -1)
595 break; /* Ooops; select failed. */
596
597 if (!rc)
598 {
599 /* FIXME: Because we run several tools at once it is
600 unlikely that we will see a block in select at all. */
601 if (!any_need_entropy
602 || last_so_far != (gather_buffer_size - bufPos) )
603 {
604 last_so_far = gather_buffer_size - bufPos;
605 _gcry_random_progress ("need_entropy", 'X',
606 last_so_far,
607 gather_buffer_size);
608 any_need_entropy = 1;
609 }
610 delay = 10; /* Use 10 seconds henceforth. */
611 /* Note that the fd_set is setup again at the end of this loop. */
612 }
613
614 /* One of the sources has data available, read it into the buffer */
615 for (i = 0; dataSources[i].path != NULL; i++) {
616 if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
617 size_t noBytes;
618
619 if ((noBytes = fread(gather_buffer + bufPos, 1,
620 gather_buffer_size - bufPos,
621 dataSources[i].pipe)) == 0) {
622 if (my_pclose(&dataSources[i]) == 0) {
623 int total = 0;
624
625 /* Try and estimate how much entropy we're getting
626 * from a data source */
627 if (dataSources[i].usefulness) {
628 if (dataSources[i].usefulness < 0)
629 total = (dataSources[i].length + 999)
630 / -dataSources[i].usefulness;
631 else
632 total = dataSources[i].length
633 / dataSources[i].usefulness;
634 }
635 if( dbgfp )
636 fprintf(dbgfp,
637 "%s %s contributed %d bytes, "
638 "usefulness = %d\n", dataSources[i].path,
639 (dataSources[i].arg != NULL) ?
640 dataSources[i].arg : "",
641 dataSources[i].length, total);
642 if( dataSources[i].length )
643 usefulness += total;
644 }
645 dataSources[i].pipe = NULL;
646 }
647 else {
648 int currPos = bufPos;
649 int endPos = bufPos + noBytes;
650
651 /* Run-length compress the input byte sequence */
652 while (currPos < endPos) {
653 int ch = gather_buffer[currPos];
654
655 /* If it's a single byte, just copy it over */
656 if (ch != gather_buffer[currPos + 1]) {
657 gather_buffer[bufPos++] = ch;
658 currPos++;
659 }
660 else {
661 int count = 0;
662
663 /* It's a run of repeated bytes, replace them
664 * with the byte count mod 256 */
665 while ((ch == gather_buffer[currPos])
666 && currPos < endPos) {
667 count++;
668 currPos++;
669 }
670 gather_buffer[bufPos++] = count;
671 noBytes -= count - 1;
672 }
673 }
674
675 /* Remember the number of (compressed) bytes of input we
676 * obtained */
677 dataSources[i].length += noBytes;
678 }
679 }
680 }
681
682 /* Check if there is more input available on any of the sources */
683 moreSources = 0;
684 FD_ZERO(&fds);
685 for (i = 0; dataSources[i].path != NULL; i++) {
686 if (dataSources[i].pipe != NULL) {
687 FD_SET(dataSources[i].pipeFD, &fds);
688 moreSources = 1;
689 }
690 }
691 }
692
693 if (any_need_entropy)
694 _gcry_random_progress ("need_entropy", 'X',
695 gather_buffer_size,
696 gather_buffer_size);
697
698 if( dbgfp ) {
699 fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
700 fflush(dbgfp);
701 }
702 *nbytes = bufPos;
703 return usefulness;
704 }
705
706 /****************
707 * Start the gatherer process which writes messages of
708 * type GATHERER_MSG to pipedes
709 */
710 static void
start_gatherer(int pipefd)711 start_gatherer( int pipefd )
712 {
713 FILE *dbgfp = NULL;
714 int dbgall;
715
716 {
717 const char *s = getenv("GCRYPT_RNDUNIX_DBG");
718 if( s ) {
719 dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
720 if( !dbgfp )
721 log_info("can't open debug file `%s': %s\n",
722 s, strerror(errno) );
723 else
724 fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
725 }
726 dbgall = !!getenv("GCRYPT_RNDUNIX_DBGALL");
727 }
728 /* close all files but the ones we need */
729 { int nmax, n1, n2, i;
730 #ifdef _SC_OPEN_MAX
731 if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
732 # ifdef _POSIX_OPEN_MAX
733 nmax = _POSIX_OPEN_MAX;
734 # else
735 nmax = 20; /* assume a reasonable value */
736 # endif
737 }
738 /* AIX returns INT32_MAX instead of a proper value. We assume that
739 * this is always an error and use a reasonable value. */
740 # ifdef INT32_MAX
741 if (nmax == INT32_MAX)
742 nmax = 20;
743 # endif
744 #else /*!_SC_OPEN_MAX*/
745 nmax = 20; /* assume a reasonable value */
746 #endif /*!_SC_OPEN_MAX*/
747 n1 = fileno( stderr );
748 n2 = dbgfp? fileno( dbgfp ) : -1;
749 for(i=0; i < nmax; i++ ) {
750 if( i != n1 && i != n2 && i != pipefd )
751 close(i);
752 }
753 errno = 0;
754 }
755
756
757 /* Set up the buffer. Not ethat we use a plain standard malloc here. */
758 gather_buffer_size = GATHER_BUFSIZE;
759 gather_buffer = malloc( gather_buffer_size );
760 if( !gather_buffer ) {
761 log_error("out of core while allocating the gatherer buffer\n");
762 exit(2);
763 }
764
765 /* Reset the SIGC(H)LD handler to the system default. This is necessary
766 * because if the program which cryptlib is a part of installs its own
767 * SIGC(H)LD handler, it will end up reaping the cryptlib children before
768 * cryptlib can. As a result, my_pclose() will call waitpid() on a
769 * process which has already been reaped by the installed handler and
770 * return an error, so the read data won't be added to the randomness
771 * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
772 * the BSD/Posix SIGCHLD, so we need to handle either possibility */
773 #ifdef SIGCLD
774 signal(SIGCLD, SIG_DFL);
775 #else
776 signal(SIGCHLD, SIG_DFL);
777 #endif
778
779 fclose(stderr); /* Arrghh!! It's Stuart code!! */
780
781 /* Mary goes to Berkeley: NetBSD emits warnings if the standard
782 descriptors are not open when running setuid program. Thus we
783 connect them to the bitbucket if they are not already open. */
784 {
785 struct stat statbuf;
786
787 if (fstat (STDIN_FILENO, &statbuf) == -1 && errno == EBADF)
788 open ("/dev/null",O_RDONLY);
789 if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
790 open ("/dev/null",O_WRONLY);
791 if (fstat (STDERR_FILENO, &statbuf) == -1 && errno == EBADF)
792 open ("/dev/null",O_WRONLY);
793 }
794
795 for(;;) {
796 GATHER_MSG msg;
797 size_t nbytes;
798 const char *p;
799
800 msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
801 p = (const char*)gather_buffer;
802 while( nbytes ) {
803 msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
804 memcpy( msg.data, p, msg.ndata );
805 nbytes -= msg.ndata;
806 p += msg.ndata;
807
808 while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
809 if( errno == EINTR )
810 continue;
811 if( errno == EAGAIN ) {
812 struct timeval tv;
813 tv.tv_sec = 0;
814 tv.tv_usec = 50000;
815 select(0, NULL, NULL, NULL, &tv);
816 continue;
817 }
818 if( errno == EPIPE ) /* parent has exited, so give up */
819 exit(0);
820
821 /* we can't do very much here because stderr is closed */
822 if( dbgfp )
823 fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
824 strerror(errno) );
825 /* we start a new poll to give the system some time */
826 nbytes = 0;
827 break;
828 }
829 }
830 }
831 /* we are killed when the parent dies */
832 }
833
834
835 static int
read_a_msg(int fd,GATHER_MSG * msg)836 read_a_msg( int fd, GATHER_MSG *msg )
837 {
838 char *buffer = (char*)msg;
839 size_t length = sizeof( *msg );
840 int n;
841
842 do {
843 do {
844 n = read(fd, buffer, length );
845 } while( n == -1 && errno == EINTR );
846 if( n == -1 )
847 return -1;
848 buffer += n;
849 length -= n;
850 } while( length );
851 return 0;
852 }
853
854
855 /****************
856 * Using a level of 0 should never block and better add nothing
857 * to the pool. So this is just a dummy for this gatherer.
858 */
859 int
_gcry_rndunix_gather_random(void (* add)(const void *,size_t,enum random_origins),enum random_origins origin,size_t length,int level)860 _gcry_rndunix_gather_random (void (*add)(const void*, size_t,
861 enum random_origins),
862 enum random_origins origin,
863 size_t length, int level )
864 {
865 static pid_t gatherer_pid = 0;
866 static int pipedes[2];
867 GATHER_MSG msg;
868 size_t n;
869
870 if( !level )
871 return 0;
872
873 if( !gatherer_pid ) {
874 /* Make sure we are not setuid. */
875 if ( getuid() != geteuid() )
876 BUG();
877 /* time to start the gatherer process */
878 if( pipe( pipedes ) ) {
879 log_error("pipe() failed: %s\n", strerror(errno));
880 return -1;
881 }
882 gatherer_pid = fork();
883 if( gatherer_pid == -1 ) {
884 log_error("can't for gatherer process: %s\n", strerror(errno));
885 return -1;
886 }
887 if( !gatherer_pid ) {
888 start_gatherer( pipedes[1] );
889 /* oops, can't happen */
890 return -1;
891 }
892 }
893
894 /* now read from the gatherer */
895 while( length ) {
896 int goodness;
897 unsigned long subtract;
898
899 if( read_a_msg( pipedes[0], &msg ) ) {
900 log_error("reading from gatherer pipe failed: %s\n",
901 strerror(errno));
902 return -1;
903 }
904
905
906 if( level > 1 ) {
907 if( msg.usefulness > 30 )
908 goodness = 100;
909 else if ( msg.usefulness )
910 goodness = msg.usefulness * 100 / 30;
911 else
912 goodness = 0;
913 }
914 else if( level ) {
915 if( msg.usefulness > 15 )
916 goodness = 100;
917 else if ( msg.usefulness )
918 goodness = msg.usefulness * 100 / 15;
919 else
920 goodness = 0;
921 }
922 else
923 goodness = 100; /* goodness of level 0 is always 100 % */
924
925 n = msg.ndata;
926 if( n > length )
927 n = length;
928 (*add)( msg.data, n, origin );
929
930 /* this is the trick how we cope with the goodness */
931 subtract = (unsigned long)n * goodness / 100;
932 /* subtract at least 1 byte to avoid infinite loops */
933 length -= subtract ? subtract : 1;
934 }
935
936 return 0;
937 }
938