Merge branch 'mdw/fixes'
authorMark Wooding <mdw@distorted.org.uk>
Mon, 25 May 2015 17:59:52 +0000 (18:59 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 25 May 2015 17:59:52 +0000 (18:59 +0100)
* mdw/fixes:
  symm/safer.[ch]: Correct description for `safer_setup'.
  symm/rc4.h: Mention that RC4 isn't really very good.
  symm/rc4.[ch]: Fix incorrect documentation on `rc4_rand'.
  symm/seal.c: Fix IV handling through `gcipher' interface.
  math/mpint.h: Add new conversions.
  math/mpint.[ch]: Consolidate the list of supplied conversions in header.
  progs/rspit.c: Update the baton more frequently if we can.
  progs/rspit.c: Higher resolution timing.
  progs/rspit.c: Handle large requested output.
  progs/rspit.c: Better handling of block cipher IVs.
  progs/rspit.c: Make the internal tables be const.
  rand/rand.[ch]: Spring-clean the random source cryptography.
  rand/rand.[ch]: Don't dynamically construct the global generator.
  symm/multigen: Some UI improvements.
  symm: Expunge stubby header files from the source tree.
  symm/Makefile.am: Modes files listed as `EXTRA_DIST' and `nodist_...'.
  symm/Makefile.am: Have modes things depend on `Makefile.am'.
  symm/modes.am.in: Fix `Generated from ...' header.

23 files changed:
.gitignore
build-setup
math/mpint.c
math/mpint.h
progs/rspit.c
rand/rand.c
rand/rand.h
symm/Makefile.am
symm/modes.am.in
symm/multigen
symm/rc4.c
symm/rc4.h
symm/safer.c
symm/safer.h
symm/safersk.c
symm/safersk.h [deleted file]
symm/seal.c
symm/sha224.h [deleted file]
symm/sha384.h [deleted file]
symm/stub.c.in [new file with mode: 0644]
symm/stub.h.in [new file with mode: 0644]
symm/stubs.am.in [new file with mode: 0644]
symm/whirlpool256.h [deleted file]

index 7603014..39e8565 100644 (file)
@@ -8,5 +8,16 @@ precomp
 progs/getdate.h
 progs/getdate.y
 symm/modes.am
+symm/stubs.am
 *.t
 *.to
+/symm/safersk.h
+/symm/salsa2012.h
+/symm/salsa208.h
+/symm/sha224.h
+/symm/sha384.h
+/symm/whirlpool256.h
+/symm/xsalsa20.h
+/symm/xsalsa2012.h
+/symm/xsalsa208.h
+/symm/stubs.gen-stamp
index 77af12e..ded8b11 100755 (executable)
@@ -1,2 +1,4 @@
 #! /bin/sh -ex
-if [ ! -r symm/modes.am ]; then touch -t197001010000.00 symm/modes.am; fi
+for gen in symm/modes.am symm/stubs.am; do
+  if [ ! -r $gen ]; then touch -t197001010000.00 $gen; fi
+done
index d89fb07..3511f1e 100644 (file)
 
 /* --- Conversion from C integers --- */
 
-#define FROM(name, type)                                               \
+#define FROM(name, type, max)                                          \
   mp *mp_from##name(mp *d, type i) {                                   \
     MP_FROMINT(d, type, i);                                            \
     return (d);                                                                \
   }
-
-FROM(short, short)
-FROM(ushort, unsigned short)
-FROM(int, int)
-FROM(uint, unsigned)
-FROM(uint32, uint32)
-FROM(long, long)
-FROM(ulong, unsigned long)
-
-#undef FROM
+MPINT_CONVERSIONS(FROM)
 
 /* --- Conversion to C integers --- */
 
@@ -58,14 +49,7 @@ FROM(ulong, unsigned long)
     MP_TOINT(m, type, max, i);                                         \
     return (i);                                                                \
   }
-
-TO(short, short, SHRT_MAX)
-TO(ushort, unsigned short, USHRT_MAX)
-TO(int, int, INT_MAX)
-TO(uint, unsigned, UINT_MAX)
-TO(uint32, uint32, 0xffffffff)
-TO(long, long, LONG_MAX)
-TO(ulong, unsigned long, ULONG_MAX)
+MPINT_CONVERSIONS(TO)
 
 #undef TO
 
index e351b05..1b0a762 100644 (file)
 
 /*----- Functions provided ------------------------------------------------*/
 
+/* --- Build up the list of conversions to be supplied --- */
+
+#ifdef ULLONG_MAX
+#  ifndef LLONG_MAX
+#    define LLONG_MAX LONG_LONG_MAX
+#  endif
+#  define MPINT_CONV_LLONG(_)                                          \
+  _(llong, long long, LLONG_MAX)                                       \
+  _(ullong, unsigned long long, ULLONG_MAX)
+#else
+#  define MPINT_CONV_LLONG(_)
+#endif
+
+#ifdef INTMAX_MAX
+#  define MPINT_CONV_INTMAX(_)                                         \
+  _(intmax, intmax_t, INTMAX_MAX)                                      \
+  _(uintmax, uintmax_t, UINTMAX_MAX)
+#else
+#  define MPINT_CONV_INTMAX(_)
+#endif
+
+#ifdef HAVE_UINT64
+#  define MPINT_CONV_U64(_) _(uint64, uint64, MASK64)
+#else
+#  define MPINT_CONV_U64(_)
+#endif
+
+#define MPINT_CONVERSIONS(_)                                           \
+  _(short, short, SHRT_MAX)                                            \
+  _(ushort, unsigned short, USHRT_MAX)                                 \
+  _(int, int, INT_MAX)                                                 \
+  _(uint, unsigned, UINT_MAX)                                          \
+  _(long, long, LONG_MAX)                                              \
+  _(ulong, unsigned long, ULONG_MAX)                                   \
+  MPINT_CONV_LLONG(_)                                                  \
+  _(uint8, uint8, MASK8)                                               \
+  _(uint16, uint16, MASK16)                                            \
+  _(uint24, uint24, MASK24)                                            \
+  _(uint32, uint32, MASK32)                                            \
+  MPINT_CONV_U64(_)                                                    \
+  MPINT_CONV_INTMAX(_)                                                 \
+  _(sizet, size_t, (size_t)-1)
+
 /* --- @mp_fromINT@ --- *
  *
  * Arguments:  @mp *d@ = pointer to destination multiprecision integer
  * Use:                Converts a standard C integer to a multiprecision integer.
  */
 
