X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/16efb197c59c4b4cfaef7b2f23bd39f70176dd9e..7b0d1a63587f3cb1ae3bb8b248bbb1b82bdca7bd:/progs/rspit.c diff --git a/progs/rspit.c b/progs/rspit.c index 67913d54..66a05389 100644 --- a/progs/rspit.c +++ b/progs/rspit.c @@ -27,6 +27,8 @@ /*----- Header files ------------------------------------------------------*/ +#define _FILE_OFFSET_BITS 64 + #include "config.h" #include @@ -68,8 +70,12 @@ #include "bbs.h" #include "mprand.h" +#include "chacha.h" #include "rc4.h" +#include "salsa20.h" +#include "salsa20-core.h" #include "seal.h" +#include "sha3.h" #include "des-ofb.h" #include "des3-ofb.h" @@ -203,6 +209,62 @@ static const struct { #undef E }; +#define SALSAE \ + E(salsa20, 20,, SALSA20) \ + E(salsa20, 12,, SALSA20) \ + E(salsa20, 8,, SALSA20) \ + E(xsalsa20, 20, X, SALSA20) \ + E(xsalsa20, 12, X, SALSA20) \ + E(xsalsa20, 8, X, SALSA20) \ + E(chacha, 20,, CHACHA) \ + E(chacha, 12,, CHACHA) \ + E(chacha, 8,, CHACHA) \ + E(xchacha, 20, X, CHACHA) \ + E(xchacha, 12, X, CHACHA) \ + E(xchacha, 8, X, CHACHA) + +#define E(pre, r, x, BASE) pre##_##r##_INDEX, +enum { SALSAE BOGUS_SALSA }; +#undef E + +#define SALSA20_GEN(pre, r) SALSA20_DECOR(pre, r, _rand) +#define CHACHA_GEN(pre, r) pre##r##_rand + +#define SALSA20_NAME(r) SALSA20_NAME_##r +#define XSALSA20_NAME(r) "x" SALSA20_NAME_##r +#define CHACHA_NAME(r) "chacha" #r +#define XCHACHA_NAME(r) "xchacha" #r + +static const struct { + size_t noncesz; + grand *(*gen)(const void *, size_t, const void *); +} salsatab[] = { +#define E(pre, r, x, BASE) { x##BASE##_NONCESZ, BASE##_GEN(pre, r) }, + SALSAE +#undef E +}; + +#define SHAKES E(128) E(256) + +enum { +#define E(sz) SHAKE##sz##_INDEX, + SHAKES +#undef E + SHAKE__LIMIT +}; + +static const struct { + const octet *ksz; + grand *(*shake)(const void *, size_t, const void *, size_t, + const void *, size_t); + grand *(*kmac)(const void *, size_t, + const void *, size_t); +} shaketab[] = { +#define E(sz) { shake##sz##_keysz, cshake##sz##_rand, kmac##sz##_rand }, + SHAKES +#undef E +}; + /*----- Miscellaneous static data -----------------------------------------*/ static FILE *outfp; @@ -805,6 +867,75 @@ static grand *gen_seal(unsigned i) return (r); } +/* --- Salsa20, XSalsa20, ChaCha, and XChaCha --- */ + +static grand *gen_salsae(unsigned i) +{ + grand *r; + char *p; + dstr d = DSTR_INIT; + dstr n = DSTR_INIT; + kludge64 pos = { 0 }; + octet posbuf[8]; + mp *x; + + static struct option opts[] = { + { "key", OPTF_ARGREQ, 0, 'k' }, + { "hex", OPTF_ARGREQ, 0, 'H' }, + { "nonce", OPTF_ARGREQ, 0, 'n' }, + { "seek", OPTF_ARGREQ, 0, 's' }, + { 0, 0, 0, 0 } + }; + + addopts("k:H:n:s:", opts); + + for (;;) { + int o = opt(); + if (o < 0) + break; + switch (o) { + case 'k': + DRESET(&d); + textkey(&d, optarg, salsa20_keysz); + break; + case 'H': + DRESET(&d); + hexkey(&d, optarg, salsa20_keysz); + break; + case 'n': + DRESET(&n); + unhex(optarg, &p, &n); + if (*p) + die(EXIT_FAILURE, "bad hex IV `%s'", optarg); + if (n.len != salsatab[i].noncesz) { + die(EXIT_FAILURE, "bad nonce length %lu (must be %lu)", + (unsigned long)n.len, (unsigned long)salsatab[i].noncesz); + } + break; + case 's': + x = mp_readstring(MP_NEW, optarg, &p, 0); + if (*p || MP_NEGP(x) || mp_bits(x) > 64) + die(EXIT_FAILURE, "bad position `%s'", optarg); + mp_storeb(x, posbuf, sizeof(posbuf)); + mp_drop(x); + LOAD64_(pos, posbuf); + break; + default: + return (0); + } + } + + if (!d.len) + randkey(&d, salsa20_keysz); + r = salsatab[i].gen(d.buf, d.len, n.len ? n.buf : 0); + r->ops->misc(r, SALSA20_SEEKU64, pos); + + dstr_destroy(&d); + dstr_destroy(&n); + + return (r); +} + /* --- Output feedback generators --- */ static grand *gen_ofb(unsigned i) @@ -971,6 +1102,113 @@ static grand *gen_mgf(unsigned i) return (r); } +/* --- SHAKE generators --- */ + +static grand *gen_shake(unsigned i) +{ + dstr d = DSTR_INIT; + const char *func = 0, *perso = 0; + grand *r; + + static struct option opts[] = { + { "function", OPTF_ARGREQ, 0, 'F' }, + { "personalization", OPTF_ARGREQ, 0, 'P' }, + { "key", OPTF_ARGREQ, 0, 'k' }, + { "hex", OPTF_ARGREQ, 0, 'H' }, + { 0, 0, 0, 0 } + }; + + addopts("F:P:k:H:", opts); + + for (;;) { + int o = opt(); + if (o < 0) + break; + switch (o) { + case 'F': + func = optarg; + break; + case 'P': + perso = optarg; + break; + case 'k': + DRESET(&d); + textkey(&d, optarg, shaketab[i].ksz); + break; + case 'H': + DRESET(&d); + hexkey(&d, optarg, shaketab[i].ksz); + break; + default: + return (0); + } + } + + if (!d.len) randkey(&d, shaketab[i].ksz); + r = shaketab[i].shake(func, func ? strlen(func) : 0, + perso, perso ? strlen(perso) : 0, + d.buf, d.len); + dstr_destroy(&d); + return (r); +} + +/* --- KMAC generators --- */ + +static grand *gen_kmac(unsigned i) +{ + dstr d = DSTR_INIT, m = DSTR_INIT; + const char *perso = 0; + char *q; + grand *r; + + static struct option opts[] = { + { "personalization", OPTF_ARGREQ, 0, 'P' }, + { "key", OPTF_ARGREQ, 0, 'k' }, + { "hex", OPTF_ARGREQ, 0, 'H' }, + { "message", OPTF_ARGREQ, 0, 'M' }, + { "msghex", OPTF_ARGREQ, 0, 'N' }, + { 0, 0, 0, 0 } + }; + + addopts("P:k:H:M:N:", opts); + + for (;;) { + int o = opt(); + if (o < 0) + break; + switch (o) { + case 'P': + perso = optarg; + break; + case 'k': + DRESET(&d); + textkey(&d, optarg, shaketab[i].ksz); + break; + case 'H': + DRESET(&d); + hexkey(&d, optarg, shaketab[i].ksz); + break; + case 'M': + DRESET(&m); + DPUTS(&d, optarg); + break; + case 'N': + DRESET(&m); + unhex(optarg, &q, &m); + if (*q) die(EXIT_FAILURE, "bad hex"); + break; + default: + return (0); + } + } + + if (!d.len) randkey(&d, shaketab[i].ksz); + r = shaketab[i].kmac(perso, perso ? strlen(perso) : 0, d.buf, d.len); + r->ops->misc(r, GRAND_SEEDBLOCK, (void *)m.buf, m.len); + dstr_destroy(&d); dstr_destroy(&m); + return (r); +} + /* --- Fibonacci generator --- */ static grand *gen_fib(unsigned i) @@ -1077,6 +1315,21 @@ gen generators[] = { "[-k KEY-PHRASE] [-H HEX-KEY] [-i INDEX]" }, HASHES #undef E +#define E(pre, r, x, BASE) \ + { x##BASE##_NAME(r), gen_salsae, pre##_##r##_INDEX, \ + "[-k KEY-PHRASE] [-H HEX-KEY] [-n NONCE]" }, + SALSAE +#undef E +#define E(sz) \ + { "shake" #sz, gen_shake, SHAKE##sz##_INDEX, \ + "[-k KEY-PHRASE] [-H HEX-KEY]" }, + SHAKES +#undef E +#define E(sz) \ + { "kmac" #sz, gen_kmac, SHAKE##sz##_INDEX, \ + "[-k KEY-PHRASE] [-H HEX-KEY] [-m MSG]" }, + SHAKES +#undef E { "rc4", gen_rc4, 0, "[-k KEY-PHRASE] [-H HEX-KEY]" }, { "seal", gen_seal, 0,