/*----- Header files ------------------------------------------------------*/
+#define _FILE_OFFSET_BITS 64
+
#include "config.h"
#include <assert.h>
#include <mLib/darray.h>
#include <mLib/dstr.h>
+#include <mLib/macros.h>
#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include "salsa20.h"
#include "salsa20-core.h"
#include "seal.h"
+#include "sha3.h"
#include "des-ofb.h"
#include "des3-ofb.h"
#define CHACHA_NAME(r) "chacha" #r
#define XCHACHA_NAME(r) "xchacha" #r
-static struct {
+static const struct {
size_t noncesz;
grand *(*gen)(const void *, size_t, const void *);
} salsatab[] = {
#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;
case 'o':
if (flags & f_file)
die(EXIT_FAILURE, "already set an output file");
- if (strcmp(optarg, "-") == 0)
+ if (STRCMP(optarg, ==, "-"))
outfp = stdout;
else {
outfp = fopen(optarg, "w");
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)
"[-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,
g = 0;
for (gg = generators; gg->name; gg++) {
- if (strncmp(arg, gg->name, sz) == 0) {
+ if (STRNCMP(arg, ==, gg->name, sz)) {
if (gg->name[sz] == 0) {
g = gg;
break;