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#include <string.h> 90 91/* OS-specific includes */ 92 93#ifdef __osf__ 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 97 * anyway */ 98#undef BIG_ENDIAN 99#undef LITTLE_ENDIAN 100#endif /* __osf__ */ 101 102#include <unistd.h> 103#include <fcntl.h> 104#include <pwd.h> 105#ifndef __QNX__ 106#include <sys/errno.h> 107#include <sys/ipc.h> 108#endif /* __QNX__ */ 109#include <sys/time.h> /* SCO and SunOS need this before resource.h */ 110#ifndef __QNX__ 111#include <sys/resource.h> 112#endif /* __QNX__ */ 113#if defined( _AIX ) || defined( __QNX__ ) 114#include <sys/select.h> 115#endif /* _AIX */ 116#ifndef __QNX__ 117#include <sys/shm.h> 118#include <signal.h> 119#include <sys/signal.h> 120#endif /* __QNX__ */ 121#include <sys/stat.h> 122#include <sys/types.h> /* Verschiedene komische Typen */ 123#if defined( __hpux ) && ( OS_VERSION == 9 ) 124#include <vfork.h> 125#endif /* __hpux 9.x, after that it's in unistd.h */ 126#include <sys/wait.h> 127/* #include <kitchensink.h> */ 128#ifdef __QNX__ 129#include <signal.h> 130#include <process.h> 131#endif /* __QNX__ */ 132#include <errno.h> 133 134#include "types.h" /* for byte and u32 typedefs */ 135#include "g10lib.h" 136#include "rand-internal.h" 137 138#ifndef EAGAIN 139#define EAGAIN EWOULDBLOCK 140#endif 141#ifndef STDIN_FILENO 142#define STDIN_FILENO 0 143#endif 144#ifndef STDOUT_FILENO 145#define STDOUT_FILENO 1 146#endif 147 148#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */ 149 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 156 * sources). 157 * 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. 164 * 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). 168 * 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. 178 * 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). 196 * 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. 202 * 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 207 * '1024 / SC_0' */ 208 209#define SC( weight ) ( 1024 / weight ) /* Scale factor */ 210#define SC_0 16384 /* SC( SC_0 ) evaluates to 0 */ 211 212static struct RI { 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 */ 221} dataSources[] = { 222 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 }, 295#ifdef __sgi 296 { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 }, 297#endif /* __sgi */ 298#ifdef __hpux 299 { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 }, 300#endif /* __hpux */ 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 327 * pretty dodgy */ 328#ifdef __QNXNTO__ 329 { "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3), 330 NULL, 0, 0, 0, 0 }, 331#endif 332#if 0 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 }, 341#endif /* 0 */ 342 { NULL, NULL, 0, NULL, 0, 0, 0, 0 } 343}; 344 345static byte *gather_buffer; /* buffer for gathering random noise */ 346static int gather_buffer_size; /* size of the memory buffer */ 347static uid_t gatherer_uid; 348 349/* The message structure used to communicate with the parent */ 350typedef struct { 351 int usefulness; /* usefulness of data */ 352 int ndata; /* valid bytes in data */ 353 char data[500]; /* gathered data */ 354} GATHER_MSG; 355 356#ifndef HAVE_WAITPID 357static pid_t 358waitpid(pid_t pid, int *statptr, int options) 359{ 360#ifdef HAVE_WAIT4 361 return wait4(pid, statptr, options, NULL); 362#else 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) { 369 errno = ECHILD; 370 return -1; 371 } 372 if (statptr == NULL) 373 statptr = &dummystat; 374 while (((tmp_pid = wait3(statptr, options, 0)) != pid) && 375 (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1)) 376 ; 377 return tmp_pid; 378#endif 379} 380#endif 381 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). 389 * 390 * Aut viam inveniam aut faciam */ 391 392static FILE * 393my_popen(struct RI *entry) 394{ 395 int pipedes[2]; 396 FILE *stream; 397 398 /* Create the pipe */ 399 if (pipe(pipedes) < 0) 400 return (NULL); 401 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 405 * more efficient */ 406#if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \ 407 defined(__hpux) 408 entry->pid = vfork(); 409#else /* */ 410 entry->pid = fork(); 411#endif /* Unixen which have vfork() */ 412 if (entry->pid == (pid_t) - 1) { 413 /* The fork failed */ 414 close(pipedes[0]); 415 close(pipedes[1]); 416 return (NULL); 417 } 418 419 if (entry->pid == (pid_t) 0) { 420 struct passwd *passwd; 421 422 /* We are the child. Make the read side of the pipe be stdout */ 423 if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0) 424 exit(127); 425 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; 432 433 setuid(gatherer_uid); 434 435 /* Close the pipe descriptors */ 436 close(pipedes[STDIN_FILENO]); 437 close(pipedes[STDOUT_FILENO]); 438 439 /* Try and exec the program */ 440 execl(entry->path, entry->path, entry->arg, NULL); 441 442 /* Die if the exec failed */ 443 exit(127); 444 } 445 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]); 450 451#ifdef FD_CLOEXEC 452 fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC); 453#endif 454 455 stream = fdopen(pipedes[STDIN_FILENO], "r"); 456 457 if (stream == NULL) { 458 int savedErrno = errno; 459 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); 463 if (stream == NULL) 464 close(pipedes[STDOUT_FILENO]); 465 else 466 fclose(stream); 467 468 waitpid(entry->pid, NULL, 0); 469 470 entry->pid = 0; 471 errno = savedErrno; 472 return (NULL); 473 } 474 475 return (stream); 476} 477 478static int 479my_pclose(struct RI *entry) 480{ 481 int status = 0; 482 483 if (fclose(entry->pipe)) 484 return (-1); 485 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) 493 status = -1; 494 495 entry->pipe = NULL; 496 entry->pid = 0; 497 return (status); 498} 499 500 501/* Unix slow poll (without special support for Linux) 502 * 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 */ 510 511 512static int 513slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes ) 514{ 515 int moreSources; 516 struct timeval tv; 517 fd_set fds; 518#if defined( __hpux ) 519 size_t maxFD = 0; 520#else 521 int maxFD = 0; 522#endif /* OS-specific brokenness */ 523 int bufPos, i, usefulness = 0; 524 int last_so_far = 0; 525 int any_need_entropy = 0; 526 int delay; 527 int rc; 528 529 /* Fire up each randomness source */ 530 FD_ZERO(&fds); 531 for (i = 0; dataSources[i].path != NULL; i++) { 532 /* Since popen() is a fairly heavy function, we check to see whether 533 * the executable exists before we try to run it */ 534 if (access(dataSources[i].path, X_OK)) { 535 if( dbgfp && dbgall ) 536 fprintf(dbgfp, "%s not present%s\n", dataSources[i].path, 537 dataSources[i].hasAlternative ? 538 ", has alternatives" : ""); 539 dataSources[i].pipe = NULL; 540 } 541 else 542 dataSources[i].pipe = my_popen(&dataSources[i]); 543 544 if (dataSources[i].pipe != NULL) { 545 dataSources[i].pipeFD = fileno(dataSources[i].pipe); 546 if (dataSources[i].pipeFD > maxFD) 547 maxFD = dataSources[i].pipeFD; 548 549#ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */ 550 fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK); 551#else 552#error O_NONBLOCK is missing 553#endif 554 /* FIXME: We need to make sure that the fd is less than 555 FD_SETSIZE. */ 556 FD_SET(dataSources[i].pipeFD, &fds); 557 dataSources[i].length = 0; 558 559 /* If there are alternatives for this command, don't try and 560 * execute them */ 561 while (dataSources[i].hasAlternative) { 562 if( dbgfp && dbgall ) 563 fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path); 564 i++; 565 } 566 } 567 } 568 569 570 /* Suck all the data we can get from each of the sources */ 571 bufPos = 0; 572 moreSources = 1; 573 delay = 0; /* Return immediately (well, after 100ms) the first time. */ 574 while (moreSources && bufPos <= gather_buffer_size) { 575 /* Wait for data to become available from any of the sources, with a 576 * timeout of 10 seconds. This adds even more randomness since data 577 * becomes available in a nondeterministic fashion. Kudos to HP's QA 578 * department for managing to ship a select() which breaks its own 579 * prototype */ 580 tv.tv_sec = delay; 581 tv.tv_usec = delay? 0 : 100000; 582 583#if defined( __hpux ) && ( OS_VERSION == 9 ) 584 rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv); 585#else /* */ 586 rc = select(maxFD + 1, &fds, NULL, NULL, &tv); 587#endif /* __hpux */ 588 if (rc == -1) 589 break; /* Ooops; select failed. */ 590 591 if (!rc) 592 { 593 /* FIXME: Because we run several tools at once it is 594 unlikely that we will see a block in select at all. */ 595 if (!any_need_entropy 596 || last_so_far != (gather_buffer_size - bufPos) ) 597 { 598 last_so_far = gather_buffer_size - bufPos; 599 _gcry_random_progress ("need_entropy", 'X', 600 last_so_far, 601 gather_buffer_size); 602 any_need_entropy = 1; 603 } 604 delay = 10; /* Use 10 seconds henceforth. */ 605 /* Note that the fd_set is setup again at the end of this loop. */ 606 } 607 608 /* One of the sources has data available, read it into the buffer */ 609 for (i = 0; dataSources[i].path != NULL; i++) { 610 if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) { 611 size_t noBytes; 612 613 if ((noBytes = fread(gather_buffer + bufPos, 1, 614 gather_buffer_size - bufPos, 615 dataSources[i].pipe)) == 0) { 616 if (my_pclose(&dataSources[i]) == 0) { 617 int total = 0; 618 619 /* Try and estimate how much entropy we're getting 620 * from a data source */ 621 if (dataSources[i].usefulness) { 622 if (dataSources[i].usefulness < 0) 623 total = (dataSources[i].length + 999) 624 / -dataSources[i].usefulness; 625 else 626 total = dataSources[i].length 627 / dataSources[i].usefulness; 628 } 629 if( dbgfp ) 630 fprintf(dbgfp, 631 "%s %s contributed %d bytes, " 632 "usefulness = %d\n", dataSources[i].path, 633 (dataSources[i].arg != NULL) ? 634 dataSources[i].arg : "", 635 dataSources[i].length, total); 636 if( dataSources[i].length ) 637 usefulness += total; 638 } 639 dataSources[i].pipe = NULL; 640 } 641 else { 642 int currPos = bufPos; 643 int endPos = bufPos + noBytes; 644 645 /* Run-length compress the input byte sequence */ 646 while (currPos < endPos) { 647 int ch = gather_buffer[currPos]; 648 649 /* If it's a single byte, just copy it over */ 650 if (ch != gather_buffer[currPos + 1]) { 651 gather_buffer[bufPos++] = ch; 652 currPos++; 653 } 654 else { 655 int count = 0; 656 657 /* It's a run of repeated bytes, replace them 658 * with the byte count mod 256 */ 659 while ((ch == gather_buffer[currPos]) 660 && currPos < endPos) { 661 count++; 662 currPos++; 663 } 664 gather_buffer[bufPos++] = count; 665 noBytes -= count - 1; 666 } 667 } 668 669 /* Remember the number of (compressed) bytes of input we 670 * obtained */ 671 dataSources[i].length += noBytes; 672 } 673 } 674 } 675 676 /* Check if there is more input available on any of the sources */ 677 moreSources = 0; 678 FD_ZERO(&fds); 679 for (i = 0; dataSources[i].path != NULL; i++) { 680 if (dataSources[i].pipe != NULL) { 681 FD_SET(dataSources[i].pipeFD, &fds); 682 moreSources = 1; 683 } 684 } 685 } 686 687 if (any_need_entropy) 688 _gcry_random_progress ("need_entropy", 'X', 689 gather_buffer_size, 690 gather_buffer_size); 691 692 if( dbgfp ) { 693 fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness); 694 fflush(dbgfp); 695 } 696 *nbytes = bufPos; 697 return usefulness; 698} 699 700/**************** 701 * Start the gatherer process which writes messages of 702 * type GATHERER_MSG to pipedes 703 */ 704static void 705start_gatherer( int pipefd ) 706{ 707 FILE *dbgfp = NULL; 708 int dbgall; 709 710 { 711 const char *s = getenv("GNUPG_RNDUNIX_DBG"); 712 if( s ) { 713 dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a"); 714 if( !dbgfp ) 715 log_info("can't open debug file `%s': %s\n", 716 s, strerror(errno) ); 717 else 718 fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid()); 719 } 720 dbgall = !!getenv("GNUPG_RNDUNIX_DBGALL"); 721 } 722 /* close all files but the ones we need */ 723 { int nmax, n1, n2, i; 724#ifdef _SC_OPEN_MAX 725 if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) { 726#ifdef _POSIX_OPEN_MAX 727 nmax = _POSIX_OPEN_MAX; 728#else 729 nmax = 20; /* assume a reasonable value */ 730#endif 731 } 732#else /*!_SC_OPEN_MAX*/ 733 nmax = 20; /* assume a reasonable value */ 734#endif /*!_SC_OPEN_MAX*/ 735 n1 = fileno( stderr ); 736 n2 = dbgfp? fileno( dbgfp ) : -1; 737 for(i=0; i < nmax; i++ ) { 738 if( i != n1 && i != n2 && i != pipefd ) 739 close(i); 740 } 741 errno = 0; 742 } 743 744 745 /* Set up the buffer. Not ethat we use a plain standard malloc here. */ 746 gather_buffer_size = GATHER_BUFSIZE; 747 gather_buffer = malloc( gather_buffer_size ); 748 if( !gather_buffer ) { 749 log_error("out of core while allocating the gatherer buffer\n"); 750 exit(2); 751 } 752 753 /* Reset the SIGC(H)LD handler to the system default. This is necessary 754 * because if the program which cryptlib is a part of installs its own 755 * SIGC(H)LD handler, it will end up reaping the cryptlib children before 756 * cryptlib can. As a result, my_pclose() will call waitpid() on a 757 * process which has already been reaped by the installed handler and 758 * return an error, so the read data won't be added to the randomness 759 * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and 760 * the BSD/Posix SIGCHLD, so we need to handle either possibility */ 761#ifdef SIGCLD 762 signal(SIGCLD, SIG_DFL); 763#else 764 signal(SIGCHLD, SIG_DFL); 765#endif 766 767 fclose(stderr); /* Arrghh!! It's Stuart code!! */ 768 769 for(;;) { 770 GATHER_MSG msg; 771 size_t nbytes; 772 const char *p; 773 774 msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes ); 775 p = gather_buffer; 776 while( nbytes ) { 777 msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes; 778 memcpy( msg.data, p, msg.ndata ); 779 nbytes -= msg.ndata; 780 p += msg.ndata; 781 782 while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) { 783 if( errno == EINTR ) 784 continue; 785 if( errno == EAGAIN ) { 786 struct timeval tv; 787 tv.tv_sec = 0; 788 tv.tv_usec = 50000; 789 select(0, NULL, NULL, NULL, &tv); 790 continue; 791 } 792 if( errno == EPIPE ) /* parent has exited, so give up */ 793 exit(0); 794 795 /* we can't do very much here because stderr is closed */ 796 if( dbgfp ) 797 fprintf(dbgfp, "gatherer can't write to pipe: %s\n", 798 strerror(errno) ); 799 /* we start a new poll to give the system some time */ 800 nbytes = 0; 801 break; 802 } 803 } 804 } 805 /* we are killed when the parent dies */ 806} 807 808 809static int 810read_a_msg( int fd, GATHER_MSG *msg ) 811{ 812 char *buffer = (char*)msg; 813 size_t length = sizeof( *msg ); 814 int n; 815 816 do { 817 do { 818 n = read(fd, buffer, length ); 819 } while( n == -1 && errno == EINTR ); 820 if( n == -1 ) 821 return -1; 822 buffer += n; 823 length -= n; 824 } while( length ); 825 return 0; 826} 827 828 829/**************** 830 * Using a level of 0 should never block and better add nothing 831 * to the pool. So this is just a dummy for this gatherer. 832 */ 833int 834_gcry_rndunix_gather_random (void (*add)(const void*, size_t, 835 enum random_origins), 836 enum random_origins origin, 837 size_t length, int level ) 838{ 839 static pid_t gatherer_pid = 0; 840 static int pipedes[2]; 841 GATHER_MSG msg; 842 size_t n; 843 844 if( !level ) 845 return 0; 846 847 if( !gatherer_pid ) { 848 /* Make sure we are not setuid. */ 849 if ( getuid() != geteuid() ) 850 BUG(); 851 /* time to start the gatherer process */ 852 if( pipe( pipedes ) ) { 853 log_error("pipe() failed: %s\n", strerror(errno)); 854 return -1; 855 } 856 gatherer_pid = fork(); 857 if( gatherer_pid == -1 ) { 858 log_error("can't for gatherer process: %s\n", strerror(errno)); 859 return -1; 860 } 861 if( !gatherer_pid ) { 862 start_gatherer( pipedes[1] ); 863 /* oops, can't happen */ 864 return -1; 865 } 866 } 867 868 /* now read from the gatherer */ 869 while( length ) { 870 int goodness; 871 ulong subtract; 872 873 if( read_a_msg( pipedes[0], &msg ) ) { 874 log_error("reading from gatherer pipe failed: %s\n", 875 strerror(errno)); 876 return -1; 877 } 878 879 880 if( level > 1 ) { 881 if( msg.usefulness > 30 ) 882 goodness = 100; 883 else if ( msg.usefulness ) 884 goodness = msg.usefulness * 100 / 30; 885 else 886 goodness = 0; 887 } 888 else if( level ) { 889 if( msg.usefulness > 15 ) 890 goodness = 100; 891 else if ( msg.usefulness ) 892 goodness = msg.usefulness * 100 / 15; 893 else 894 goodness = 0; 895 } 896 else 897 goodness = 100; /* goodness of level 0 is always 100 % */ 898 899 n = msg.ndata; 900 if( n > length ) 901 n = length; 902 (*add)( msg.data, n, origin ); 903 904 /* this is the trick how we cope with the goodness */ 905 subtract = (ulong)n * goodness / 100; 906 /* subtract at least 1 byte to avoid infinite loops */ 907 length -= subtract ? subtract : 1; 908 } 909 910 return 0; 911} 912