#include <mLib/alloc.h>
#include <mLib/bits.h>
#include <mLib/dstr.h>
+#include <mLib/macros.h>
#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include "ed448.h"
#include "cc.h"
+#include "gaead.h"
#include "gcipher.h"
#include "ghash.h"
#include "gmac.h"
GC_ENCRYPT(c->c, c->m, c->m, c->sz);
}
+/* --- Authenticated encryption --- */
+
+typedef struct aeadsetup_ctx {
+ const gcaead *aec;
+ octet *k; size_t ksz;
+ octet *n; size_t nsz;
+ size_t tsz;
+} aeadsetup_ctx;
+
+static void *aeadsetup_init(opts *o)
+{
+ aeadsetup_ctx *c = CREATE(aeadsetup_ctx);
+ if (!o->name)
+ die(1, "must specify encryption scheme name");
+ if ((c->aec = gaead_byname(o->name)) == 0)
+ die(1, "aead scheme `%s' not known", o->name);
+ c->ksz = keysz(o->fbits/8, c->aec->keysz);
+ c->nsz = keysz_pad(o->gbits/8, c->aec->noncesz);
+ c->tsz = keysz(0, c->aec->tagsz);
+ if (o->fbits%8 || (o->fbits && c->ksz != o->fbits/8))
+ die(1, "bad key size %u for %s", o->fbits, o->name);
+ if (o->gbits%8 || (o->gbits && c->nsz != o->gbits/8))
+ die(1, "bad nonce size %u for %s", o->gbits, o->name);
+ c->k = xmalloc(c->ksz); rand_get(RAND_GLOBAL, c->k, c->ksz);
+ c->n = xmalloc(c->nsz); rand_get(RAND_GLOBAL, c->n, c->nsz);
+ return (c);
+}
+
+static void aeadsetup_run(void *cc)
+{
+ aeadsetup_ctx *c = cc;
+ gaead_key *k = GAEAD_KEY(c->aec, c->k, c->ksz);
+ gaead_enc *e = GAEAD_ENC(k, c->n, c->nsz, 0, 0, c->tsz);
+ GAEAD_DESTROY(e); GAEAD_DESTROY(k);
+}
+
+typedef struct aeadenc_ctx {
+ gaead_enc *enc;
+ octet *n; size_t nsz;
+ octet *p, *q; size_t sz; size_t nn;
+ size_t tsz;
+} aeadenc_ctx;
+
+static void *aeadenc_init(opts *o)
+{
+ aeadenc_ctx *c = CREATE(aeadenc_ctx);
+ const gcaead *aec;
+ gaead_key *key;
+ octet *k; size_t ksz;
+
+ if (!o->name)
+ die(1, "must specify encryption scheme name");
+ if ((aec = gaead_byname(o->name)) == 0)
+ die(1, "aead scheme `%s' not known", o->name);
+ c->sz = o->gbits ? o->gbits : 65536;
+ c->nn = o->n ? o->n : 16;
+ ksz = keysz(o->fbits/8, aec->keysz);
+ c->nsz = keysz(0, aec->noncesz);
+ c->tsz = keysz(0, aec->tagsz);
+ if (o->fbits%8 || (o->fbits && ksz != o->fbits/8))
+ die(1, "bad key size %u for %s", o->fbits, o->name);
+
+ k = xmalloc(ksz); rand_get(RAND_GLOBAL, k, ksz);
+ c->n = xmalloc(c->nsz); rand_get(RAND_GLOBAL, c->n, c->nsz);
+ c->p = xmalloc(c->sz); c->q = xmalloc(c->sz + aec->bufsz);
+
+ key = GAEAD_KEY(aec, k, ksz);
+ c->enc = GAEAD_ENC(key, c->n, c->nsz, 0, 0, c->tsz);
+ GAEAD_DESTROY(key); xfree(k);
+
+ o->opwhat = "byte"; o->sc = c->nn*c->sz;
+ return (c);
+}
+
+static void aeadaad_run(void *cc)
+{
+ aeadenc_ctx *c = cc;
+ gaead_aad *a;
+ size_t i;
+
+ GAEAD_REINIT(c->enc, c->n, c->nsz, c->nn*c->sz, 0, c->tsz);
+ a = GAEAD_AAD(c->enc);
+ for (i = 0; i < c->nn; i++) GAEAD_HASH(a, c->p, c->sz);
+ GAEAD_DESTROY(a);
+}
+
+static void aeadenc_run(void *cc)
+{
+ aeadenc_ctx *c = cc;
+ buf b;
+ size_t i;
+
+ GAEAD_REINIT(c->enc, c->n, c->nsz, 0, c->nn*c->sz, c->tsz);
+ for (i = 0; i < c->nn; i++) {
+ buf_init(&b, c->q, c->sz + c->enc->ops->c->bufsz);
+ GAEAD_ENCRYPT(c->enc, c->p, c->sz, &b);
+ }
+}
+
/* --- Hashing --- */
typedef struct hash_ctx {
{ "ed448-vrf", ed448_vrfinit, ed448_vrfrun },
{ "ksched", ksched_init, ksched_run },
{ "enc", enc_init, enc_run },
+ { "aead-setup", aeadsetup_init, aeadsetup_run },
+ { "aead-aad", aeadenc_init, aeadaad_run },
+ { "aead-enc", aeadenc_init, aeadenc_run },
{ "hash", hash_init, hash_run },
{ "poly1305", poly1305_jobinit, poly1305_jobrun },
{ 0, 0, 0 }
\n\
-C, --name=NAME Select curve/DH-group/enc/hash name.\n\
-b, --field-bits Field size for g-prime and rsa;\n\
- key bits for ksched and enc.\n\
+ key bits for ksched, enc, aead-setup, aead-enc.\n\
-q, --no-check Don't check field/group for validity.\n\
--B, --group-bits Group size for g-prime; data size for enc and hash.\n\
+-B, --group-bits Group size for g-prime; nonce bits for aead-setup;\n\
+ data size for enc, aead-aad, aead-enc, and hash.\n\
-n, --factors=COUNT Number of factors for {exp,mul}-sim;\n\
- inner iterations for enc and hash.\n\
+ inner iters for enc, aead-aad, aead-enc, hash.\n\
-i, --intervals=COUNT Number of intervals to run for. [0; forever]\n\
-k, --batch=COUNT Number of operations to batch between timer checks.\n\
-t, --time=TIME Length of an interval in seconds. [1]\n\
ptab[i].name, ptab[i].name) \
LI("Encryption algorithms", cipher, \
gciphertab[i], gciphertab[i]->name) \
+ LI("Authenticated encryption schemes", aead, \
+ gaeadtab[i], gaeadtab[i]->name) \
LI("Hash functions", hash, \
ghashtab[i], ghashtab[i]->name)
if (optind + 1 != argc) { usage(stderr); exit(1); }
for (j = jobtab; j->name; j++)
- if (strcmp(j->name, argv[optind]) == 0) break;
+ if (STRCMP(j->name, ==, argv[optind])) break;
if (!j->name) die(1, "unknown job type `%s'", argv[optind]);
p = j->init(&o);