progs/rspit.c: Include Salsa20 and ChaCha (and their variants).
authorMark Wooding <mdw@distorted.org.uk>
Mon, 22 Dec 2014 20:32:58 +0000 (20:32 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 3 Jul 2015 21:53:05 +0000 (22:53 +0100)
progs/rspit.c

index 67913d5..21d94bf 100644 (file)
 #include "bbs.h"
 #include "mprand.h"
 
+#include "chacha.h"
 #include "rc4.h"
+#include "salsa20.h"
+#include "salsa20-core.h"
 #include "seal.h"
 
 #include "des-ofb.h"
@@ -203,6 +206,41 @@ 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 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
+};
+
 /*----- Miscellaneous static data -----------------------------------------*/
 
 static FILE *outfp;
@@ -805,6 +843,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)
@@ -1077,6 +1184,11 @@ 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
   { "rc4",             gen_rc4,        0,
     "[-k KEY-PHRASE] [-H HEX-KEY]" },
   { "seal",            gen_seal,       0,