chiark / gitweb /
New Rijndael block sizes.
[catacomb] / rspit.c
1 /* -*-c-*-
2  *
3  * $Id: rspit.c,v 1.17 2001/05/07 17:33:19 mdw Exp $
4  *
5  * Spit out random numbers
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: rspit.c,v $
33  * Revision 1.17  2001/05/07 17:33:19  mdw
34  * New Rijndael block sizes.
35  *
36  * Revision 1.16  2001/04/29 18:11:32  mdw
37  * New block ciphers.
38  *
39  * Revision 1.15  2001/04/19 18:26:13  mdw
40  * Use the new MAC keysize names.
41  *
42  * Revision 1.14  2001/02/21 20:03:22  mdw
43  * Added support for MD2 hash function.
44  *
45  * Revision 1.13  2000/12/06 20:33:27  mdw
46  * Make flags be macros rather than enumerations, to ensure that they're
47  * unsigned.
48  *
49  * Revision 1.12  2000/10/08 15:49:18  mdw
50  * Remove failed kludge for shutting up a warning.
51  *
52  * Revision 1.11  2000/10/08 12:10:32  mdw
53  * Make table have external linkage to bodge around deficiency in C.  The
54  * problem is that @static gen generators[];@ is considered to be a
55  * `tentative definition', and therefore mustn't have incomplete type,
56  * which it obviously has.
57  *
58  * Revision 1.10  2000/08/11 21:34:59  mdw
59  * New restartable interface to Maurer testing.
60  *
61  * Revision 1.9  2000/08/04 23:24:15  mdw
62  * Add a timer and a discard option.
63  *
64  * Revision 1.8  2000/07/29 22:05:47  mdw
65  * Fix error in help message about Maurer test syntax.
66  *
67  * Revision 1.7  2000/07/18 23:01:26  mdw
68  * Improve progress indications, and allow user to choose chunk sizes for
69  * Maurer's test.
70  *
71  * Revision 1.6  2000/07/15 20:53:35  mdw
72  * Add a load of new ciphers and hashes.
73  *
74  * Revision 1.5  2000/07/01 11:27:03  mdw
75  * Portability fix: don't assume that `stdout' is a constant expression.
76  * Remove old type name `bbs_param'.
77  *
78  * Revision 1.4  2000/06/17 12:08:28  mdw
79  * Restructure handling of cipher-based generators.  Add counter-mode
80  * ciphers and MGF-1 hash functions.  Add FIPS 140-1 and Maurer's tests.
81  *
82  * Revision 1.3  2000/02/12 18:21:03  mdw
83  * Overhaul of key management (again).
84  *
85  * Revision 1.2  1999/12/22 15:59:51  mdw
86  * New prime-search system.  Read BBS keys from key files.
87  *
88  * Revision 1.1  1999/12/10 23:29:13  mdw
89  * Emit random numbers for statistical tests.
90  *
91  */
92
93 /*----- Header files ------------------------------------------------------*/
94
95 #include "config.h"
96
97 #include <assert.h>
98 #include <errno.h>
99 #include <math.h>
100 #include <signal.h>
101 #include <stdio.h>
102 #include <stdlib.h>
103 #include <string.h>
104 #include <time.h>
105
106 #ifndef PORTABLE
107 #  include <unistd.h>
108 #endif
109
110 #include <mLib/darray.h>
111 #include <mLib/dstr.h>
112 #include <mLib/mdwopt.h>
113 #include <mLib/quis.h>
114 #include <mLib/report.h>
115 #include <mLib/sub.h>
116
117 #include "fipstest.h"
118 #include "grand.h"
119 #include "maurer.h"
120 #include "key.h"
121
122 #include "lcrand.h"
123 #include "fibrand.h"
124 #include "rand.h"
125 #include "noise.h"
126
127 #include "bbs.h"
128 #include "mprand.h"
129
130 #include "rc4.h"
131 #include "seal.h"
132
133 #include "des-ofb.h"
134 #include "des3-ofb.h"
135 #include "rc2-ofb.h"
136 #include "rc5-ofb.h"
137 #include "mars-ofb.h"
138 #include "skipjack-ofb.h"
139 #include "tea-ofb.h"
140 #include "xtea-ofb.h"
141 #include "blowfish-ofb.h"
142 #include "twofish-ofb.h"
143 #include "idea-ofb.h"
144 #include "cast128-ofb.h"
145 #include "cast256-ofb.h"
146 #include "rijndael-ofb.h"
147 #include "rijndael192-ofb.h"
148 #include "rijndael256-ofb.h"
149 #include "safer-ofb.h"
150 #include "safersk-ofb.h"
151 #include "square-ofb.h"
152 #include "serpent-ofb.h"
153
154 #include "des-counter.h"
155 #include "des3-counter.h"
156 #include "rc2-counter.h"
157 #include "rc5-counter.h"
158 #include "mars-counter.h"
159 #include "skipjack-counter.h"
160 #include "tea-counter.h"
161 #include "xtea-counter.h"
162 #include "blowfish-counter.h"
163 #include "twofish-counter.h"
164 #include "idea-counter.h"
165 #include "cast128-counter.h"
166 #include "cast256-counter.h"
167 #include "rijndael-counter.h"
168 #include "rijndael192-counter.h"
169 #include "rijndael256-counter.h"
170 #include "safer-counter.h"
171 #include "safersk-counter.h"
172 #include "square-counter.h"
173 #include "serpent-counter.h"
174
175 #include "md2-mgf.h"
176 #include "md4-mgf.h"
177 #include "md5-mgf.h"
178 #include "sha-mgf.h"
179 #include "tiger-mgf.h"
180 #include "rmd128-mgf.h"
181 #include "rmd160-mgf.h"
182 #include "rmd256-mgf.h"
183 #include "rmd320-mgf.h"
184
185 #include "rmd160.h"
186
187 /*----- Data structures ---------------------------------------------------*/
188
189 typedef struct gen {
190   const char *name;
191   grand *(*seed)(unsigned /*i*/);
192   unsigned i;
193   const char *help;
194 } gen;
195
196 extern gen generators[];
197
198 #define CIPHERS                                                         \
199   E(DES, des)                                                           \
200   E(DES3, des3)                                                         \
201   E(RC2, rc2)                                                           \
202   E(RC5, rc5)                                                           \
203   E(MARS, mars)                                                         \
204   E(SKIPJACK, skipjack)                                                 \
205   E(TEA, tea)                                                           \
206   E(XTEA, xtea)                                                         \
207   E(BLOWFISH, blowfish)                                                 \
208   E(TWOFISH, twofish)                                                   \
209   E(IDEA, idea)                                                         \
210   E(CAST128, cast128)                                                   \
211   E(CAST256, cast256)                                                   \
212   E(SQUARE, square)                                                     \
213   E(SAFER, safer)                                                       \
214   E(SAFERSK, safersk)                                                   \
215   E(RIJNDAEL, rijndael)                                                 \
216   E(RIJNDAEL192, rijndael192)                                           \
217   E(RIJNDAEL256, rijndael256)                                           \
218   E(SERPENT, serpent)
219
220 #define HASHES                                                          \
221   E(MD2, md2)                                                           \
222   E(MD4, md4)                                                           \
223   E(MD5, md5)                                                           \
224   E(SHA, sha)                                                           \
225   E(TIGER, tiger)                                                       \
226   E(RMD128, rmd128)                                                     \
227   E(RMD160, rmd160)                                                     \
228   E(RMD256, rmd256)                                                     \
229   E(RMD320, rmd320)
230
231 #define E(PRE, pre) CIPHER_##PRE,
232 enum { CIPHERS CIPHER__bogus };
233 #undef E
234
235 #define E(PRE, pre) HASH_##PRE,
236 enum { HASHES HASH__bogus };
237 #undef E
238
239 static struct {
240   const octet *keysz;
241   size_t blksz;
242   grand *(*ofb)(const void */*k*/, size_t /*sz*/);
243   grand *(*counter)(const void */*k*/, size_t /*sz*/);
244 } ciphertab[] = {
245 #define E(PRE, pre)                                                     \
246   { pre##_keysz, PRE##_BLKSZ, pre##_ofbrand, pre##_counterrand },
247   CIPHERS
248 #undef E
249 };
250
251 static struct {
252   const gchash *h;
253   const octet *keysz;
254   grand *(*mgf)(const void */*k*/, size_t /*sz*/);
255 } hashtab[] = {
256 #define E(PRE, pre)                                                     \
257   { &pre, pre##_mgfkeysz, pre##_mgfrand },
258   HASHES
259 #undef E
260 };
261
262 /*----- Miscellaneous static data -----------------------------------------*/
263
264 static FILE *outfp;
265 static size_t outsz = 0;
266 static unsigned maurer_lo = 5, maurer_hi = 8;
267
268 static int argc;
269 static char **argv;
270
271 static unsigned flags = 0;
272
273 #define f_progress 1u
274 #define f_file 2u
275 #define f_fips 4u
276 #define f_maurer 8u
277 #define f_timer 16u
278 #define f_discard 32u
279
280 /*----- Help options ------------------------------------------------------*/
281
282 static void usage(FILE *fp)
283 {
284   pquis(fp, "Usage: $ generator [options]\n");
285 }
286
287 static void version(FILE *fp)
288 {
289   pquis(fp, "$, Catacomb version " VERSION "\n");
290 }
291
292 static void help(FILE *fp)
293 {
294   version(fp);
295   fputc('\n', fp);
296   usage(fp);
297   pquis(fp, "\n\
298 Emits a stream of random bytes suitable for, well, all sorts of things.\n\
299 The primary objective is to be able to generate streams of input for\n\
300 statistical tests, such as Diehard.\n\
301 \n\
302 Options are specific to the particular generator, although there's a\n\
303 common core set:\n\
304 \n\
305 -h, --help              Display this help message.\n\
306 -v, --version           Display the program's version number.\n\
307 -u, --usage             Display a useless usage message.\n\
308 \n\
309 -l, --list              Show a list of the supported generators, with\n\
310                         their options.\n\
311 -f, --fipstest          Run the FIPS 140-1 randomness test.\n\
312 -m, --maurer[=LO-HI]    Run Maurer's universal statistical test.\n\
313 -o, --output FILE       Write output to FILE, not stdout.\n\
314 -z, --size SIZE         Emit SIZE bytes, not an unlimited number.\n\
315 -p, --progress          Show a little progress meter (on stderr).\n\
316 -T, --timer             Keep track of the CPU time used by the generator.\n\
317 -d, --discard           Discard the generated output.\n\
318 \n\
319 (A SIZE may be followed by `g' for gigabytes, `m' for megabytes, or\n\
320 `k' for kilobytes.  If unqualified, an amount in bytes is assumed.)\n\
321 ");
322 }
323
324 /*----- Main options parser -----------------------------------------------*/
325
326 static struct option opts[] = {
327
328   /* --- Standard GNU help options --- */
329
330   { "help",     0,              0,      'h' },
331   { "version",  0,              0,      'v' },
332   { "usage",    0,              0,      'u' },
333
334   /* --- Other useful things --- */
335
336   { "list",     0,              0,      'l' },
337   { "fipstest", 0,              0,      'f' },
338   { "maurer",   OPTF_ARGOPT,    0,      'm' },
339   { "output",   OPTF_ARGREQ,    0,      'o' },
340   { "size",     OPTF_ARGREQ,    0,      'z' },
341   { "progress", 0,              0,      'p' },
342   { "timer",    0,              0,      'T' },
343   { "discard",  0,              0,      'd' },
344
345   /* --- End of main table --- */
346
347   { 0,          0,              0,      0 }
348 };
349
350 static const char *sopts = "hvu lfm::o:z:pTd";
351
352 #ifndef OPTION_V
353    DA_DECL(option_v, struct option);
354 #  define OPTION_V
355 #endif
356
357 static option_v optv = DA_INIT;
358 static dstr optd = DSTR_INIT;
359
360 /* --- @addopts@ --- *
361  *
362  * Arguments:   @const char *s@ = pointer to short options
363  *              @struct option *l@ = pointer to long options
364  *
365  * Returns:     ---
366  *
367  * Use:         Adds a collection of options to the table.
368  */
369
370 static void addopts(const char *s, struct option *l)
371 {
372   dstr_puts(&optd, s);
373   if (DA_LEN(&optv))
374     DA_SHRINK(&optv, 1);
375   while (l->name)
376     DA_PUSH(&optv, *l++);
377   DA_PUSH(&optv, *l);
378 }
379
380 /* --- @opt@ --- *
381  *
382  * Arguments:   ---
383  *
384  * Returns:     Next option from argument array.
385  *
386  * Use:         Fetches options, handling the standard ones.
387  */
388
389 static int opt(void)
390 {
391   for (;;) {
392     int i = mdwopt(argc, argv, optd.buf, DA(&optv), 0, 0, 0);
393     switch (i) {
394       case 'h':
395         help(stdout);
396         exit(0);
397       case 'v':
398         version(stdout);
399         exit(0);
400       case 'u':
401         usage(stdout);
402         exit(0);
403       case 'l': {
404         gen *g;
405         puts("Generators supported:");
406         for (g = generators; g->name; g++)
407           printf("  %s %s\n", g->name, g->help);
408         exit(0);
409       } break;
410       case 'f':
411         flags |= f_fips;
412         break;
413       case 'm':
414         flags |= f_maurer;
415         if (optarg) {
416           char *p;
417           unsigned long lo, hi;
418           lo = strtoul(optarg, &p, 0);
419           if (*p == '-' || *p == ',')
420             hi = strtoul(p + 1, &p, 0);
421           else
422             hi = lo;
423           if (*p != 0 || hi < lo || lo == 0)
424             die(EXIT_FAILURE, "bad bit range `%s'", optarg);
425           maurer_lo = lo;
426           maurer_hi = hi;
427         }
428         break;
429       case 'o':
430         if (flags & f_file)
431           die(EXIT_FAILURE, "already set an output file");
432         if (strcmp(optarg, "-") == 0)
433           outfp = stdout;
434         else {
435           outfp = fopen(optarg, "w");
436           if (!outfp) {
437             die(EXIT_FAILURE, "couldn't open output file `%s': %s",
438                 optarg, strerror(errno));
439           }
440         }
441         flags |= f_file;
442         break;
443       case 'z': {
444         char *p;
445         outsz = strtoul(optarg, &p, 0);
446         if (!outsz)
447           die(EXIT_FAILURE, "bad number `%s'", optarg);
448         switch (*p) {
449           case 'G': case 'g': outsz *= 1024;
450           case 'M': case 'm': outsz *= 1024;
451           case 'K': case 'k': outsz *= 1024;
452           case 0:
453             break;
454           default:
455             die(EXIT_FAILURE, "bad suffix `%s'", p);
456             break;
457         }
458         if (*p && p[1] != 0)
459           die(EXIT_FAILURE, "bad suffix `%s'", p);
460       } break;
461       case 'p':
462         flags |= f_progress;
463         break;
464       case 'T':
465         flags |= f_timer;
466         break;
467       case 'd':
468         flags |= f_discard;
469         break;
470       default:
471         return (i);
472     }
473   }
474 }
475
476 /*----- Manglers for seed strings -----------------------------------------*/
477
478 /* --- @unhex@ --- *
479  *
480  * Arguments:   @const char *p@ = pointer to input string
481  *              @char **end@ = where the end goes
482  *              @dstr *d@ = output buffer
483  *
484  * Returns:     ---
485  *
486  * Use:         Transforms a hex string into a chunk of binary data.
487  */
488
489 static void unhex(const char *p, char **end, dstr *d)
490 {
491   while (p[0] && p[1]) {
492     int x = p[0], y = p[1];
493     if ('0' <= x && x <= '9') x -= '0';
494     else if ('A' <= x && x <= 'F') x -= 'A' - 10;
495     else if ('a' <= x && x <= 'f') x -= 'a' - 10;
496     else x = 0;
497     if ('0' <= y && y <= '9') y -= '0';
498     else if ('A' <= y && y <= 'F') y -= 'A' - 10;
499     else if ('a' <= y && y <= 'f') y -= 'a' - 10;
500     else y = 0;
501     DPUTC(d, (x << 4) + y);
502     p += 2;
503   }
504   *end = (char *)p;
505 }
506
507 /* --- Generate a key --- */
508
509 static void textkey(dstr *d, const char *p, const octet *ksz)
510 {
511   size_t sz = strlen(p);
512
513   if (!sz)
514     die(EXIT_FAILURE, "zero-length key string");
515   if (keysz(sz, ksz) != sz)
516     DPUTM(d, p, sz);
517   else {
518     rmd160_mgfctx g;
519     rmd160_mgfinit(&g, p, sz);
520     sz = keysz(0, ksz);
521     dstr_ensure(d, sz);
522     rmd160_mgfencrypt(&g, 0, d->buf, sz);
523     d->len += sz;
524   }
525   assert(((void)"I can't seem to choose a good key size",
526           keysz(d->len, ksz) == d->len));
527 }
528
529 static void hexkey(dstr *d, const char *p, const octet *ksz)
530 {
531   char *q;
532   unhex(optarg, &q, d);
533   if (*q)
534     die(EXIT_FAILURE, "bad hex key `%s'", p);
535   if (keysz(d->len, ksz) != d->len)
536     die(EXIT_FAILURE, "bad key length");
537 }
538
539 static void randkey(dstr *d, const octet *ksz)
540 {
541   size_t sz = keysz(0, ksz);
542   dstr_ensure(d, sz);
543   rand_get(RAND_GLOBAL, d->buf, sz);
544   d->len += sz;
545 }
546
547 /*----- Generators --------------------------------------------------------*/
548
549 /* --- Blum-Blum-Shub strong generator --- */
550
551 static grand *gen_bbs(unsigned i)
552 {
553   /* --- Default modulus --- *
554    *
555    * The factors of this number are
556    *
557    *  @p = 1229936431484295969649886203367009966370895964206162032259292413@
558    *      @7754313537966036459299022912838407755462506416274551744201653277@
559    *      @313130311731673973886822067@
560    *
561    *  @q = 9798171783943489959487301695884963889684294764514008432498259742@
562    *      @5374320073594018817245784145742769603334292182227671519041431067@
563    *      @61344781426317516045890159@
564    *
565    * Both %$p$% and %$q$% are prime; %$(p - 1)/2$% and %$(q - 1)/2$% have no
566    * common factors.  They were found using this program, with random
567    * starting points.
568    *
569    * I hope that, by publishing these factors, I'll dissuade people from
570    * actually using this modulus in an attempt to attain real security.  The
571    * program is quite quick at finding Blum numbers, so there's no excuse for
572    * not generating your own.
573    */
574
575   const char *mt =
576   "120511284390135742513572142094334711443073194119732569353820828435640527418092392240366088035509890969913081816369160298961490135716255689660470370755013177656905237112577648090277537209936078171554274553448103698084782669252936352843649980105109850503830397166360721262431179505917248447259735253684659338653";
577
578   /* --- Other things --- */
579
580   grand *r;
581   const char *xt = 0;
582   unsigned bits = 1024;
583   mp *m, *x;
584   unsigned show = 0;
585   const char *kfile = 0, *id = 0, *ktype = 0;
586
587   /* --- Parse options --- */
588
589   static struct option opts[] = {
590     { "modulus",        OPTF_ARGREQ,    0,      'M' },
591     { "generate",       0,              0,      'g' },
592     { "seed",           OPTF_ARGREQ,    0,      's' },
593     { "bits",           OPTF_ARGREQ,    0,      'b' },
594     { "show",           0,              0,      'S' },
595     { "keyring",        OPTF_ARGREQ,    0,      'k' },
596     { "id",             OPTF_ARGREQ,    0,      'i' },
597     { "type",           OPTF_ARGREQ,    0,      't' },
598     { 0,                0,              0,      0 }
599   };
600
601   addopts("M:gs:b:Sk:i:t:", opts);
602
603   for (;;) {
604     int o = opt();
605     if (o < 0)
606       break;
607     switch (o) {
608       case 'M':
609         mt = optarg;
610         break;
611       case 'g':
612         mt = 0;
613         break;
614       case 's':
615         xt = optarg;
616         break;
617       case 'b':
618         bits = strtoul(optarg, 0, 0);
619         if (bits == 0)
620           die(EXIT_FAILURE, "bad number of bits `%s'", optarg);
621         break;
622       case 'S':
623         show = 1;
624         break;
625       case 'k':
626         kfile = optarg;
627         mt = 0;
628         break;
629       case 'i':
630         id = optarg;
631         mt = 0;
632         break;
633       case 't':
634         ktype = optarg;
635         mt = 0;
636         break;
637       default:
638         return (0);
639     }
640   }
641
642   /* --- Generate a modulus if one is requested --- */
643
644   if (mt) {
645     char *p;
646     m = mp_readstring(MP_NEW, mt, &p, 0);
647     if (!m || *p || (m->v[0] & 3) != 1)
648       die(EXIT_FAILURE, "bad modulus `%s'", mt);
649     /* Unfortunately I don't know how to test for a Blum integer */
650   } else if (kfile || id || ktype) {
651     key_file kf;
652     key *kk;
653     key_data *kd;
654
655     /* --- Open the key file --- */
656
657     if (!kfile)
658       kfile = "keyring";
659     if (key_open(&kf, kfile, KOPEN_READ, key_moan, 0)) {
660       die(EXIT_FAILURE, "error opening key file `%s': %s",
661           kfile, strerror(errno));
662     }
663
664     /* --- Find the key --- */
665
666     if (id) {
667       if ((kk = key_bytag(&kf, id)) == 0)
668         die(EXIT_FAILURE, "key `%s' not found", id);
669     } else {
670       if (!ktype)
671         ktype = "bbs";
672       if ((kk = key_bytype(&kf, ktype)) == 0)
673         die(EXIT_FAILURE, "no suitable key with type `%s' found", ktype);
674     }
675
676     /* --- Read the key data --- */
677
678     if ((kk->k.e & KF_ENCMASK) != KENC_STRUCT)
679       die(EXIT_FAILURE, "key is not structured");
680     if ((kd = key_structfind(&kk->k, "n")) == 0)
681       die(EXIT_FAILURE, "key has no subkey `n'");
682     if ((kd->e & KF_ENCMASK) != KENC_MP)
683       die(EXIT_FAILURE, "incomatible subkey encoding");
684     m = MP_COPY(kd->u.m);
685     key_close(&kf);
686   } else {
687     bbs_priv bp;
688
689     if (bbs_gen(&bp, bits, &rand_global, 0,
690                 (flags & f_progress) ? pgen_ev : 0, 0))
691       die(EXIT_FAILURE, "modulus generation failed");
692     m = bp.n;
693
694     if (show) {
695       fputs("p = ", stderr);
696       mp_writefile(bp.p, stderr, 10);
697       fputs("\nq = ", stderr);
698       mp_writefile(bp.q, stderr, 10);
699       fputs("\nn = ", stderr);
700       mp_writefile(bp.n, stderr, 10);
701       fputc('\n', stderr);
702     }
703
704     mp_drop(bp.p);
705     mp_drop(bp.q);
706   }
707
708   /* --- Set up a seed --- */
709
710   if (!xt)
711     x = mprand(MP_NEW, mp_bits(m) - 1, &rand_global, 1);
712   else {
713     char *p;
714     x = mp_readstring(MP_NEW, xt, &p, 0);
715     if (*p)
716       die(EXIT_FAILURE, "bad modulus `%s'", xt);
717   }
718
719   /* --- Right --- */
720
721   r = bbs_rand(m, x);
722
723   mp_drop(m);
724   mp_drop(x);
725   return (r);
726 }
727
728 /* --- Catacomb's random number generator --- */
729
730 static grand *gen_rand(unsigned i)
731 {
732   grand *r = rand_create();
733   dstr d = DSTR_INIT;
734
735   static struct option opts[] = {
736     { "key",            OPTF_ARGREQ,    0,      'k' },
737     { "text",           OPTF_ARGREQ,    0,      't' },
738     { "hex",            OPTF_ARGREQ,    0,      'H' },
739     { 0,                0,              0,      0 }
740   };
741
742   addopts("k:t:H:n", opts);
743
744   r->ops->misc(r, RAND_NOISESRC, &noise_source);
745   r->ops->misc(r, RAND_SEED, 160);
746
747   for (;;) {
748     int o = opt();
749     if (o < 0)
750       break;
751     switch (o) {
752       case 'k':
753         DRESET(&d);
754         textkey(&d, optarg, rmd160_hmackeysz);
755         r->ops->misc(r, RAND_KEY, d.buf, d.len);
756         break;
757       case 't':
758         r->ops->misc(r, GRAND_SEEDBLOCK, optarg, strlen(optarg));
759         break;
760       case 'H':
761         DRESET(&d);
762         hexkey(&d, optarg, rmd160_hmackeysz);
763         r->ops->misc(r, GRAND_SEEDBLOCK, d.buf, d.len);
764         break;
765     }
766   }
767
768   dstr_destroy(&d);
769   return (r);
770 }
771
772 /* --- RC4 output --- */
773
774 static grand *gen_rc4(unsigned i)
775 {
776   grand *r;
777   dstr d = DSTR_INIT;
778
779   static struct option opts[] = {
780     { "key",            OPTF_ARGREQ,    0,      'k' },
781     { "hex",            OPTF_ARGREQ,    0,      'H' },
782     { 0,                0,              0,      0 }
783   };
784
785   addopts("k:H:", opts);
786
787   for (;;) {
788     int o = opt();
789     if (o < 0)
790       break;
791     switch (o) {
792       case 'k':
793         DRESET(&d);
794         textkey(&d, optarg, rc4_keysz);
795         break;
796       case 'H':
797         DRESET(&d);
798         hexkey(&d, optarg, rc4_keysz);
799         break;
800       default:
801         return (0);
802     }
803   }
804
805   if (!d.len)
806     randkey(&d, rc4_keysz);
807   r = rc4_rand(d.buf, d.len);
808   dstr_destroy(&d);
809   return (r);
810 }
811
812 /* --- SEAL output --- */
813
814 static grand *gen_seal(unsigned i)
815 {
816   grand *r;
817   dstr d = DSTR_INIT;
818   uint32 n = 0;
819
820   static struct option opts[] = {
821     { "key",            OPTF_ARGREQ,    0,      'k' },
822     { "hex",            OPTF_ARGREQ,    0,      'H' },
823     { "sequence",       OPTF_ARGREQ,    0,      'n' },
824     { 0,                0,              0,      0 }
825   };
826
827   addopts("k:H:n:", opts);
828
829   for (;;) {
830     int o = opt();
831     if (o < 0)
832       break;
833     switch (o) {
834       case 'k':
835         DRESET(&d);
836         textkey(&d, optarg, seal_keysz);
837         break;
838       case 'H':
839         DRESET(&d);
840         hexkey(&d, optarg, seal_keysz);
841         break;
842       case 'n': {
843         char *p;
844         n = strtoul(optarg, &p, 0);
845         if (*p)
846           die(EXIT_FAILURE, "bad number `%s'", optarg);
847       } break;
848       default:
849         return (0);
850     }
851   }
852
853   if (!d.len)
854     randkey(&d, seal_keysz);
855   r = seal_rand(d.buf, d.len, n);
856   dstr_destroy(&d);
857   return (r);
858 }
859
860 /* --- Output feedback generators --- */
861
862 static grand *gen_ofb(unsigned i)
863 {
864   grand *r;
865   dstr d = DSTR_INIT;
866   dstr iv = DSTR_INIT;
867
868   static struct option opts[] = {
869     { "key",            OPTF_ARGREQ,    0,      'k' },
870     { "hex",            OPTF_ARGREQ,    0,      'H' },
871     { "iv",             OPTF_ARGREQ,    0,      'i' },
872     { 0,                0,              0,      0 }
873   };
874
875   addopts("k:H:i:", opts);
876
877   for (;;) {
878     int o = opt();
879     if (o < 0)
880       break;
881     switch (o) {
882       case 'k':
883         DRESET(&d);
884         textkey(&d, optarg, ciphertab[i].keysz);
885         break;
886       case 'H':
887         DRESET(&d);
888         hexkey(&d, optarg, ciphertab[i].keysz);
889         break;
890       case 'i': {
891         char *p;
892         unhex(optarg, &p, &iv);
893         if (*p)
894           die(EXIT_FAILURE, "bad hex IV `%s'", optarg);
895       } break;
896       default:
897         return (0);
898     }
899   }
900
901   if (!d.len)
902     randkey(&d, ciphertab[i].keysz);
903   r = ciphertab[i].ofb(d.buf, d.len);
904   if (iv.len) {
905     if (iv.len != ciphertab[i].blksz) {
906       die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
907           (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
908     }
909     r->ops->misc(r, GRAND_SEEDBLOCK, iv.buf);
910   }
911
912   dstr_destroy(&d);
913   dstr_destroy(&iv);
914   return (r);
915 }
916
917 /* --- Counter generators --- */
918
919 static grand *gen_counter(unsigned i)
920 {
921   grand *r;
922   dstr d = DSTR_INIT;
923   dstr iv = DSTR_INIT;
924
925   static struct option opts[] = {
926     { "key",            OPTF_ARGREQ,    0,      'k' },
927     { "hex",            OPTF_ARGREQ,    0,      'H' },
928     { "iv",             OPTF_ARGREQ,    0,      'i' },
929     { 0,                0,              0,      0 }
930   };
931
932   addopts("k:H:i:", opts);
933
934   for (;;) {
935     int o = opt();
936     if (o < 0)
937       break;
938     switch (o) {
939       case 'k':
940         DRESET(&d);
941         textkey(&d, optarg, ciphertab[i].keysz);
942         break;
943       case 'H':
944         DRESET(&d);
945         hexkey(&d, optarg, ciphertab[i].keysz);
946         break;
947       case 'i': {
948         char *p;
949         unhex(optarg, &p, &iv);
950         if (*p)
951           die(EXIT_FAILURE, "bad hex IV `%s'", optarg);
952       } break;
953       default:
954         return (0);
955     }
956   }
957
958   if (!d.len)
959     randkey(&d, ciphertab[i].keysz);
960   r = ciphertab[i].counter(d.buf, d.len);
961   if (iv.len) {
962     if (iv.len != ciphertab[i].blksz) {
963       die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
964           (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
965     }
966     r->ops->misc(r, GRAND_SEEDBLOCK, iv.buf);
967   }
968
969   dstr_destroy(&d);
970   dstr_destroy(&iv);
971   return (r);
972 }
973
974 /* --- Mask generators --- */
975
976 static grand *gen_mgf(unsigned i)
977 {
978   grand *r;
979   dstr d = DSTR_INIT;
980   uint32 c = 0;
981
982   static struct option opts[] = {
983     { "key",            OPTF_ARGREQ,    0,      'k' },
984     { "hex",            OPTF_ARGREQ,    0,      'H' },
985     { "index",          OPTF_ARGREQ,    0,      'i' },
986     { 0,                0,              0,      0 }
987   };
988
989   addopts("k:H:i:", opts);
990
991   for (;;) {
992     int o = opt();
993     if (o < 0)
994       break;
995     switch (o) {
996       case 'k':
997         DRESET(&d);
998         textkey(&d, optarg, hashtab[i].keysz);
999         break;
1000       case 'H':
1001         DRESET(&d);
1002         hexkey(&d, optarg, hashtab[i].keysz);
1003         break;
1004       case 'i': {
1005         char *p;
1006         c = strtoul(optarg, &p, 0);
1007         if (*p)
1008           die(EXIT_FAILURE, "bad index `%s'", optarg);
1009       } break;
1010       default:
1011         return (0);
1012     }
1013   }
1014
1015   if (!d.len)
1016     randkey(&d, hashtab[i].keysz);
1017
1018   r = hashtab[i].mgf(d.buf, d.len);
1019   if (c)
1020     r->ops->misc(r, GRAND_SEEDUINT32, c);
1021
1022   dstr_destroy(&d);
1023   return (r);
1024 }
1025
1026 /* --- Fibonacci generator --- */
1027
1028 static grand *gen_fib(unsigned i)
1029 {
1030   grand *r;
1031   uint32 s = 0;
1032   char *p;
1033   unsigned set = 0;
1034
1035   static struct option opts[] = {
1036     { "seed",           OPTF_ARGREQ,    0,      's' },
1037     { 0,                0,              0,      0 }
1038   };
1039
1040   addopts("s:", opts);
1041
1042   for (;;) {
1043     int o = opt();
1044     if (o < 0)
1045       break;
1046     switch (o) {
1047       case 's':
1048         s = strtoul(optarg, &p, 0);
1049         if (*p)
1050           die(EXIT_FAILURE, "bad integer `%s'", optarg);
1051         set = 1;
1052         break;
1053       default:
1054         return (0);
1055     }
1056   }
1057   r = fibrand_create(s);
1058   if (!set)
1059     r->ops->misc(r, GRAND_SEEDRAND, &rand_global);
1060   return (r);
1061 }
1062
1063 /* --- LC generator --- */
1064
1065 static grand *gen_lc(unsigned i)
1066 {
1067   uint32 s = 0;
1068   char *p;
1069   unsigned set = 0;
1070
1071   static struct option opts[] = {
1072     { "seed",           OPTF_ARGREQ,    0,      's' },
1073     { 0,                0,              0,      0 }
1074   };
1075
1076   addopts("s:", opts);
1077
1078   for (;;) {
1079     int o = opt();
1080     if (o < 0)
1081       break;
1082     switch (o) {
1083       case 's':
1084         s = strtoul(optarg, &p, 0);
1085         if (*p)
1086           die(EXIT_FAILURE, "bad integer `%s'", optarg);
1087         set = 1;
1088         break;
1089       default:
1090         return (0);
1091     }
1092   }
1093   if (!set) {
1094     do
1095       s = rand_global.ops->range(&rand_global, LCRAND_P);
1096     while (s == LCRAND_FIXEDPT);
1097   }
1098   return (lcrand_create(s));
1099 }
1100
1101 /* --- Basic options parser -- can't generate output --- */
1102
1103 static grand *gen_opts(unsigned i)
1104 {
1105   while (opt() >= 0)
1106     ;
1107   return (0);
1108 }
1109
1110 /*----- Generators table --------------------------------------------------*/
1111
1112 gen generators[] = {
1113   { "fibonacci",        gen_fib,        0,
1114     "[-s SEED]" },
1115   { "lc",               gen_lc,         0,
1116     "[-s SEED]" },
1117 #define E(PRE, pre)                                                     \
1118   { #pre "-ofb",        gen_ofb,        CIPHER_##PRE,                   \
1119     "[-k KEY-PHRASE] [-H HEX-KEY] [-i HEX-IV]" },
1120   CIPHERS
1121 #undef E
1122 #define E(PRE, pre)                                                     \
1123   { #pre "-counter",    gen_counter,    CIPHER_##PRE,                   \
1124     "[-k KEY-PHRASE] [-H HEX-KEY] [-i HEX-IV]" },
1125   CIPHERS
1126 #undef E
1127 #define E(PRE, pre)                                                     \
1128   { #pre "-mgf",        gen_mgf,        HASH_##PRE,                     \
1129     "[-k KEY-PHRASE] [-H HEX-KEY] [-i INDEX]" },
1130   HASHES
1131 #undef E
1132   { "rc4",              gen_rc4,        0,
1133     "[-k KEY-PHRASE] [-H HEX-KEY]" },
1134   { "seal",             gen_seal,       0,
1135     "[-k KEY-PHRASE] [-H HEX-KEY] [-n SEQ]" },
1136   { "rand",             gen_rand,       0,
1137     "[-n] [-k KEY-PHRASE] [-t TEXT-BLOCK] [-H HEX-BLOCK]" },
1138   { "bbs",              gen_bbs,        0,
1139     "[-gS] [-s SEED] [-M MODULUS] [-b BITS] [-k KEYRING] [-i TAG] [-t TYPE]"
1140   },
1141   { 0,                  0,              0, 0 },
1142 };
1143
1144 static gen optsg = { "options", gen_opts, 0,
1145                      "This message shouldn't be printed." };
1146
1147 /*----- Random number generation ------------------------------------------*/
1148
1149 static int genfile(const void *buf, size_t sz, void *p)
1150 {
1151   FILE *fp = p;
1152   if (fwrite(buf, 1, sz, fp) != sz)
1153     die(EXIT_FAILURE, "error writing to file: %s", strerror(errno));
1154   return (0);
1155 }
1156
1157 static int genbuf(const void *buf, size_t sz, void *p)
1158 {
1159   octet **pp = p;
1160   memcpy(*pp, buf, sz);
1161   *pp += sz;
1162   return (0);
1163 }
1164
1165 typedef struct genmaurer_ctx {
1166   size_t n;
1167   maurer_ctx *m;
1168 } genmaurer_ctx;
1169
1170 static int genmaurer(const void *buf, size_t sz, void *p)
1171 {
1172   genmaurer_ctx *g = p;
1173   size_t i;
1174
1175   for (i = 0; i < g->n; i++)
1176     maurer_test(&g->m[i], buf, sz);
1177   return (0);
1178 }
1179
1180 static int generate(grand *r, size_t outsz,
1181                     int (*func)(const void *buf, size_t sz, void *p),
1182                     void *p)
1183 {
1184   static char kmg[] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0 };
1185
1186   unsigned percent = 0;
1187   size_t kb = 0;
1188   time_t last;
1189   static char baton[] = "-\\|/";
1190   char *bp;
1191   int rc;
1192   clock_t clk = 0;
1193
1194   /* --- Spit out random data --- */
1195
1196   last = time(0);
1197   bp = baton;
1198   if (flags & f_progress) {
1199     char *errbuf = xmalloc(BUFSIZ);
1200     setvbuf(stderr, errbuf, _IOLBF, BUFSIZ);
1201     if (outsz)
1202       fprintf(stderr, "[%*s]   0%%    0\r[/\b", 50, "");
1203     else
1204       fputs("[ ]    0\r[/\b", stderr);
1205     fflush(stderr);
1206   }
1207
1208 #ifdef SIGPIPE
1209   signal(SIGPIPE, SIG_IGN);
1210 #endif
1211
1212   do {
1213     octet buf[BUFSIZ];
1214     size_t sz = sizeof(buf);
1215     clock_t c_start, c_stop;
1216
1217     /* --- Emit a bufferful (or less) of data --- */
1218
1219     if (outsz) {
1220       if (sz > outsz - kb)
1221         sz = outsz - kb;
1222     }
1223     c_start = clock();
1224     r->ops->fill(r, buf, sz);
1225     c_stop = clock();
1226     clk += c_stop - c_start;
1227     if (func && (rc = func(buf, sz, p)) != 0)
1228       return (rc);
1229     kb += sz;
1230
1231     /* --- Update the display --- */
1232
1233     if (flags & f_progress) {
1234       time_t t = time(0);
1235       unsigned up = 0;
1236
1237       if (percent > 100)
1238         up = 1;
1239
1240       if (!outsz) {
1241         if (difftime(t, last) > 1.0) {
1242           up = 1;
1243         }
1244         if (up)
1245           fputs(" ] ", stderr);
1246       } else {
1247         unsigned pc = kb * 100.0 / outsz;
1248         if (pc > percent || percent > 100 || difftime(t, last) > 1.0) {
1249           if (percent > 100)
1250             percent = 0;
1251           percent &= ~1;
1252           for (; percent < (pc & ~1); percent += 2)
1253             putc('.', stderr);
1254           percent = pc;
1255           for (; pc < 100; pc += 2)
1256             putc(' ', stderr);
1257           fprintf(stderr, "] %3i%% ", percent);
1258           up = 1;
1259         }
1260       }
1261
1262       if (up) {
1263         size_t q = kb;
1264         char *kk = kmg;
1265         while (q > 8192 && kk[1]) {
1266           q >>= 10;
1267           kk++;
1268         }
1269         fprintf(stderr, "%4i%c\r[", q, *kk);
1270         if (outsz) {
1271           unsigned pc;
1272           for (pc = 0; pc < (percent & ~1); pc += 2)
1273             putc('.', stderr);
1274         }
1275         last = t;
1276       }
1277
1278       if (percent > 100)
1279         percent = 0;
1280
1281       if (percent < 100) {
1282         putc(*bp++, stderr);
1283         putc('\b', stderr);
1284         if (!*bp)
1285           bp = baton;
1286       }
1287       fflush(stderr);
1288     }
1289
1290     /* --- Terminate the loop --- */
1291
1292   } while (!outsz || kb < outsz);
1293
1294   if (flags & f_progress)
1295     fputc('\n', stderr);
1296   if (flags & f_timer) {
1297     fprintf(stderr, "generated %lu bytes ", (unsigned long)outsz);
1298     if (!clk)
1299       fputs("too quickly to measure\n", stderr);
1300     else {
1301       char *kk;
1302       double sec = (double)clk/CLOCKS_PER_SEC;
1303       double bps = (outsz << 3)/sec;
1304       for (kk = kmg; bps > 1024 && kk[1]; kk++, bps /= 1024)
1305         ;
1306       fprintf(stderr, "in %g secs (%g %cb/s)\n", sec, bps, *kk);
1307     }
1308   }
1309   return (0);
1310 }
1311
1312 /*----- Main code ---------------------------------------------------------*/
1313
1314 int main(int ac, char *av[])
1315 {
1316   gen *g = &optsg;
1317   grand *r;
1318
1319   /* --- Initialize mLib --- */
1320
1321   ego(av[0]);
1322   sub_init();
1323
1324   /* --- Set up the main Catacomb generator --- */
1325
1326   rand_noisesrc(RAND_GLOBAL, &noise_source);
1327   rand_seed(RAND_GLOBAL, 160);
1328
1329   /* --- Initialize the options table --- */
1330
1331   addopts(sopts, opts);
1332   argc = ac;
1333   argv = av;
1334   outfp = stdout;
1335
1336   /* --- Read the generator out of the first argument --- */
1337
1338   if (argc > 1 && *argv[1] != '-') {
1339     const char *arg = av[1];
1340     size_t sz = strlen(arg);
1341     gen *gg;
1342
1343     g = 0;
1344     for (gg = generators; gg->name; gg++) {
1345       if (strncmp(arg, gg->name, sz) == 0) {
1346         if (gg->name[sz] == 0) {
1347           g = gg;
1348           break;
1349         } else if (g)
1350           die(EXIT_FAILURE, "ambiguous generator name `%s'", arg);
1351         else
1352           g = gg;
1353       }
1354     }
1355     if (!g)
1356       die(EXIT_FAILURE, "unknown generator name `%s'", arg);
1357     argc--;
1358     argv++;
1359   }
1360
1361   /* --- Get a generic random number generator --- */
1362
1363   r = g->seed(g->i);
1364   if (!r || optind != ac - 1) {
1365     usage(stderr);
1366     exit(EXIT_FAILURE);
1367   }
1368
1369   /* --- Do the FIPS test --- */
1370
1371   if (flags & f_fips) {
1372     octet buf[FIPSTEST_BUFSZ];
1373     unsigned rc;
1374     octet *p = buf;
1375
1376     generate(r, sizeof(buf), genbuf, &p);
1377     rc = fipstest(buf);
1378     if (rc & FIPSTEST_MONOBIT)
1379       moan("failed monobit test");
1380     if (rc & FIPSTEST_POKER)
1381       moan("failed poker test");
1382     if (rc & FIPSTEST_RUNS)
1383       moan("failed runs test");
1384     if (rc & FIPSTEST_LONGRUNS)
1385       moan("failed long runs test");
1386     if (!rc && (flags & f_progress))
1387       fputs("test passed\n", stderr);
1388     return (rc ? EXIT_FAILURE : 0);
1389   }
1390
1391   /* --- Do Maurer's test --- */
1392
1393   if (flags & f_maurer) {
1394     size_t bufsz;
1395     unsigned i;
1396     unsigned rc = 0;
1397     genmaurer_ctx g;
1398
1399     static struct { double x; const char *sig; } sigtab[] = {
1400       { 3.2905, "1e-3" },
1401       { 3.0902, "2e-3" },
1402       { 2.8070, "5e-3" },
1403       { 2.5758, "1e-2" },
1404       { 0     , 0      }
1405     };
1406
1407     g.n = maurer_hi - maurer_lo + 1;
1408     g.m = xmalloc(g.n * sizeof(maurer_ctx));
1409     for (i = 0; i < g.n; i++)
1410       maurer_init(&g.m[i], i + maurer_lo);
1411     bufsz = (100 * maurer_hi) << maurer_hi;
1412
1413     generate(r, bufsz, genmaurer, &g);
1414
1415     for (i = maurer_lo; i <= maurer_hi; i++) {
1416       double z = maurer_done(&g.m[i - maurer_lo]);
1417       double zz = fabs(z);
1418       unsigned j;
1419
1420       for (j = 0; sigtab[j].sig; j++) {
1421         if (zz > sigtab[j].x) {
1422           rc = EXIT_FAILURE;
1423           moan("failed, bits = %u, sig = %s, Z_u = %g",
1424                i, sigtab[j].sig, z);
1425           break;
1426         }
1427       }
1428       if (flags & f_progress)
1429         fprintf(stderr, "bits = %u, Z_u = %g\n", i, z);
1430     }
1431
1432     xfree(g.m);
1433     return (rc);
1434   }
1435
1436   /* --- Discard --- */
1437
1438   if (flags & f_discard) {
1439     generate(r, outsz, 0, 0);
1440     return (0);
1441   }
1442
1443   /* --- Write to a file --- */
1444
1445 #ifndef PORTABLE
1446   if (!(flags & f_file) && isatty(STDOUT_FILENO))
1447     die(EXIT_FAILURE, "writing output to a terminal is a bad idea");
1448 #endif
1449
1450   generate(r, outsz, genfile, outfp);
1451
1452   /* --- Done --- */
1453
1454   r->ops->destroy(r);
1455   return (0);
1456 }
1457
1458 /*----- That's all, folks -------------------------------------------------*/