-#define mp_fromINT(name, type)                                         \
-  extern mp *mp_from##name(mp */*d*/, type /*i*/)
-
-mp_fromINT(short, short);
-mp_fromINT(ushort, unsigned short);
-mp_fromINT(int, int);
-mp_fromINT(uint, unsigned);
-mp_fromINT(uint32, uint32);
-mp_fromINT(long, long);
-mp_fromINT(ulong, unsigned long);
-
+#define mp_fromINT(name, type, max)                                    \
+  extern mp *mp_from##name(mp */*d*/, type /*i*/);
+MPINT_CONVERSIONS(mp_fromINT)
 #undef mp_fromINT
 
 /* --- @mp_toINT@ --- *
@@ -181,17 +216,9 @@ mp_fromINT(ulong, unsigned long);
  *             type is signed, the behaviour is undefined.
  */
 
-#define mp_toINT(name, type)                                           \
-  extern type mp_to##name(const mp */*m*/)
-
-mp_toINT(short, short);
-mp_toINT(ushort, unsigned short);
-mp_toINT(int, int);
-mp_toINT(uint, unsigned);
-mp_toINT(uint32, uint32);
-mp_toINT(long, long);
-mp_toINT(ulong, unsigned long);
-
+#define mp_toINT(name, type, max)                                      \
+  extern type mp_to##name(const mp */*m*/);
+MPINT_CONVERSIONS(mp_toINT)
 #undef mp_toINT
 
 /*----- That's all, folks -------------------------------------------------*/
index b75c6f8..67913d5 100644 (file)
@@ -40,6 +40,7 @@
 
 #ifndef PORTABLE
 #  include <unistd.h>
+#  include <sys/time.h>
 #endif
 
 #include <mLib/darray.h>
 #include <mLib/report.h>
 #include <mLib/sub.h>
 
+#include "mp.h"
+#include "mpint.h"
+#include "mplimits.h"
+#include "mptext.h"
+
 #include "fipstest.h"
 #include "grand.h"
 #include "maurer.h"
@@ -174,7 +180,7 @@ enum { CIPHERS CIPHER__bogus };
 enum { HASHES HASH__bogus };
 #undef E
 
