+static void aead_decdestroy(bulk *b)
+{
+ aead_encctx *ctx = (aead_encctx *)b;
+ if (ctx->ed.dec) GAEAD_DESTROY(ctx->ed.dec);
+ aead_commondestroy(ctx);
+}
+
+static const struct bulkops aead_encops = {
+ aead_init, aead_encsetup, aead_overhead,
+ aead_encdoit, aead_encdestroy
+}, aead_decops = {
+ aead_init, aead_decsetup, aead_overhead,
+ aead_decdoit, aead_decdestroy
+};
+
+/* --- NaCl `secretbox' in terms of AEAD --- */
+
+static bulk *naclbox_init(key *k, const char *calg, const char *halg)
+{
+ const gcaead *aec;
+ dstr t = DSTR_INIT;
+ const char *q;
+
+ key_fulltag(k, &t);
+
+ if ((q = key_getattr(0, k, "cipher")) != 0) calg = q;
+ if (!calg || STRCMP(calg, ==, "salsa20")) aec = &salsa20_naclbox;
+ else if (STRCMP(calg, ==, "salsa20/12")) aec = &salsa2012_naclbox;
+ else if (STRCMP(calg, ==, "salsa20/8")) aec = &salsa208_naclbox;
+ else if (STRCMP(calg, ==, "chacha20")) aec = &chacha20_naclbox;
+ else if (STRCMP(calg, ==, "chacha12")) aec = &chacha12_naclbox;
+ else if (STRCMP(calg, ==, "chacha8")) aec = &chacha8_naclbox;
+ else {
+ die(EXIT_FAILURE,
+ "unknown or inappropriate encryption scheme `%s' in key `%s'",
+ calg, t.buf);
+ }
+
+ dstr_destroy(&t);
+ return (aead_internalinit(k, aec));
+}
+