From: Mark Wooding Date: Mon, 25 May 2015 17:59:52 +0000 (+0100) Subject: Merge branch 'mdw/fixes' X-Git-Tag: 2.2.0~7 X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/commitdiff_plain/16efb197c59c4b4cfaef7b2f23bd39f70176dd9e?hp=f6ca81030435df68a6af9ccd48265fce902ab099 Merge branch 'mdw/fixes' * 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. --- diff --git a/.gitignore b/.gitignore index 76030140..39e85652 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/build-setup b/build-setup index 77af12e8..ded8b110 100755 --- a/build-setup +++ b/build-setup @@ -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 diff --git a/math/mpint.c b/math/mpint.c index d89fb078..3511f1ee 100644 --- a/math/mpint.c +++ b/math/mpint.c @@ -33,21 +33,12 @@ /* --- 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 diff --git a/math/mpint.h b/math/mpint.h index e351b056..1b0a7623 100644 --- a/math/mpint.h +++ b/math/mpint.h @@ -145,6 +145,49 @@ /*----- 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 @@ -155,17 +198,9 @@ * 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 -------------------------------------------------*/ diff --git a/progs/rspit.c b/progs/rspit.c index b75c6f87..67913d54 100644 --- a/progs/rspit.c +++ b/progs/rspit.c @@ -40,6 +40,7 @@ #ifndef PORTABLE # include +# include #endif #include @@ -49,6 +50,11 @@ #include #include +#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]); diff --git a/rand/rand.c b/rand/rand.c index fa6dab86..ab00e893 100644 --- a/rand/rand.c +++ b/rand/rand.c @@ -35,32 +35,49 @@ #include #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: --- diff --git a/rand/rand.h b/rand/rand.h index a024c0f4..3c2fa738 100644 --- a/rand/rand.h +++ b/rand/rand.h @@ -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@ --- * * diff --git a/symm/Makefile.am b/symm/Makefile.am index c4043d22..bd7710b8 100644 --- a/symm/Makefile.am +++ b/symm/Makefile.am @@ -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)" diff --git a/symm/modes.am.in b/symm/modes.am.in index 4cbc88f2..e9e52a79 100644 --- a/symm/modes.am.in +++ b/symm/modes.am.in @@ -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. diff --git a/symm/multigen b/symm/multigen index f498ce2a..241cd34c 100755 --- a/symm/multigen +++ b/symm/multigen @@ -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 -------------------------------------------------- diff --git a/symm/rc4.c b/symm/rc4.c index 303b76ed..38f00973 100644 --- a/symm/rc4.c +++ b/symm/rc4.c @@ -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) diff --git a/symm/rc4.h b/symm/rc4.h index caeeadbd..1e34c508 100644 --- a/symm/rc4.h +++ b/symm/rc4.h @@ -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*/); diff --git a/symm/safer.c b/symm/safer.c index 8dd31cbf..a75e6147 100644 --- a/symm/safer.c +++ b/symm/safer.c @@ -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; diff --git a/symm/safer.h b/symm/safer.h index 6186d966..1ed1f17d 100644 --- a/symm/safer.h +++ b/symm/safer.h @@ -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 diff --git a/symm/safersk.c b/symm/safersk.c index c9041ee3..389b5536 100644 --- a/symm/safersk.c +++ b/symm/safersk.c @@ -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 index 7087432e..00000000 --- a/symm/safersk.h +++ /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 diff --git a/symm/seal.c b/symm/seal.c index da9d0843..57cfc10f 100644 --- a/symm/seal.c +++ b/symm/seal.c @@ -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 index 3a495693..00000000 --- a/symm/sha224.h +++ /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 index ed7731fe..00000000 --- a/symm/sha384.h +++ /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 index 00000000..59721da2 --- /dev/null +++ b/symm/stub.c.in @@ -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 index 00000000..72531948 --- /dev/null +++ b/symm/stub.h.in @@ -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 index 00000000..104363e2 --- /dev/null +++ b/symm/stubs.am.in @@ -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 index 8091d74e..00000000 --- a/symm/whirlpool256.h +++ /dev/null @@ -1,11 +0,0 @@ -/* -*-c-*- - * - * Stub header for Whirlpool-256 - */ - -#ifndef CATACOMB_WHIRLPOOL256_H -#define CATACOMB_WHIRLPOOL256_H - -#include "whirlpool.h" - -#endif