1
/****************************************************************************
4
* Unix Randomness-Gathering Code *
6
* Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999. *
7
* Heavily modified for GnuPG by Werner Koch *
10
****************************************************************************/
12
/* This module is part of the cryptlib continuously seeded pseudorandom
13
number generator. For usage conditions, see lib_rand.c
15
[Here is the notice from lib_rand.c:]
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".
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:
27
1. Redistributions of source code must retain the above copyright notice
28
and this permission notice in its entirety.
30
2. Redistributions in binary form must reproduce the copyright notice in
31
the documentation and/or other materials provided with the distribution.
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.
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
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:
50
From: pgut001 <pgut001@cs.auckland.ac.nz>
51
Subject: Re: LGPL for the windows entropy gatherer
53
Date: Wed, 22 Aug 2007 03:05:42 +1200
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.
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.
69
From: pgut001 <pgut001@cs.auckland.ac.nz>
70
Subject: Re: LGPL for the windows entropy gatherer
72
Date: Wed, 22 Aug 2007 20:50:08 +1200
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.
78
Sure, it covers the entire entropy-gathering subsystem.
84
/* General includes */
91
/* OS-specific includes */
94
/* Somewhere in the morass of system-specific cruft which OSF/1 pulls in
95
* via the following includes are various endianness defines, so we
96
* undefine the cryptlib ones, which aren't really needed for this module
106
#include <sys/errno.h>
109
#include <sys/time.h> /* SCO and SunOS need this before resource.h */
111
#include <sys/resource.h>
113
#if defined( _AIX ) || defined( __QNX__ )
114
#include <sys/select.h>
119
#include <sys/signal.h>
121
#include <sys/stat.h>
122
#include <sys/types.h> /* Verschiedene komische Typen */
123
#if defined( __hpux ) && ( OS_VERSION == 9 )
125
#endif /* __hpux 9.x, after that it's in unistd.h */
126
#include <sys/wait.h>
127
/* #include <kitchensink.h> */
134
#include "types.h" /* for byte and u32 typedefs */
136
#include "rand-internal.h"
139
#define EAGAIN EWOULDBLOCK
142
#define STDIN_FILENO 0
144
#ifndef STDOUT_FILENO
145
#define STDOUT_FILENO 1
148
#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
150
/* The structure containing information on random-data sources. Each
151
* record contains the source and a relative estimate of its usefulness
152
* (weighting) which is used to scale the number of kB of output from the
153
* source (total = data_bytes / usefulness). Usually the weighting is in the
154
* range 1-3 (or 0 for especially useless sources), resulting in a usefulness
155
* rating of 1...3 for each kB of source output (or 0 for the useless
158
* If the source is constantly changing (certain types of network statistics
159
* have this characteristic) but the amount of output is small, the weighting
160
* is given as a negative value to indicate that the output should be treated
161
* as if a minimum of 1K of output had been obtained. If the source produces
162
* a lot of output then the scale factor is fractional, resulting in a
163
* usefulness rating of < 1 for each kB of source output.
165
* In order to provide enough randomness to satisfy the requirements for a
166
* slow poll, we need to accumulate at least 20 points of usefulness (a
167
* typical system should get about 30 points).
169
* Some potential options are missed out because of special considerations.
170
* pstat -i and pstat -f can produce amazing amounts of output (the record
171
* is 600K on an Oracle server) which floods the buffer and doesn't yield
172
* anything useful (apart from perhaps increasing the entropy of the vmstat
173
* output a bit), so we don't bother with this. pstat in general produces
174
* quite a bit of output, but it doesn't change much over time, so it gets
175
* very low weightings. netstat -s produces constantly-changing output but
176
* also produces quite a bit of it, so it only gets a weighting of 2 rather
177
* than 3. The same holds for netstat -in, which gets 1 rather than 2.
179
* Some binaries are stored in different locations on different systems so
180
* alternative paths are given for them. The code sorts out which one to
181
* run by itself, once it finds an exectable somewhere it moves on to the
182
* next source. The sources are arranged roughly in their order of
183
* usefulness, occasionally sources which provide a tiny amount of
184
* relatively useless data are placed ahead of ones which provide a large
185
* amount of possibly useful data because another 100 bytes can't hurt, and
186
* it means the buffer won't be swamped by one or two high-output sources.
187
* All the high-output sources are clustered towards the end of the list
188
* for this reason. Some binaries are checked for in a certain order, for
189
* example under Slowaris /usr/ucb/ps understands aux as an arg, but the
190
* others don't. Some systems have conditional defines enabling alternatives
191
* to commands which don't understand the usual options but will provide
192
* enough output (in the form of error messages) to look like they're the
193
* real thing, causing alternative options to be skipped (we can't check the
194
* return either because some commands return peculiar, non-zero status even
195
* when they're working correctly).
197
* In order to maximise use of the buffer, the code performs a form of run-
198
* length compression on its input where a repeated sequence of bytes is
199
* replaced by the occurrence count mod 256. Some commands output an awful
200
* lot of whitespace, this measure greatly increases the amount of data we
201
* can fit in the buffer.
203
* When we scale the weighting using the SC() macro, some preprocessors may
204
* give a division by zero warning for the most obvious expression
205
* 'weight ? 1024 / weight : 0' (and gcc 2.7.2.2 dies with a division by zero
206
* trap), so we define a value SC_0 which evaluates to zero when fed to
209
#define SC( weight ) ( 1024 / weight ) /* Scale factor */
210
#define SC_0 16384 /* SC( SC_0 ) evalutes to 0 */
213
const char *path; /* Path to check for existence of source */
214
const char *arg; /* Args for source */
215
const int usefulness; /* Usefulness of source */
216
FILE *pipe; /* Pipe to source as FILE * */
217
int pipeFD; /* Pipe to source as FD */
218
pid_t pid; /* pid of child for waitpid() */
219
int length; /* Quantity of output produced */
220
const int hasAlternative; /* Whether source has alt.location */
223
{ "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1 },
224
{ "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
225
{ "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1 },
226
{ "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
227
{ "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
228
{ "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1 },
229
{ "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
230
{ "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
231
{ "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
232
{ "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
233
{ "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
234
{ "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
235
{ "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
236
{ "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
237
{ "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
238
{ "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
239
{ "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
240
{ "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
241
{ "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
242
{ "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
243
{ "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
244
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
245
SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
246
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
247
SC(-1), NULL, 0, 0, 0, 0 }, /* UDP out */
248
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
249
SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
250
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
251
SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
252
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
253
SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
254
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
255
SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
256
{ "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
257
{ "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1 },
258
{ "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0 },
259
{ "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1 },
260
{ "/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0 },
261
{ "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
262
{ "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
263
{ "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
264
{ "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
265
{ "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1 },
266
{ "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0 },
267
{ "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
268
{ "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
269
{ "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
270
{ "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
271
{ "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
272
{ "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0 },
273
#if defined( __sgi ) || defined( __hpux )
274
{ "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1 },
275
#endif /* __sgi || __hpux */
276
{ "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
277
{ "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
278
{ "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
279
{ "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0 }, /*QNX*/
280
{ "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
281
{ "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
282
/* Unreliable source, depends on system usage */
283
{ "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1 },
284
{ "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0 },
285
{ "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1 },
286
{ "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0 },
287
{ "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1 },
288
{ "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0 },
289
{ "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1 },
290
{ "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0 },
291
{ "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
292
{ "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
293
/* pstat is your friend */
294
{ "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1 },
296
{ "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
299
{ "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
301
{ "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0 },
302
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
303
SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
304
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
305
SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
306
{ "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
307
{ "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
308
{ "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
309
{ "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
310
{ "/usr/sbin/ripquery", "-nw 1 127.0.0.1",
311
SC(0.1), NULL, 0, 0, 0, 0 },
312
{ "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
313
{ "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
314
{ "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
315
{ "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
316
/* This is very environment-dependant. If network traffic is low, it'll
317
* probably time out before delivering 5 packets, which is OK because
318
* it'll probably be fixed stuff like ARP anyway */
319
{ "/usr/sbin/advfsstat", "-b usr_domain",
320
SC(SC_0), NULL, 0, 0, 0, 0},
321
{ "/usr/sbin/advfsstat", "-l 2 usr_domain",
322
SC(0.5), NULL, 0, 0, 0, 0},
323
{ "/usr/sbin/advfsstat", "-p usr_domain",
324
SC(SC_0), NULL, 0, 0, 0, 0},
325
/* This is a complex and screwball program. Some systems have things
326
* like rX_dmn, x = integer, for RAID systems, but the statistics are
329
{ "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
333
/* The following aren't enabled since they're somewhat slow and not very
334
* unpredictable, however they give an indication of the sort of sources
335
* you can use (for example the finger might be more useful on a
336
* firewalled internal network) */
337
{ "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
338
{ "/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
339
SC(0.9), NULL, 0, 0, 0, 0 },
340
{ "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
342
{ NULL, NULL, 0, NULL, 0, 0, 0, 0 }
345
static byte *gather_buffer; /* buffer for gathering random noise */
346
static int gather_buffer_size; /* size of the memory buffer */
347
static uid_t gatherer_uid;
349
/* The message structure used to communicate with the parent */
351
int usefulness; /* usefulness of data */
352
int ndata; /* valid bytes in data */
353
char data[500]; /* gathered data */
358
waitpid(pid_t pid, int *statptr, int options)
361
return wait4(pid, statptr, options, NULL);
363
/* If wait4 is also not available, try wait3 for SVR3 variants */
364
/* Less ideal because can't actually request a specific pid */
365
/* For that reason, first check to see if pid is for an */
366
/* existing process. */
367
int tmp_pid, dummystat;;
368
if (kill(pid, 0) == -1) {
373
statptr = &dummystat;
374
while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
375
(tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
382
/* Under SunOS popen() doesn't record the pid of the child process. When
383
* pclose() is called, instead of calling waitpid() for the correct child, it
384
* calls wait() repeatedly until the right child is reaped. The problem is
385
* that this reaps any other children that happen to have died at that
386
* moment, and when their pclose() comes along, the process hangs forever.
387
* The fix is to use a wrapper for popen()/pclose() which saves the pid in
388
* the dataSources structure (code adapted from GNU-libc's popen() call).
390
* Aut viam inveniam aut faciam */
393
my_popen(struct RI *entry)
398
/* Create the pipe */
399
if (pipe(pipedes) < 0)
402
/* Fork off the child ("vfork() is like an OS orgasm. All OS's want to
403
* do it, but most just end up faking it" - Chris Wedgwood). If your OS
404
* supports it, you should try to use vfork() here because it's somewhat
406
#if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \
408
entry->pid = vfork();
411
#endif /* Unixen which have vfork() */
412
if (entry->pid == (pid_t) - 1) {
413
/* The fork failed */
419
if (entry->pid == (pid_t) 0) {
420
struct passwd *passwd;
422
/* We are the child. Make the read side of the pipe be stdout */
423
if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
426
/* Now that everything is set up, give up our permissions to make
427
* sure we don't read anything sensitive. If the getpwnam() fails,
428
* we default to -1, which is usually nobody */
429
if (gatherer_uid == (uid_t)-1 && \
430
(passwd = getpwnam("nobody")) != NULL)
431
gatherer_uid = passwd->pw_uid;
433
setuid(gatherer_uid);
435
/* Close the pipe descriptors */
436
close(pipedes[STDIN_FILENO]);
437
close(pipedes[STDOUT_FILENO]);
439
/* Try and exec the program */
440
execl(entry->path, entry->path, entry->arg, NULL);
442
/* Die if the exec failed */
446
/* We are the parent. Close the irrelevant side of the pipe and open
447
* the relevant side as a new stream. Mark our side of the pipe to
448
* close on exec, so new children won't see it */
449
close(pipedes[STDOUT_FILENO]);
452
fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
455
stream = fdopen(pipedes[STDIN_FILENO], "r");
457
if (stream == NULL) {
458
int savedErrno = errno;
460
/* The stream couldn't be opened or the child structure couldn't be
461
* allocated. Kill the child and close the other side of the pipe */
462
kill(entry->pid, SIGKILL);
464
close(pipedes[STDOUT_FILENO]);
468
waitpid(entry->pid, NULL, 0);
479
my_pclose(struct RI *entry)
483
if (fclose(entry->pipe))
486
/* We ignore the return value from the process because some
487
programs return funny values which would result in the input
488
being discarded even if they executed successfully. This isn't
489
a problem because the result data size threshold will filter
490
out any programs which exit with a usage message without
491
producing useful output. */
492
if (waitpid(entry->pid, NULL, 0) != entry->pid)
501
/* Unix slow poll (without special support for Linux)
503
* If a few of the randomness sources create a large amount of output then
504
* the slowPoll() stops once the buffer has been filled (but before all the
505
* randomness sources have been sucked dry) so that the 'usefulness' factor
506
* remains below the threshold. For this reason the gatherer buffer has to
507
* be fairly sizeable on moderately loaded systems. This is something of a
508
* bug since the usefulness should be influenced by the amount of output as
509
* well as the source type */
513
slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
518
#if defined( __hpux )
522
#endif /* OS-specific brokenness */
523
int bufPos, i, usefulness = 0;
526
/* Fire up each randomness source */
528
for (i = 0; dataSources[i].path != NULL; i++) {
529
/* Since popen() is a fairly heavy function, we check to see whether
530
* the executable exists before we try to run it */
531
if (access(dataSources[i].path, X_OK)) {
532
if( dbgfp && dbgall )
533
fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
534
dataSources[i].hasAlternative ?
535
", has alternatives" : "");
536
dataSources[i].pipe = NULL;
539
dataSources[i].pipe = my_popen(&dataSources[i]);
541
if (dataSources[i].pipe != NULL) {
542
dataSources[i].pipeFD = fileno(dataSources[i].pipe);
543
if (dataSources[i].pipeFD > maxFD)
544
maxFD = dataSources[i].pipeFD;
546
#ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */
547
fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK);
549
#error O_NONBLOCK is missing
552
FD_SET(dataSources[i].pipeFD, &fds);
553
dataSources[i].length = 0;
555
/* If there are alternatives for this command, don't try and
557
while (dataSources[i].hasAlternative) {
558
if( dbgfp && dbgall )
559
fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
566
/* Suck all the data we can get from each of the sources */
569
while (moreSources && bufPos <= gather_buffer_size) {
570
/* Wait for data to become available from any of the sources, with a
571
* timeout of 10 seconds. This adds even more randomness since data
572
* becomes available in a nondeterministic fashion. Kudos to HP's QA
573
* department for managing to ship a select() which breaks its own
578
#if defined( __hpux ) && ( OS_VERSION == 9 )
579
if (select(maxFD + 1, (int *)&fds, NULL, NULL, &tv) == -1)
581
if (select(maxFD + 1, &fds, NULL, NULL, &tv) == -1)
585
/* One of the sources has data available, read it into the buffer */
586
for (i = 0; dataSources[i].path != NULL; i++) {
587
if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
590
if ((noBytes = fread(gather_buffer + bufPos, 1,
591
gather_buffer_size - bufPos,
592
dataSources[i].pipe)) == 0) {
593
if (my_pclose(&dataSources[i]) == 0) {
596
/* Try and estimate how much entropy we're getting
597
* from a data source */
598
if (dataSources[i].usefulness) {
599
if (dataSources[i].usefulness < 0)
600
total = (dataSources[i].length + 999)
601
/ -dataSources[i].usefulness;
603
total = dataSources[i].length
604
/ dataSources[i].usefulness;
608
"%s %s contributed %d bytes, "
609
"usefulness = %d\n", dataSources[i].path,
610
(dataSources[i].arg != NULL) ?
611
dataSources[i].arg : "",
612
dataSources[i].length, total);
613
if( dataSources[i].length )
616
dataSources[i].pipe = NULL;
619
int currPos = bufPos;
620
int endPos = bufPos + noBytes;
622
/* Run-length compress the input byte sequence */
623
while (currPos < endPos) {
624
int ch = gather_buffer[currPos];
626
/* If it's a single byte, just copy it over */
627
if (ch != gather_buffer[currPos + 1]) {
628
gather_buffer[bufPos++] = ch;
634
/* It's a run of repeated bytes, replace them
635
* with the byte count mod 256 */
636
while ((ch == gather_buffer[currPos])
637
&& currPos < endPos) {
641
gather_buffer[bufPos++] = count;
642
noBytes -= count - 1;
646
/* Remember the number of (compressed) bytes of input we
648
dataSources[i].length += noBytes;
653
/* Check if there is more input available on any of the sources */
656
for (i = 0; dataSources[i].path != NULL; i++) {
657
if (dataSources[i].pipe != NULL) {
658
FD_SET(dataSources[i].pipeFD, &fds);
665
fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
673
* Start the gatherer process which writes messages of
674
* type GATHERER_MSG to pipedes
677
start_gatherer( int pipefd )
683
const char *s = getenv("GNUPG_RNDUNIX_DBG");
685
dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
687
log_info("can't open debug file `%s': %s\n",
688
s, strerror(errno) );
690
fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
692
dbgall = !!getenv("GNUPG_RNDUNIX_DBGALL");
694
/* close all files but the ones we need */
695
{ int nmax, n1, n2, i;
697
if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
698
#ifdef _POSIX_OPEN_MAX
699
nmax = _POSIX_OPEN_MAX;
701
nmax = 20; /* assume a reasonable value */
704
#else /*!_SC_OPEN_MAX*/
705
nmax = 20; /* assume a reasonable value */
706
#endif /*!_SC_OPEN_MAX*/
707
n1 = fileno( stderr );
708
n2 = dbgfp? fileno( dbgfp ) : -1;
709
for(i=0; i < nmax; i++ ) {
710
if( i != n1 && i != n2 && i != pipefd )
717
/* Set up the buffer. Not ethat we use a plain standard malloc here. */
718
gather_buffer_size = GATHER_BUFSIZE;
719
gather_buffer = malloc( gather_buffer_size );
720
if( !gather_buffer ) {
721
log_error("out of core while allocating the gatherer buffer\n");
725
/* Reset the SIGC(H)LD handler to the system default. This is necessary
726
* because if the program which cryptlib is a part of installs its own
727
* SIGC(H)LD handler, it will end up reaping the cryptlib children before
728
* cryptlib can. As a result, my_pclose() will call waitpid() on a
729
* process which has already been reaped by the installed handler and
730
* return an error, so the read data won't be added to the randomness
731
* pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
732
* the BSD/Posix SIGCHLD, so we need to handle either possibility */
734
signal(SIGCLD, SIG_DFL);
736
signal(SIGCHLD, SIG_DFL);
739
fclose(stderr); /* Arrghh!! It's Stuart code!! */
746
msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
749
msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
750
memcpy( msg.data, p, msg.ndata );
754
while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
757
if( errno == EAGAIN ) {
761
select(0, NULL, NULL, NULL, &tv);
764
if( errno == EPIPE ) /* parent has exited, so give up */
767
/* we can't do very much here because stderr is closed */
769
fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
771
/* we start a new poll to give the system some time */
777
/* we are killed when the parent dies */
782
read_a_msg( int fd, GATHER_MSG *msg )
784
char *buffer = (char*)msg;
785
size_t length = sizeof( *msg );
790
n = read(fd, buffer, length );
791
} while( n == -1 && errno == EINTR );
802
* Using a level of 0 should never block and better add nothing
803
* to the pool. So this is just a dummy for this gatherer.
806
_gcry_rndunix_gather_random (void (*add)(const void*, size_t,
807
enum random_origins),
808
enum random_origins origin,
809
size_t length, int level )
811
static pid_t gatherer_pid = 0;
812
static int pipedes[2];
819
if( !gatherer_pid ) {
820
/* Make sure we are not setuid. */
821
if ( getuid() != geteuid() )
823
/* time to start the gatherer process */
824
if( pipe( pipedes ) ) {
825
log_error("pipe() failed: %s\n", strerror(errno));
828
gatherer_pid = fork();
829
if( gatherer_pid == -1 ) {
830
log_error("can't for gatherer process: %s\n", strerror(errno));
833
if( !gatherer_pid ) {
834
start_gatherer( pipedes[1] );
835
/* oops, can't happen */
840
/* now read from the gatherer */
845
if( read_a_msg( pipedes[0], &msg ) ) {
846
log_error("reading from gatherer pipe failed: %s\n",
853
if( msg.usefulness > 30 )
855
else if ( msg.usefulness )
856
goodness = msg.usefulness * 100 / 30;
861
if( msg.usefulness > 15 )
863
else if ( msg.usefulness )
864
goodness = msg.usefulness * 100 / 15;
869
goodness = 100; /* goodness of level 0 is always 100 % */
874
(*add)( msg.data, n, origin );
876
/* this is the trick how we cope with the goodness */
877
subtract = (ulong)n * goodness / 100;
878
/* subtract at least 1 byte to avoid infinite loops */
879
length -= subtract ? subtract : 1;