summaryrefslogtreecommitdiff
path: root/entropy.c
diff options
context:
space:
mode:
Diffstat (limited to 'entropy.c')
-rw-r--r--entropy.c207
1 files changed, 140 insertions, 67 deletions
diff --git a/entropy.c b/entropy.c
index 2766d90b6..9782e0f32 100644
--- a/entropy.c
+++ b/entropy.c
@@ -35,7 +35,7 @@
35#include <openssl/rand.h> 35#include <openssl/rand.h>
36#include <openssl/sha.h> 36#include <openssl/sha.h>
37 37
38RCSID("$Id: entropy.c,v 1.7 2000/05/01 14:03:56 damien Exp $"); 38RCSID("$Id: entropy.c,v 1.8 2000/05/01 23:56:41 damien Exp $");
39 39
40#ifdef EGD_SOCKET 40#ifdef EGD_SOCKET
41#ifndef offsetof 41#ifndef offsetof
@@ -111,8 +111,6 @@ void get_random_bytes(unsigned char *buf, int len)
111 * FIXME: proper entropy estimations. All current values are guesses 111 * FIXME: proper entropy estimations. All current values are guesses
112 * FIXME: (ATL) do estimates at compile time? 112 * FIXME: (ATL) do estimates at compile time?
113 * FIXME: More entropy sources 113 * FIXME: More entropy sources
114 * FIXME: (ATL) bring in entropy sources from file
115 * FIXME: (ATL) add heuristic to increase the timeout if needed
116 */ 114 */
117 115
118/* slow command timeouts (all in milliseconds) */ 116/* slow command timeouts (all in milliseconds) */
@@ -120,7 +118,8 @@ void get_random_bytes(unsigned char *buf, int len)
120static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC; 118static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC;
121 119
122static int prng_seed_loaded = 0; 120static int prng_seed_loaded = 0;
123static int prng_seed_saved = 0; 121static int prng_seed_saved = 0;
122static int prng_commands_loaded = 0;
124 123
125typedef struct 124typedef struct
126{ 125{
@@ -131,9 +130,9 @@ typedef struct
131 /* Increases by factor of two each timeout */ 130 /* Increases by factor of two each timeout */
132 unsigned int sticky_badness; 131 unsigned int sticky_badness;
133 /* Path to executable */ 132 /* Path to executable */
134 const char *path; 133 char *path;
135 /* argv to pass to executable */ 134 /* argv to pass to executable */
136 const char *args[5]; 135 char *args[5];
137} entropy_source_t; 136} entropy_source_t;
138 137
139double stir_from_system(void); 138double stir_from_system(void);
@@ -143,67 +142,10 @@ double stir_clock(double entropy_estimate);
143double stir_rusage(int who, double entropy_estimate); 142double stir_rusage(int who, double entropy_estimate);
144double hash_output_from_command(entropy_source_t *src, char *hash); 143double hash_output_from_command(entropy_source_t *src, char *hash);
145 144
146entropy_source_t entropy_sources[] = { 145/* this is initialised from a file, by prng_read_commands() */
147#ifdef PROG_LS 146entropy_source_t *entropy_sources = NULL;
148 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/var/log", NULL } }, 147#define MIN_ENTROPY_SOURCES 16
149 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/var/adm", NULL } }, 148
150 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/var/mail", NULL } },
151 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/var/spool/mail", NULL } },
152 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/proc", NULL } },
153 { 0.002, 0, 1, PROG_LS, { "ls", "-alni", "/tmp", NULL } },
154#endif
155#ifdef PROG_NETSTAT
156 { 0.005, 0, 1, PROG_NETSTAT, { "netstat","-an", NULL, NULL } },
157 { 0.010, 0, 1, PROG_NETSTAT, { "netstat","-in", NULL, NULL } },
158 { 0.002, 0, 1, PROG_NETSTAT, { "netstat","-rn", NULL, NULL } },
159 { 0.002, 0, 1, PROG_NETSTAT, { "netstat","-s", NULL, NULL } },
160#endif
161#ifdef PROG_ARP
162 { 0.002, 0, 1, PROG_ARP, { "arp","-a","-n", NULL } },
163#endif
164#ifdef PROG_IFCONFIG
165 { 0.002, 0, 1, PROG_IFCONFIG, { "ifconfig", "-a", NULL, NULL } },
166#endif
167#ifdef PROG_PS
168 { 0.003, 0, 1, PROG_PS, { "ps", "laxww", NULL, NULL } },
169 { 0.003, 0, 1, PROG_PS, { "ps", "-al", NULL, NULL } },
170 { 0.003, 0, 1, PROG_PS, { "ps", "-efl", NULL, NULL } },
171#endif
172#ifdef PROG_W
173 { 0.005, 0, 1, PROG_W, { "w", NULL, NULL, NULL } },
174#endif
175#ifdef PROG_WHO
176 { 0.001, 0, 1, PROG_WHO, { "who","-i", NULL, NULL } },
177#endif
178#ifdef PROG_LAST
179 { 0.001, 0, 1, PROG_LAST, { "last", NULL, NULL, NULL } },
180#endif
181#ifdef PROG_LASTLOG
182 { 0.001, 0, 1, PROG_LASTLOG, { "lastlog", NULL, NULL, NULL } },
183#endif
184#ifdef PROG_DF
185 { 0.010, 0, 1, PROG_DF, { "df", NULL, NULL, NULL } },
186 { 0.010, 0, 1, PROG_DF, { "df", "-i", NULL, NULL } },
187#endif
188#ifdef PROG_VMSTAT
189 { 0.010, 0, 1, PROG_VMSTAT, { "vmstat", NULL, NULL, NULL } },
190#endif
191#ifdef PROG_UPTIME
192 { 0.001, 0, 1, PROG_UPTIME, { "uptime", NULL, NULL, NULL } },
193#endif
194#ifdef PROG_IPCS
195 { 0.001, 0, 1, PROG_IPCS, { "-a", NULL, NULL, NULL } },
196#endif
197#ifdef PROG_TAIL
198 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/log/messages", NULL, NULL } },
199 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/log/syslog", NULL, NULL } },
200 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/adm/messages", NULL, NULL } },
201 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/adm/syslog", NULL, NULL } },
202 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/log/maillog", NULL, NULL } },
203 { 0.001, 0, 1, PROG_TAIL, { "tail", "-200", "/var/adm/maillog", NULL, NULL } },
204#endif
205 { 0.000, 0, 0, NULL, { NULL, NULL, NULL, NULL, NULL } },
206};
207 149
208double 150double
209stir_from_system(void) 151stir_from_system(void)
@@ -597,6 +539,131 @@ prng_read_seedfile(void) {
597 RAND_add(&seed, sizeof(seed), 0.0); 539 RAND_add(&seed, sizeof(seed), 0.0);
598} 540}
599 541
542
543/*
544 * entropy command initialisation functions
545 */
546#define WHITESPACE " \t\n"
547
548int
549prng_read_commands(char *cmdfilename)
550{
551 FILE *f;
552 char line[1024];
553 char cmd[1024], path[256];
554 double est;
555 char *cp;
556 int linenum;
557 entropy_source_t *entcmd;
558 int num_cmds = 64;
559 int cur_cmd = 0;
560
561 f = fopen(cmdfilename, "r");
562 if (!f) {
563 fatal("couldn't read entropy commands file %.100s: %.100s",
564 cmdfilename, strerror(errno));
565 }
566
567 linenum = 0;
568
569 entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t));
570 memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t));
571
572 while (fgets(line, sizeof(line), f)) {
573 linenum++;
574
575 /* skip leading whitespace, test for blank line or comment */
576 cp = line + strspn(line, WHITESPACE);
577 if ((*cp == 0) || (*cp == '#'))
578 continue; /* done with this line */
579
580 switch (*cp) {
581 int arg;
582 char *argv;
583
584 case '"':
585 /* first token, command args (incl. argv[0]) in double quotes */
586 cp = strtok(cp, "\"");
587 if (cp==NULL) {
588 error("missing or bad command string, %.100s line %d -- ignored",
589 cmdfilename, linenum);
590 continue;
591 }
592 strncpy(cmd, cp, sizeof(cmd));
593 /* second token, full command path */
594 if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
595 error("missing command path, %.100s line %d -- ignored",
596 cmdfilename, linenum);
597 continue;
598 }
599 if (strncmp("undef", cp, 5)==0) /* did configure mark this as dead? */
600 continue;
601
602 strncpy(path, cp, sizeof(path));
603 /* third token, entropy rate estimate for this command */
604 if ( (cp = strtok(NULL, WHITESPACE)) == NULL) {
605 error("missing entropy estimate, %.100s line %d -- ignored",
606 cmdfilename, linenum);
607 continue;
608 }
609 est = strtod(cp, &argv);/* FIXME: (ATL) no error checking here */
610
611 /* end of line */
612 if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
613 error("garbage at end of line %d in %.100s -- ignored",
614 linenum, cmdfilename);
615 continue;
616 }
617
618 /* split the command args */
619 cp = strtok(cmd, WHITESPACE);
620 arg = 0; argv = NULL;
621 do {
622 char *s = (char*)xmalloc(strlen(cp)+1);
623 strncpy(s, cp, strlen(cp)+1);
624 entcmd[cur_cmd].args[arg] = s;
625 arg++;
626 } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE)));
627 if (strtok(NULL, WHITESPACE))
628 error("ignored extra command elements (max 5), %.100s line %d",
629 cmdfilename, linenum);
630
631 /* copy the command path and rate estimate */
632 entcmd[cur_cmd].path = (char *)xmalloc(strlen(path)+1);
633 strncpy(entcmd[cur_cmd].path, path, strlen(path)+1);
634 entcmd[cur_cmd].rate = est;
635 /* initialise other values */
636 entcmd[cur_cmd].sticky_badness = 1;
637
638 cur_cmd++;
639
640 /* If we've filled the array, reallocate it twice the size */
641 /* Do this now because even if this we're on the last command,
642 we need another slot to mark the last entry */
643 if (cur_cmd == num_cmds) {
644 num_cmds *= 2;
645 entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t));
646 }
647 break;
648
649 default:
650 error("bad entropy command, %.100s line %d", cmdfilename,
651 linenum);
652 continue;
653 }
654 }
655
656 /* zero the last entry */
657 memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t));
658 /* trim to size */
659 entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t));
660
661 debug("loaded %d entropy commands from %.100s", cur_cmd, cmdfilename);
662
663 return (cur_cmd >= MIN_ENTROPY_SOURCES);
664}
665
666
600#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ 667#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */
601 668
602#if defined(EGD_SOCKET) || defined(RANDOM_POOL) 669#if defined(EGD_SOCKET) || defined(RANDOM_POOL)
@@ -634,6 +701,12 @@ prng_seed_cleanup(void *junk)
634void 701void
635seed_rng(void) 702seed_rng(void)
636{ 703{
704 if (!prng_commands_loaded) {
705 if (!prng_read_commands(SSH_PRNG_COMMAND_FILE))
706 fatal("PRNG initialisation failed -- exiting.");
707 prng_commands_loaded = 1;
708 }
709
637 debug("Seeding random number generator."); 710 debug("Seeding random number generator.");
638 debug("OpenSSL random status is now %i\n", RAND_status()); 711 debug("OpenSSL random status is now %i\n", RAND_status());
639 debug("%i bytes from system calls", (int)stir_from_system()); 712 debug("%i bytes from system calls", (int)stir_from_system());