-static struct {
+static const struct {
   const octet *keysz;
   size_t blksz;
   grand *(*ofb)(const void */*k*/, size_t /*sz*/);
@@ -186,7 +192,7 @@ static struct {
 #undef E
 };
 
-static struct {
+static const struct {
   const gchash *h;
   const octet *keysz;
   grand *(*mgf)(const void */*k*/, size_t /*sz*/);
@@ -200,7 +206,7 @@ static struct {
 /*----- Miscellaneous static data -----------------------------------------*/
 
 static FILE *outfp;
-static size_t outsz = 0;
+static mp *outsz = 0;
 static unsigned maurer_lo = 5, maurer_hi = 8;
 
 static int argc;
@@ -380,13 +386,13 @@ static int opt(void)
        break;
       case 'z': {
        char *p;
-       outsz = strtoul(optarg, &p, 0);
-       if (!outsz)
+       outsz = mp_readstring(outsz, optarg, &p, 0);
+       if (!outsz || MP_NEGP(outsz))
          die(EXIT_FAILURE, "bad number `%s'", optarg);
        switch (*p) {
-         case 'G': case 'g': outsz *= 1024;
-         case 'M': case 'm': outsz *= 1024;
-         case 'K': case 'k': outsz *= 1024;
+         case 'G': case 'g': outsz = mp_lsl(outsz, outsz, 10);
+         case 'M': case 'm': outsz = mp_lsl(outsz, outsz, 10);
+         case 'K': case 'k': outsz = mp_lsl(outsz, outsz, 10);
          case 0:
            break;
          default:
@@ -831,9 +837,14 @@ static grand *gen_ofb(unsigned i)
        break;
       case 'i': {
        char *p;
+       DRESET(&iv);
        unhex(optarg, &p, &iv);
        if (*p)
          die(EXIT_FAILURE, "bad hex IV `%s'", optarg);
+       if (iv.len != ciphertab[i].blksz) {
+         die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
+             (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
+       }
       } break;
       default:
        return (0);
@@ -843,13 +854,8 @@ static grand *gen_ofb(unsigned i)
   if (!d.len)
     randkey(&d, ciphertab[i].keysz);
   r = ciphertab[i].ofb(d.buf, d.len);
-  if (iv.len) {
-    if (iv.len != ciphertab[i].blksz) {
-      die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
-         (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
-    }
+  if (iv.len)
     r->ops->misc(r, GRAND_SEEDBLOCK, iv.buf);
-  }
 
   dstr_destroy(&d);
   dstr_destroy(&iv);
@@ -888,9 +894,14 @@ static grand *gen_counter(unsigned i)
        break;
       case 'i': {
        char *p;
+       DRESET(&iv);
        unhex(optarg, &p, &iv);
        if (*p)
          die(EXIT_FAILURE, "bad hex IV `%s'", optarg);
+       if (iv.len != ciphertab[i].blksz) {
+         die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
+             (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
+       }
       } break;
       default:
        return (0);
@@ -900,13 +911,8 @@ static grand *gen_counter(unsigned i)
   if (!d.len)
     randkey(&d, ciphertab[i].keysz);
   r = ciphertab[i].counter(d.buf, d.len);
-  if (iv.len) {
-    if (iv.len != ciphertab[i].blksz) {
-      die(EXIT_FAILURE, "bad IV length %lu (must be %lu)",
-         (unsigned long)iv.len, (unsigned long)ciphertab[i].blksz);
-    }
+  if (iv.len)
     r->ops->misc(r, GRAND_SEEDBLOCK, iv.buf);
-  }
 
   dstr_destroy(&d);
   dstr_destroy(&iv);
@@ -1119,15 +1125,32 @@ static int genmaurer(const void *buf, size_t sz, void *p)
   return (0);
 }
 
-static int generate(grand *r, size_t outsz,
+static double doubletime(void)
+{
+#ifdef PORTABLE
+  static time_t start = (time_t)-1;
+  time_t now = time(0);
+
+  if (start == (time_t)-1) start = now;
+  return difftime(now, start);
+#else
+  struct timeval tv;
+
+  gettimeofday(&tv, 0);
+  return (tv.tv_sec + tv.tv_usec/1000000.0);
+#endif
+}
+
+static int generate(grand *r, mp *outsz,
                    int (*func)(const void *buf, size_t sz, void *p),
                    void *p)
 {
   static char kmg[] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0 };
 
   unsigned percent = 0;
-  size_t kb = 0;
-  time_t last;
+  mp *kb = MP_ZERO, *t = MP_NEW;
+  dstr d = DSTR_INIT;
+  double now, last;
   static char baton[] = "-\\|/";
   char *bp;
   int rc;
@@ -1135,7 +1158,7 @@ static int generate(grand *r, size_t outsz,
 
   /* --- Spit out random data --- */
 
-  last = time(0);
+  last = doubletime();
   bp = baton;
   if (flags & f_progress) {
     char *errbuf = xmalloc(BUFSIZ);
@@ -1151,16 +1174,20 @@ static int generate(grand *r, size_t outsz,
   signal(SIGPIPE, SIG_IGN);
 #endif
 
-  do {
+  while (!outsz || MP_CMP(kb, <, outsz)) {
     octet buf[BUFSIZ];
-    size_t sz = sizeof(buf);
+    size_t sz = sizeof(buf), left;
     clock_t c_start, c_stop;
 
     /* --- Emit a bufferful (or less) of data --- */
 
     if (outsz) {
-      if (sz > outsz - kb)
-       sz = outsz - kb;
+      t = mp_sub(t, outsz, kb);
+      assert(!MP_NEGP(t));
+      if (MP_CMP(t, <=, MP_SIZET_MAX)) {
+       left = mp_tosizet(t);
+       if (sz > left) sz = left;
+      }
     }
     c_start = clock();
     r->ops->fill(r, buf, sz);
@@ -1168,26 +1195,33 @@ static int generate(grand *r, size_t outsz,
     clk += c_stop - c_start;
     if (func && (rc = func(buf, sz, p)) != 0)
       return (rc);
-    kb += sz;
+    t = mp_fromsizet(t, sz);
+    kb = mp_add(kb, kb, t);
 
     /* --- Update the display --- */
 
     if (flags & f_progress) {
-      time_t t = time(0);
       unsigned up = 0;
 
+      now = doubletime();
+
       if (percent > 100)
        up = 1;
 
       if (!outsz) {
-       if (difftime(t, last) > 1.0) {
+       if (now - last > 0.1) {
          up = 1;
        }
        if (up)
          fputs(" ] ", stderr);
       } else {
-       unsigned pc = kb * 100.0 / outsz;
-       if (pc > percent || percent > 100 || difftime(t, last) > 1.0) {
+       unsigned pc;
+       t = mp_fromulong(t, 100);
+       t = mp_mul(t, t, kb);
+       mp_div(&t, 0, t, outsz);
+       assert(!MP_NEGP(t) && MP_CMP(t, <, MP_UINT_MAX));
+       pc = mp_touint(t);
+       if (pc > percent || percent > 100 || now - last > 0.1) {
          if (percent > 100)
            percent = 0;
          percent &= ~1;
@@ -1202,25 +1236,27 @@ static int generate(grand *r, size_t outsz,
       }
 
       if (up) {
-       size_t q = kb;
        char *kk = kmg;
-       while (q > 8192 && kk[1]) {
-         q >>= 10;
+       t = mp_add(t, kb, MP_ZERO);
+       while (mp_bits(t) >= 14) {
+         t = mp_lsr(t, t, 10);
          kk++;
        }
-       fprintf(stderr, "%4i%c\r[", (int)q, *kk);
+       DRESET(&d);
+       mp_writedstr(t, &d, 10);
+       fprintf(stderr, "%4s%c\r[", d.buf, *kk);
        if (outsz) {
          unsigned pc;
          for (pc = 0; pc < (percent & ~1); pc += 2)
            putc('.', stderr);
        }
-       last = t;
+       last = now;
       }
 
       if (percent > 100)
        percent = 0;
 
-      if (percent < 100) {
+      if (percent < 100 && up) {
        putc(*bp++, stderr);
        putc('\b', stderr);
        if (!*bp)
@@ -1228,26 +1264,44 @@ static int generate(grand *r, size_t outsz,
       }
       fflush(stderr);
     }
-
-    /* --- Terminate the loop --- */
-
-  } while (!outsz || kb < outsz);
+  }
 
   if (flags & f_progress)
     fputc('\n', stderr);
   if (flags & f_timer) {
-    fprintf(stderr, "generated %lu bytes ", (unsigned long)outsz);
+    DRESET(&d);
+    dstr_puts(&d, "generated ");
+    mp_writedstr(kb, &d, 10);
+    dstr_puts(&d, " bytes ");
     if (!clk)
-      fputs("too quickly to measure\n", stderr);
+      dstr_puts(&d, "too quickly to measure\n");
     else {
       char *kk;
+      double out;
       double sec = (double)clk/CLOCKS_PER_SEC;
-      double bps = (outsz << 3)/sec;
+      unsigned long sh;
+      double bps;
+
+      MP_SHRINK(kb);
+      switch (MP_LEN(kb)) {
+       case 0: out = 0; break;
+       case 1: out = kb->v[0]; break;
+       default:
+         sh = mp_bits(kb) - MPW_BITS;
+         t = mp_lsr(t, kb, sh);
+         out = ldexp(t->v[0], sh);
+         break;
+      }
+      bps = (8*out)/sec;
       for (kk = kmg; bps > 1024 && kk[1]; kk++, bps /= 1024)
        ;
-      fprintf(stderr, "in %g secs (%g %cb/s)\n", sec, bps, *kk);
+      dstr_putf(&d, "in %g secs (%g %cb/s)\n", sec, bps, *kk);
+      fwrite(d.buf, 1, d.len, stderr);
     }
   }
+
+  mp_drop(t);
+  DDESTROY(&d);
   return (0);
 }
 
@@ -1313,9 +1367,12 @@ int main(int ac, char *av[])
   if (flags & f_fips) {
     octet buf[FIPSTEST_BUFSZ];
     unsigned rc;
+    mp *t;
     octet *p = buf;
 
-    generate(r, sizeof(buf), genbuf, &p);
+    t = mp_fromsizet(MP_NEW, sizeof(buf));
+    generate(r, t, genbuf, &p);
+    mp_drop(t);
     rc = fipstest(buf);
     if (rc & FIPSTEST_MONOBIT)
       moan("failed monobit test");
@@ -1336,6 +1393,7 @@ int main(int ac, char *av[])
     size_t bufsz;
     unsigned i;
     unsigned rc = 0;
+    mp *t;
     genmaurer_ctx g;
 
     static struct { double x; const char *sig; } sigtab[] = {
@@ -1352,7 +1410,9 @@ int main(int ac, char *av[])
       maurer_init(&g.m[i], i + maurer_lo);
     bufsz = (100 * maurer_hi) << maurer_hi;
 
-    generate(r, bufsz, genmaurer, &g);
+    t = mp_fromsizet(MP_NEW, bufsz);
+    generate(r, t, genmaurer, &g);
+    mp_drop(t);
 
     for (i = maurer_lo; i <= maurer_hi; i++) {
       double z = maurer_done(&g.m[i - maurer_lo]);
index fa6dab8..ab00e89 100644 (file)
 #include <mLib/sub.h>
 
 #include "arena.h"
-#include "blowfish-cbc.h"
 #include "paranoia.h"
+
+#define RAND__HACKS
 #include "rand.h"
-#include "rmd160.h"
-#include "rmd160-hmac.h"
+
+#include "noise.h"
+
+#include "twofish-counter.h"
+#include "sha256.h"
+
+#define CIPHER_CTX twofish_counterctx
+#define CIPHER_INIT twofish_counterinit
+#define CIPHER_ENCRYPT twofish_counterencrypt
+#define CIPHER_IVSZ TWOFISH_BLKSZ
+#define CIPHER_KEYSZ TWOFISH_KEYSZ
+
+#define HASH_CTX sha256_ctx
+#define HASH_INIT sha256_init
+#define HASH sha256_hash
+#define HASH_DONE sha256_done
+#define HASH_SZ SHA256_HASHSZ
 
 /*----- Static variables --------------------------------------------------*/
 
 static const grand_ops gops;
 
-typedef struct gctx {
+typedef struct rand__gctx {
   grand r;
   rand_pool p;
 } gctx;
 
-static gctx *pool = 0;                 /* Default random pool */
+gctx rand_global = {
+  { &gops },
+  { { 0 }, 0, 0, 0,
+    { 0 }, RAND_SECSZ, 0,
+    { "Catacomb global random byte pool" },
+    &noise_source }
+};
 
 /*----- Macros ------------------------------------------------------------*/
 
-#define RAND_RESOLVE(r) do {                                           \
-  if ((r) == RAND_GLOBAL) {                                            \
-    if (!pool)                                                         \
-      pool = (gctx *)rand_create();                                    \
-    (r) = &pool->p;                                                    \
-  }                                                                    \
-} while (0)
+#define RAND_RESOLVE(r)                                                        \
+  do { if ((r) == RAND_GLOBAL) r = &rand_global.p; } while (0)
 
 #define TIMER(r) do {                                                  \
   if ((r)->s && (r)->s->timer)                                         \
@@ -90,8 +107,8 @@ void rand_init(rand_pool *r)
   r->irot = 0;
   r->ibits = r->obits = 0;
   r->o = RAND_SECSZ;
-  r->s = 0;
-  rmd160_hmacinit(&r->k, 0, 0);
+  r->s = &noise_source;
+  rand_key(r, 0, 0);
   rand_gate(r);
 }
 
@@ -157,8 +174,18 @@ void rand_seed(rand_pool *r, unsigned bits)
 
 void rand_key(rand_pool *r, const void *k, size_t sz)
 {
+  HASH_CTX hc;
+  octet h[HASH_SZ];
+  static const char label[] = "Catacomb random pool key";
+
   RAND_RESOLVE(r);
-  rmd160_hmacinit(&r->k, k, sz);
+
+  assert(HASH_SZ >= RAND_KEYSZ);
+  HASH_INIT(&hc);
+  HASH(&hc, label, sizeof(label));
+  if (sz) HASH(&hc, k, sz);
+  HASH_DONE(&hc, h);
+  memcpy(r->k.k, h, RAND_KEYSZ);
 }
 
 /* --- @rand_add@ --- *
@@ -234,33 +261,28 @@ unsigned rand_goodbits(rand_pool *r)
 
 void rand_gate(rand_pool *r)
 {
-  octet mac[RMD160_HASHSZ];
+  octet h[HASH_SZ];
+  HASH_CTX hc;
+  CIPHER_CTX cc;
 
   RAND_RESOLVE(r);
   TIMER(r);
 
   /* --- Hash up all the data in the pool --- */
 
-  {
-    rmd160_macctx mc;
-
-    rmd160_macinit(&mc, &r->k);
-    rmd160_machash(&mc, r->pool, sizeof(r->pool));
-    rmd160_machash(&mc, r->buf, sizeof(r->buf));
-    rmd160_macdone(&mc, mac);
-    BURN(mc);
-  }
+  HASH_INIT(&hc);
+  HASH(&hc, r->pool, RAND_POOLSZ);
+  HASH(&hc, r->buf, RAND_BUFSZ);
+  HASH_DONE(&hc, h);
+  BURN(hc);
 
   /* --- Now mangle all of the data based on the hash --- */
 
-  {
-    blowfish_cbcctx bc;
-
-    blowfish_cbcinit(&bc, mac, sizeof(mac), 0);
-    blowfish_cbcencrypt(&bc, r->pool, r->pool, sizeof(r->pool));
-    blowfish_cbcencrypt(&bc, r->buf, r->buf, sizeof(r->buf));
-    BURN(bc);
-  }
+  assert(CIPHER_KEYSZ <= HASH_SZ);
+  CIPHER_INIT(&cc, h, CIPHER_KEYSZ, 0);
+  CIPHER_ENCRYPT(&cc, r->pool, r->pool, RAND_POOLSZ);
+  CIPHER_ENCRYPT(&cc, r->buf, r->buf, RAND_BUFSZ);
+  BURN(cc);
 
   /* --- Reset the various state variables --- */
 
@@ -288,32 +310,27 @@ void rand_gate(rand_pool *r)
 
 void rand_stretch(rand_pool *r)
 {
-  octet mac[RMD160_HASHSZ];
+  octet h[HASH_SZ];
+  HASH_CTX hc;
+  CIPHER_CTX cc;
 
   RAND_RESOLVE(r);
   TIMER(r);
 
   /* --- Hash up all the data in the buffer --- */
 
-  {
-    rmd160_macctx mc;
-
-    rmd160_macinit(&mc, &r->k);
-    rmd160_machash(&mc, r->pool, sizeof(r->pool));
-    rmd160_machash(&mc, r->buf, sizeof(r->buf));
-    rmd160_macdone(&mc, mac);
-    BURN(mc);
-  }
-
-  /* --- Now mangle the buffer based on that hash --- */
+  HASH_INIT(&hc);
+  HASH(&hc, r->pool, RAND_POOLSZ);
+  HASH(&hc, r->buf, RAND_BUFSZ);
+  HASH_DONE(&hc, h);
+  BURN(hc);
 
-  {
-    blowfish_cbcctx bc;
+  /* --- Now mangle the buffer based on the hash --- */
 
-    blowfish_cbcinit(&bc, mac, sizeof(mac), 0);
-    blowfish_cbcencrypt(&bc, r->buf, r->buf, sizeof(r->buf));
-    BURN(bc);
-  }
+  assert(CIPHER_KEYSZ < HASH_SZ);
+  CIPHER_INIT(&cc, h, CIPHER_KEYSZ, 0);
+  CIPHER_ENCRYPT(&cc, r->buf, r->buf, RAND_BUFSZ);
+  BURN(cc);
 
   /* --- Reset the various state variables --- */
 
@@ -421,21 +438,10 @@ void rand_getgood(rand_pool *r, void *p, size_t sz)
 
 /*----- Generic random number generator interface -------------------------*/
 
-#define GRESOLVE(g, r) do {                                            \
-  if (r != &rand_global)                                               \
-    g = (gctx *)r;                                                     \
-  else {                                                               \
-    if (!pool)                                                         \
-      pool = (gctx *)rand_create();                                    \
-    g = pool;                                                          \
-  }                                                                    \
-} while (0)
-
 static void gdestroy(grand *r)
 {
-  gctx *g;
-  GRESOLVE(g, r);
-  if (g != pool) {
+  gctx *g = (gctx *)r;
+  if (g != &rand_global) {
     BURN(*g);
     S_DESTROY(g);
   }
@@ -443,12 +449,11 @@ static void gdestroy(grand *r)
 
 static int gmisc(grand *r, unsigned op, ...)
 {
-  gctx *g;
+  gctx *g = (gctx *)r;
   va_list ap;
   int rc = 0;
   va_start(ap, op);
 
-  GRESOLVE(g, r);
   switch (op) {
     case GRAND_CHECK:
       switch (va_arg(ap, unsigned)) {
@@ -531,26 +536,23 @@ static int gmisc(grand *r, unsigned op, ...)
 
 static octet gbyte(grand *r)
 {
-  gctx *g;
+  gctx *g = (gctx *)r;
   octet o;
-  GRESOLVE(g, r);
   rand_getgood(&g->p, &o, 1);
   return (o);
 }
 
 static uint32 gword(grand *r)
 {
-  gctx *g;
+  gctx *g = (gctx *)r;
   octet b[4];
-  GRESOLVE(g, r);
   rand_getgood(&g->p, &b, sizeof(b));
   return (LOAD32(b));
 }
 
 static void gfill(grand *r, void *p, size_t sz)
 {
-  gctx *g;
-  GRESOLVE(g, r);
+  gctx *g = (gctx *)r;
   rand_get(&g->p, p, sz);
 }
 
@@ -561,8 +563,6 @@ static const grand_ops gops = {
   gword, gbyte, gword, grand_range, gfill
 };
 
-grand rand_global = { &gops };
-
 /* --- @rand_create@ --- *
  *
  * Arguments:  ---
index a024c0f..3c2fa73 100644 (file)
@@ -87,7 +87,8 @@
 
 #define RAND_POOLSZ 128                        /* Input pool size in bytes */
 #define RAND_BUFSZ 512                 /* Output buffer size in bytes */
-#define RAND_SECSZ 20                  /* Secret octets in output buffer */
+#define RAND_SECSZ 32                  /* Secret octets in output buffer */
+#define RAND_KEYSZ 32                  /* Recommended random key size */
 
 #define RAND_IBITS (RAND_POOLSZ * 8)
 #define RAND_OBITS (RAND_BUFSZ * 8)
@@ -104,7 +105,7 @@ typedef struct rand_pool {
   octet buf[RAND_BUFSZ];               /* Random octet output buffer */
   unsigned o;                          /* Current index into buffer */
   unsigned obits;                      /* Number of good bits in buffer */
-  rmd160_mackey k;                     /* Secret key for this pool */
+  union { octet k[RAND_KEYSZ]; rmd160_mackey _; } k; /* Key for the pool */
   const struct rand_source *s;         /* System-specific noise source */
 } rand_pool;
 
@@ -290,7 +291,11 @@ enum {
 
 /* --- Default random number generator --- */
 
-extern grand rand_global;
+#ifdef RAND__HACKS
+  extern struct rand__gctx rand_global;
+#else
+  extern grand rand_global;
+#endif
 
 /* --- @rand_create@ --- *
  *
index c4043d2..bd7710b 100644 (file)
@@ -46,13 +46,19 @@ EXTRA_DIST          += multigen
 ## we generate it using `multigen'.  Unfortunately, this needs to be done
 ## at the Automake level, which causes some interesting bootstrapping
 ## problems.
+##
+## Of course, now that we have this machinery for the complicated modes
+## generation, we might as well use it for simpler things.
 include modes.am
+include stubs.am
 
 EXTRA_DIST             += modes.am.in modes.am
+EXTRA_DIST             += stubs.am.in stubs.am
 MAINTAINERCLEANFILES   += $(srcdir)/modes.am
+MAINTAINERCLEANFILES   += $(srcdir)/stubs.am
 
 ## Generate the lists.
-$(srcdir)/modes.am: modes.am.in
+$(srcdir)/modes.am: modes.am.in Makefile.am
        $(AM_V_GEN)$(multigen) -g $(srcdir)/modes.am.in $(srcdir)/modes.am \
                blkc="$(BLKCS)" \
                        blkcmode="$(BLKCMODES)" \
@@ -61,12 +67,19 @@ $(srcdir)/modes.am: modes.am.in
                        hashmode="$(HASHMODES)" \
                        hashciphermode="$(HASHCIPHERMODES)" \
                        hashmacmode="$(HASHMACMODES)"
+$(srcdir)/stubs.am: stubs.am.in Makefile.am
+       $(AM_V_GEN)$(multigen) -g $(srcdir)/stubs.am.in $(srcdir)/stubs.am \
+               descr,hname,base="$(STUBS_HDR)" cname="$(STUBS_SRC)"
 
 ## Initialize lists of known classes.
 ALL_CIPHERS             = $(CIPHER_MODES)
 ALL_HASHES              = $(HASHES)
 ALL_MACS                = $(MAC_MODES)
 
+## Stub headers and sources.
+STUBS_HDR               =
+STUBS_SRC               =
+
 ###--------------------------------------------------------------------------
 ### Block ciphers.
 
@@ -191,6 +204,7 @@ BLKCS                       += safer safersk
 libsymm_la_SOURCES     += $(precomp)/safer-tab.c
 PRECOMPS               += $(precomp)/safer-tab.c
 PRECOMP_PROGS          += safer-mktab
+STUBS_HDR              += SAFER-SK,safersk,safer
 if !CROSS_COMPILING
 $(precomp)/safer-tab.c:
        $(AM_V_at)$(MKDIR_P) $(precomp)
@@ -297,6 +311,8 @@ HASHES                      += sha
 ## The National Security Agency's `SHA-2' suite.
 HASHES                 += sha224 sha256
 HASHES                 += sha384 sha512
+STUBS_HDR              += SHA-224,sha224,sha256
+STUBS_HDR              += SHA-384,sha384,sha512
 
 ## Anderson and Biham's `Tiger' hash function.
 HASHES                 += tiger
@@ -316,6 +332,7 @@ HASHES                      += whirlpool whirlpool256
 libsymm_la_SOURCES     += $(precomp)/whirlpool-tab.c
 PRECOMPS               += $(precomp)/whirlpool-tab.c
 PRECOMP_PROGS          += whirlpool-mktab
+STUBS_HDR              += Whirlpool-256,whirlpool256,whirlpool
 if !CROSS_COMPILING
 $(precomp)/whirlpool-tab.c:
        $(AM_V_at)$(MKDIR_P) $(precomp)
@@ -359,7 +376,7 @@ ALL_CIPHERS         += seal
 EXTRA_DIST             += mode.h.in mode.c.in
 EXTRA_DIST             += modes/gen-stamp
 MAINTAINERCLEANFILES   += modes/gen-stamp
-modes/gen-stamp:
+modes/gen-stamp: Makefile.am
        $(AM_V_at)$(MKDIR_P) $(srcdir)/modes
        $(AM_V_GEN)$(multigen) -g $(srcdir)/mode.c.in \
                $(srcdir)/modes/@base-@mode.c \
@@ -380,19 +397,38 @@ pkginclude_HEADERS        += $(MODE_H)
 
 ## Generated implementations.
 BUILT_SOURCES          += $(GENMODES_C)
-EXTRA_DIST             += $(GENMODES_C)
 MAINTAINERCLEANFILES   += $(GENMODES_C)
-nodist_libsymm_la_SOURCES += $(GENMODES_C)
+libsymm_la_SOURCES     += $(GENMODES_C)
 $(GENMODES_C): modes/gen-stamp
 
 ## Generated interfaces.
 BUILT_SOURCES          += $(GENMODES_H)
-EXTRA_DIST             += $(GENMODES_H)
 MAINTAINERCLEANFILES   += $(GENMODES_H)
-nodist_pkginclude_HEADERS += $(GENMODES_H)
+pkginclude_HEADERS     += $(GENMODES_H)
 $(GENMODES_H): modes/gen-stamp
 
 ###--------------------------------------------------------------------------
+### Autogenerated stub headers.
+
+## The master stamp file.
+EXTRA_DIST             += stub.h.in
+EXTRA_DIST             += stubs.gen-stamp
+MAINTAINERCLEANFILES   += stubs.gen-stamp
+stubs.gen-stamp: Makefile.am
+       $(AM_V_at)$(MKDIR_P) $(srcdir)/stubs
+       $(AM_V_GEN)$(multigen) -g $(srcdir)/stub.h.in \
+               $(srcdir)/@name.h descr,name,base="$(STUBS_HDR)"
+       $(AM_V_GEN)$(multigen) -g $(srcdir)/stub.c.in \
+               $(srcdir)/@name.c name="$(STUBS_SRC)"
+       $(AM_V_at)touch $(srcdir)/stubs.gen-stamp
+
+## Generated stub headers.
+BUILT_SOURCES          += $(STUB_H) $(STUB_C)
+MAINTAINERCLEANFILES   += $(STUB_H) $(STUB_C)
+pkginclude_HEADERS     += $(STUB_H)
+$(STUB_H) $(STUB_C): stubs.gen-stamp
+
+###--------------------------------------------------------------------------
 ### Tables of classes for encryption, hashing, and message authentication.
 
 ## The skeleton for the class tables.
@@ -402,7 +438,7 @@ EXTRA_DIST          += gthingtab.c.in
 pkginclude_HEADERS     += gcipher.h
 CLEANFILES             += gciphertab.c
 nodist_libsymm_la_SOURCES += gciphertab.c
-gciphertab.c: gthingtab.c.in
+gciphertab.c: gthingtab.c.in Makefile.am
        $(AM_V_GEN)$(multigen) -g $(srcdir)/gthingtab.c.in gciphertab.c \
                what=gcipher cls=gccipher thing="$(ALL_CIPHERS)"
 
@@ -410,7 +446,7 @@ gciphertab.c: gthingtab.c.in
 pkginclude_HEADERS     += ghash.h ghash-def.h
 CLEANFILES             += ghashtab.c
 nodist_libsymm_la_SOURCES += ghashtab.c
-ghashtab.c: gthingtab.c.in
+ghashtab.c: gthingtab.c.in Makefile.am
        $(AM_V_GEN)$(multigen) -g $(srcdir)/gthingtab.c.in ghashtab.c \
                what=ghash cls=gchash thing="$(ALL_HASHES)"
 
@@ -418,7 +454,7 @@ ghashtab.c: gthingtab.c.in
 pkginclude_HEADERS     += gmac.h
 CLEANFILES             += gmactab.c
 nodist_libsymm_la_SOURCES += gmactab.c
-gmactab.c: gthingtab.c.in
+gmactab.c: gthingtab.c.in Makefile.am
        $(AM_V_GEN)$(multigen) -g $(srcdir)/gthingtab.c.in gmactab.c \
                what=gmac cls=gcmac thing="$(ALL_MACS)"
 
index 4cbc88f..e9e52a7 100644 (file)
@@ -1,6 +1,6 @@
 %## -*-makefile-*-
 %#
-### -*-makefile-*- GENERATED from modes.make.in
+### -*-makefile-*- GENERATED from modes.am.in
 ###
 ### Lots of lists of crypto primitives in various modes of operation.
 
index f498ce2..241cd34 100755 (executable)
@@ -741,17 +741,21 @@ def compile_template(file, text):
 
 op = OP.OptionParser(
   description = 'Generates files by filling in simple templates',
-  usage = 'usage: %prog [-gl] FILE [COL,...=VAL,... ... | @FILE:COL,...] ...',
+  usage = 'usage: %prog {-l | -g TMPL} FILE [COL,...=VAL,... ... | @FILE:COL,...] ...',
   version = 'Catacomb version @VERSION@')
+def cb_gen(opt, optstr, arg, op):
+  op.values.input = arg
+  op.values.mode = 'gen'
 for short, long, kw in [
   ('-l', '--list', dict(
       action = 'store_const', const = 'list', dest = 'mode',
       help = 'list filenames generated')),
   ('-g', '--generate', dict(
-      action = 'store', metavar = 'PATH', dest = 'input',
-      help = 'generate output (default)'))]:
+      action = 'callback', metavar = 'TEMPLATE',
+      callback = cb_gen, type = 'string',
+      help = 'generate file(s) from TEMPLATE file'))]:
   op.add_option(short, long, **kw)
-op.set_defaults(mode = 'gen')
+op.set_defaults(mode = 'what?')
 opts, args = op.parse_args()
 
 if len(args) < 1: op.error('missing FILE')
@@ -787,6 +791,6 @@ elif opts.mode == 'gen':
       templ.subst(out, cs)
     OS.rename(new, file)
 else:
-  raise Exception, 'What am I doing here?'
+  die('What am I doing here?')
 
 ###----- That's all, folks --------------------------------------------------
index 303b76e..38f0097 100644 (file)
@@ -277,8 +277,8 @@ static const grand_ops grops = {
  *
  * Returns:    Pointer to generic random number generator interface.
  *
- * Use:                Creates a random number interface wrapper around an
- *             OFB-mode block cipher.
+ * Use:                Creates a random number interface wrapper around the RC4
+ *             stream cipher.
  */
 
 grand *rc4_rand(const void *k, size_t sz)
index caeeadb..1e34c50 100644 (file)
@@ -31,6 +31,9 @@
  * trade secret of RSA Data Security, Inc., but somehow source code for a
  * cipher which interworks with RC4 was posted to the Cypherpunks mailing
  * list.
+ *
+ * RC4 has some quite bad biases, and its use for cryptographic purposes is
+ * no longer recommended.
  */
 
 #ifndef CATACOMB_RC4_H
@@ -180,8 +183,8 @@ extern const gccipher rc4;
  *
  * Returns:    Pointer to generic random number generator interface.
  *
- * Use:                Creates a random number interface wrapper around an
- *             OFB-mode block cipher.
+ * Use:                Creates a random number interface wrapper around the RC4
+ *             stream cipher.
  */
 
 extern grand *rc4_rand(const void */*k*/, size_t /*sz*/);
index 8dd31cb..a75e614 100644 (file)
@@ -59,8 +59,8 @@ extern const octet safer_s[256], safer_si[256];
  *
  * Returns:    ---
  *
- * Use:                Initializes an SAFER expanded key.  A default number of
- *             rounds is chosen, based on the key length.
+ * Use:                Initializes an SAFER expanded key, with lots of options
+ *             controlling how to do it.
  */
 
 struct ksched {
@@ -252,7 +252,6 @@ void safersk_init(safer_ctx *k, const void *buf, size_t sz)
   KXS(k, a, b, c, d, e, f, g, h);                                      \
 } while (0)
 
-
 void safer_eblk(const safer_ctx *k, const uint32 *src, uint32 *dst)
 {
   octet a, b, c, d, e, f, g, h;
index 6186d96..1ed1f17 100644 (file)
@@ -85,8 +85,8 @@ typedef struct safer_ctx {
  *
  * Returns:    ---
  *
- * Use:                Initializes an SAFER expanded key.  A default number of
- *             rounds is chosen, based on the key length.
+ * Use:                Initializes an SAFER expanded key, with lots of options
+ *             controlling how to do it.
  */
 
 #define SAFER_SK 1u
index c9041ee..389b553 100644 (file)
@@ -1,13 +1,10 @@
 /* -*-c-*-
  *
- * Stub source for SAFER SK
- *
- * (c) 2001 Straylight/Edgeware
+ * Stub code for SAFER-SK
  */
 
 #include "blkc.h"
 #include "safersk.h"
 
-const char *safersk_magic = "Compile this useless file";
-
+typedef int uninteresting;
 BLKC_TEST(SAFERSK, safersk)
diff --git a/symm/safersk.h b/symm/safersk.h
deleted file mode 100644 (file)
index 7087432..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*-c-*-
- *
- * Stub header for SAFER SK
- *
- * (c) 2001 Straylight/Edgeware
- */
-
-#ifndef CATACOMB_SAFERSK_H
-#define CATACOMB_SAFERSK_H
-
-#include "safer.h"
-
-extern const char *safersk_magic;
-
-#endif
index da9d084..57cfc10 100644 (file)
@@ -413,8 +413,8 @@ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz)
 static void gsetiv(gcipher *c, const void *iv)
 {
   gctx *g = (gctx *)c;
-  uint32 n = *(const uint32 *)iv;
-  seal_initctx(&g->cc, &g->k, n);
+  const octet *ivp = iv;
+  seal_initctx(&g->cc, &g->k, LOAD32(ivp));
 }
 
 static void gdestroy(gcipher *c)
@@ -430,7 +430,7 @@ static const gcipher_ops gops = {
 };
 
 const gccipher seal = {
-  "seal", seal_keysz, 0,
+  "seal", seal_keysz, 4,
   ginit
 };
 
diff --git a/symm/sha224.h b/symm/sha224.h
deleted file mode 100644 (file)
index 3a49569..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*-c-*-
- *
- * Stub header for SHA-224
- */
-
-#ifndef CATACOMB_SHA224_H
-#define CATACOMB_SHA224_H
-
-#include "sha256.h"
-
-#endif
diff --git a/symm/sha384.h b/symm/sha384.h
deleted file mode 100644 (file)
index ed7731f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*-c-*-
- *
- * Stub header for SHA-384
- */
-
-#ifndef CATACOMB_SHA384_H
-#define CATACOMB_SHA384_H
-
-#include "sha512.h"
-
-#endif
diff --git a/symm/stub.c.in b/symm/stub.c.in
new file mode 100644 (file)
index 0000000..59721da
--- /dev/null
@@ -0,0 +1,6 @@
+%## -*-c-*-
+%##
+%## Skeleton stub source file.
+%#
+/* -*-c-*- */
+typedef int uninteresting;
diff --git a/symm/stub.h.in b/symm/stub.h.in
new file mode 100644 (file)
index 0000000..7253194
--- /dev/null
@@ -0,0 +1,15 @@
+%## -*-c-*-
+%##
+%## Skeleton stub header file.
+%#
+/* -*-c-*-
+ *
+ * Stub header for @{descr}
+ */
+
+#ifndef CATACOMB_@{name:u}_H
+#define CATACOMB_@{name:u}_H
+
+#include "@base.h"
+
+#endif
diff --git a/symm/stubs.am.in b/symm/stubs.am.in
new file mode 100644 (file)
index 0000000..104363e
--- /dev/null
@@ -0,0 +1,15 @@
+%## -*-makefile-*-
+%#
+### -*-makefile-*- GENERATED from stubs.am.in
+###
+### A list of the stub header files we have to make.
+
+STUB_H =
+%repeat
+STUB_H += @hname.h
+%end
+
+STUB_C =
+%repeat
+STUB_C += @cname.c
+%end
diff --git a/symm/whirlpool256.h b/symm/whirlpool256.h
deleted file mode 100644 (file)
index 8091d74..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*-c-*-
- *
- * Stub header for Whirlpool-256
- */
-
-#ifndef CATACOMB_WHIRLPOOL256_H
-#define CATACOMB_WHIRLPOOL256_H
-
-#include "whirlpool.h"
-
-#endif