X-Git-Url: https://git.distorted.org.uk/~mdw/become/blobdiff_plain/c4f2d992e4a0fc068281376d89ec38de56dc2f58..c758e6541ca05409b178dd9629e9337494c49890:/src/keygen.c diff --git a/src/keygen.c b/src/keygen.c index 17bf93c..d9d6bde 100644 --- a/src/keygen.c +++ b/src/keygen.c @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: keygen.c,v 1.1 1997/07/21 13:47:48 mdw Exp $ + * $Id: keygen.c,v 1.5 1998/01/12 16:46:05 mdw Exp $ * * Key generation * - * (c) 1997 EBI + * (c) 1998 EBI */ -/*----- Licencing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of `become' * @@ -22,14 +22,28 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with `become'; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*----- Revision history --------------------------------------------------* * * $Log: keygen.c,v $ - * Revision 1.1 1997/07/21 13:47:48 mdw + * Revision 1.5 1998/01/12 16:46:05 mdw + * Fix copyright date. + * + * Revision 1.4 1997/12/08 15:29:27 mdw + * Major update: make random number sources configurable. Generate + * warnings if there isn't enough randomness available. + * + * Revision 1.3 1997/09/17 15:29:28 mdw + * Mix the noise from the key timings with some other environmental noise + * (obtained from `noise_acquire') for a little bit more randomness. + * + * Revision 1.2 1997/08/04 10:24:23 mdw + * Sources placed under CVS control. + * + * Revision 1.1 1997/07/21 13:47:48 mdw * Initial revision * */ @@ -57,8 +71,10 @@ /* --- Local headers --- */ #include "config.h" -#include "tx.h" #include "mdwopt.h" +#include "noise.h" +#include "rand.h" +#include "tx.h" #include "utils.h" /*----- Static variables --------------------------------------------------*/ @@ -245,9 +261,9 @@ static void kg__gen(unsigned char *ui, size_t sz) unsigned long fact = 1000000 / CLOCKS_PER_SEC; fprintf(kg__ttyfp, -"I need to get %i random bits; I'll do this by timing your keypresses.\n" +"I need to get %lu random bits; I'll do this by timing your keypresses.\n" "Please type some arbitrary text until I say `done'.\n", - sz); + (unsigned long)sz); { struct timeval tv; @@ -261,7 +277,7 @@ static void kg__gen(unsigned char *ui, size_t sz) /* --- Print current status --- */ - fprintf(kg__ttyfp, "\r%5i...", sz); + fprintf(kg__ttyfp, "\r%5lu...", (unsigned long)sz); fflush(kg__ttyfp); /* --- Read the next character --- */ @@ -425,9 +441,16 @@ int main(int argc, char *argv[]) { unsigned char *uip; size_t sz = 128; + size_t keybits = 0; + unsigned f = 0; const char *file = 0; FILE *fp; + enum { + f_envNoise = 1, + f_keyTimer = 2 + }; + /* --- Formats table --- */ static struct { @@ -447,33 +470,45 @@ int main(int argc, char *argv[]) ego(argv[0]); + f |= f_envNoise | f_keyTimer; + /* --- Read arguments --- */ for (;;) { static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "bits", gFlag_argReq, 0, 'b' }, - { "output", gFlag_argReq, 0, 'o' }, - { "format", gFlag_argReq, 0, 'f' }, - { 0, 0, 0, 0 } + { "help", 0, 0, 'h' }, + { "bits", gFlag_argReq, 0, 'b' }, + { "output", gFlag_argReq, 0, 'o' }, + { "format", gFlag_argReq, 0, 'f' }, + { "key-times", gFlag_negate|gFlag_argOpt, 0, 'k' }, + { "env-noise", gFlag_negate, 0, 'e' }, + { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "hb:o:f:", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "hb:o:f:k+::e+", opts, 0, 0, gFlag_negation); if (i < 0) break; switch (i) { case 'h': printf("" -"Usage: %s [--bits=BITS] [--output=FILE] [--format=FORMAT]\n" +"Usage: %s [-h] [-|+ek] [-b BITS] [-o FILE] [-f FORMAT]\n" "\n" -"Generates BITS (by default, 128) random bits by timing keypresses. The\n" -"resulting number is written to FILE, or standard output in the given\n" -"format. Formats currently supported are:\n" -"\n" -"tx, hex Hexadecimal, with punctuating dashes.\n" -"binary Raw binary.\n" -"base64 Base64-encoded binary; the result is printable ASCII.\n", +"Generates BITS (by default, 128) random bits. The resulting number is\n" +"written to FILE, or standard output.\n\n" +"Randomness is taken from key-timings and environmental noise, although\n" +"you can disable either (or both) of these sources.\n\n" +"Options provided are:\n\n" +"-h, --help Display this help text\n" +"-b, --bits=BITS\t Generate BITS random bits instead of 128\n" +"-o, --output=FILE Write bits to FILE, not standard output\n" +"-f, --format=FORMAT Write bits in FORMAT:\n" +" tx, hex Hexadecimal\n" +" binary Raw binary\n" +" base64 Base64-encoded binary\n" +"-e, --[no-]env-noise Do [not] read environmental noise\n" +"-k, --[no-]key-times[=BITS] Do [not] read key timing information\n" +" (only read BITS bits from key timings)\n", quis()); exit(0); break; @@ -507,29 +542,107 @@ int main(int argc, char *argv[]) if (!fmt) die("unknown format name: `%s'", optarg); break; + case 'e': + f |= f_envNoise; + break; + case 'e' | gFlag_negated: + f &= ~f_envNoise; + break; + case 'k': + f |= f_keyTimer; + if (optarg) { + keybits = atoi(optarg); + if (keybits == 0) + die("bad number of bits (illegible or zero)"); + if (keybits % 8) + die("bad number of bits (must be multiple of 8)"); + } + else + keybits = 0; + break; + case 'k' | gFlag_negated: + f &= ~f_keyTimer; + break; case '?': exit(1); break; } } + /* --- Check the sanity of this request --- */ + + { + size_t bits = 0; + + if (f & f_keyTimer) { + if (!keybits) + keybits = sz; + bits += keybits; + } + if (f & f_envNoise) + bits += 384; /* Estimate */ + + if (bits == 0) + die("no randomness sources given"); + if (bits < sz) + moan("warning: randomness may not be sufficiently high"); + } + if (optind < argc) { - fprintf(stderr, "Usage: %s [--bits=BITS] [--output=FILE]\n", quis()); + fprintf(stderr, "Usage: %s [-opts]\n", quis()); exit(1); } /* --- Allocate memory --- */ - uip = xmalloc(sz / 8); + { + size_t buff = sz / 8; + if (f & f_keyTimer && keybits > sz) + buff = keybits / 8; + uip = xmalloc(buff); + } + + rand_clear(); - /* --- Open the terminal --- * - * - * I'd like to be able to @fprintf@ to the terminal, so use @fopen@. - */ + /* --- Fetch randomness from key timings --- */ - if ((kg__ttyfp = fopen("/dev/tty", "r+")) == 0) - die("couldn't open terminal: %s", strerror(errno)); - kg__tty = fileno(kg__ttyfp); + if (f & f_keyTimer) { + + /* --- Open the terminal --- * + * + * I'd like to be able to @fprintf@ to the terminal, so use @fopen@. + */ + + if ((kg__ttyfp = fopen("/dev/tty", "r+")) == 0) + die("couldn't open terminal: %s", strerror(errno)); + kg__tty = fileno(kg__ttyfp); + + /* --- Tidy up nicely if I die --- */ + + signal(SIGINT, kg__signal); + signal(SIGTERM, kg__signal); + atexit(kg__crepair); + + /* --- Put the terminal into cbreak, read the key, and restore --- */ + + kg__cbreak(); + kg__gen(uip, keybits); + kg__crepair(); + rand_add(uip, keybits / 8); + rand_churn(); + } + + /* --- Find some noise from the environment too --- */ + + if (f & f_envNoise) { + noise_acquire(); + rand_churn(); + } + + /* --- Now write the number and exit --- */ + + rand_extract(uip, sz / 8); + D( fputs("*** ", fp); tx_putBits(uip, sz, stdout); ) /* --- Open the output file, if one is specified --- */ @@ -541,8 +654,8 @@ int main(int argc, char *argv[]) * There's a good reason for this. I want to be able to @fprintf@ (for * the benefit of @tx_putWords@ mainly) but I also want to ensure that * only the user has read permissions for the file. So I'll use @open@ - * with an appropriate mode and then @fdopen@ the file descriptor to get - * a stream. Yuk. + * with an appropriate mode and then @fdopen@ the file descriptor to + * get a stream. Yuk. */ if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) @@ -552,25 +665,11 @@ int main(int argc, char *argv[]) } else fp = stdout; - /* --- Tidy up nicely if I die --- */ - - signal(SIGINT, kg__signal); - signal(SIGTERM, kg__signal); - atexit(kg__crepair); - - /* --- Put the terminal into cbreak, read the key, and restore --- */ - - kg__cbreak(); - kg__gen(uip, sz); - kg__crepair(); - - /* --- Now write the number and exit --- */ - - D( fputs("*** ", fp); tx_putBits(uip, sz, stdout); ) fmt(uip, sz, fp); if (file) fclose(fp); memset(uip, 0, sz / 8); /* Burn temporary buffer */ + rand_clear(); return (0); }