X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/099355bc239ba5c0c066be2924fbf0930744ee2f..025c5f4aa5ffbf8948482a4233318db81c2df5d2:/noise.c diff --git a/noise.c b/noise.c index ed2d83c..9088930 100644 --- a/noise.c +++ b/noise.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: noise.c,v 1.5 1999/12/22 15:57:55 mdw Exp $ + * $Id$ * * Acquisition of environmental noise (Unix-specific) * @@ -27,30 +27,11 @@ * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: noise.c,v $ - * Revision 1.5 1999/12/22 15:57:55 mdw - * Label system-specific parts more clearly. - * - * Revision 1.4 1999/12/10 23:25:15 mdw - * Bug fix: remove old spurious fflush. - * - * Revision 1.3 1999/12/10 23:24:11 mdw - * Bug fix: flush buffers before forking. - * - * Revision 1.2 1999/11/11 00:59:08 mdw - * A bit of reformatting. Initialize the uid and gid correctly. - * - * Revision 1.1 1999/09/03 08:41:12 mdw - * Initial import. - * - */ - /*----- Header files ------------------------------------------------------*/ #include "config.h" +#include #include #include #include @@ -80,7 +61,7 @@ /*----- Noise source definition -------------------------------------------*/ -rand_source noise_source = { noise_acquire, noise_timer }; +const rand_source noise_source = { noise_acquire, noise_timer }; /*----- Static variables --------------------------------------------------*/ @@ -120,7 +101,7 @@ static int bitcount(unsigned long x) * Arguments: @rand_pool *r@ = pointer to randomness pool * @struct timeval *tv@ = pointer to time block * - * Returns: Nonzer if some randomness was contributed. + * Returns: Nonzero if some randomness was contributed. * * Use: Low-level timer contributor. */ @@ -187,7 +168,9 @@ int noise_devrandom(rand_pool *r) * needs to get some more entropy from somewhere. */ - if ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) >= 0) { + if ((fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK)) >= 0 || + (fd = open("/dev/arandom", O_RDONLY | O_NONBLOCK)) >= 0 || + (fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) >= 0) { if ((len = read(fd, buf, sizeof(buf))) > 0) { rand_add(r, buf, len, len * 8); BURN(buf); @@ -364,6 +347,95 @@ int noise_filter(rand_pool *r, int good, const char *c) return (ret); } +/* --- @noise_freewheel@ --- * + * + * Arguments: @rand_pool *r@ = pointer to a randomness pool + * + * Returns: Nonzero if some randomness was contributed. + * + * Use: Runs a free counter for a short while as a desparate attempt + * to get randomness from somewhere. This is actually quite + * effective. + */ + +#ifdef USE_FREEWHEEL + +static jmp_buf fwjmp; + +static void fwalarm(int sig) +{ + siglongjmp(fwjmp, 1); +} + +int noise_freewheel(rand_pool *r) +{ + void (*sigal)(int) = 0; + struct itimerval oitv, itv = { { 0, 0 }, { 0, 5000 } }; + int rc = 0; + volatile uint32 fwcount = 0; + + if (!sigsetjmp(fwjmp, 1)) { + if ((sigal = signal(SIGALRM, fwalarm)) == SIG_ERR) + return (0); + if (setitimer(ITIMER_REAL, &itv, &oitv)) + goto done; + for (;;) + fwcount++; + } else { + octet buf[4]; + STORE32(buf, fwcount); + rand_add(r, buf, sizeof(buf), 16); + rc = 1; + } + +done: + signal(SIGALRM, sigal); + TV_SUB(&oitv.it_value, &oitv.it_value, &itv.it_value); + setitimer(ITIMER_REAL, &oitv, 0); + return (rc); +} + +#else + +int noise_freewheel(rand_pool *r) +{ + return (0); +} + +#endif + +/* --- @noise_enquire@ --- * + * + * Arguments: @rand_pool *r@ = pointer to a randomness pool + * + * Returns: Nonzero if some randomness was contributed. + * + * Use: Runs some shell commands to enquire about the prevailing + * environment. This can gather quite a lot of low-quality + * entropy. + */ + +int noise_enquire(rand_pool *r) +{ + struct tab { + const char *cmd; + unsigned rate; + } tab[] = { + { "ps alxww || ps -elf", 16 }, + { "netstat -n", 6 }, + { "ifconfig -a", 8 }, + { "df", 20 }, + { "w", 6 }, + { "ls -align /tmp/.", 10 }, + { 0, 0 } + }; + int i; + + for (i = 0; tab[i].cmd; i++) + noise_filter(r, tab[i].rate, tab[i].cmd); + return (1); +} + /* --- @noise_acquire@ --- * * * Arguments: @rand_pool *r@ = pointer to a randomness pool @@ -375,33 +447,13 @@ int noise_filter(rand_pool *r, int good, const char *c) void noise_acquire(rand_pool *r) { + unsigned i; + for (i = 0; i < 8; i++) + noise_freewheel(r); if (!noise_devrandom(r)) { - - /* --- Output of `ps' --- * - * - * This is a hopefully cheap way of getting a bit of noise. I'm guessing - * the good bit ratio based on about 90 bytes per line of output, and - * each line containing maybe 12 bits worth of interesting data. (Some - * quick experiments with gzip seem to bear this idea out.) So, 12 good - * bits per 90 bytes of output gives slightly more than 17 good bits per - * 1024 bits of output. So I'll be a pessimist and say 16 bits. - */ - - (void) - (noise_filter(r, 16, "ps alxww") || - noise_filter(r, 16, "ps -elf")); - - /* --- Output of `netstat' --- * - * - * Another possibly cheap way of getting noise. My output has about - * 72 bytes per line of output. My wild guesses are telling me that - * there are probably only about four good bits per line (gzip tells - * me there's six, but I want to underestimate). Four bits per 72 bytes - * is 7 good bits per 1024 bits of output. Pessimist that I am, I'll - * call it six. - */ - - noise_filter(r, 6, "netstat -n"); + noise_enquire(r); + for (i = 0; i < 8; i++) + noise_freewheel(r); } }