#include <mLib/sub.h>
#include "buf.h"
+#include "ct.h"
#include "rand.h"
#include "noise.h"
#include "mprand.h"
#include "key.h"
#include "cc.h"
+#include "gaead.h"
#include "ectab.h"
#include "ptab.h"
int en;
size_t n, chsz;
dstr d = DSTR_INIT;
- octet *tag, *ct;
buf b;
size_t seq;
char bb[65536];
key *k;
key *sk = 0;
kem *km;
+ bulk *bc;
sig *s = 0;
- gcipher *cx, *c;
- gmac *m;
- ghash *h;
const encops *eo;
enc *e;
ofp = stdout;
else if ((ofp = fopen(of, eo->wmode)) == 0) {
die(EXIT_FAILURE, "couldn't open file `%s' for output: %s",
- ofp, strerror(errno));
+ of, strerror(errno));
}
dstr_reset(&d);
key_fulltag(k, &d);
e = initenc(eo, ofp, "CATCRYPT ENCRYPTED MESSAGE");
- km = getkem(k, "cckem", 0);
+ km = getkem(k, "cckem", 0, &bc);
if (!(f & f_nocheck) && (err = km->ops->check(km)) != 0)
moan("key %s fails check: %s", d.buf, err);
if (sk) {
/* --- Build the KEM chunk --- */
dstr_reset(&d);
- if (setupkem(km, &d, &cx, &c, &m))
- die(EXIT_FAILURE, "failed to encapsulate key");
+ if (setupkem(km, &d, bc)) die(EXIT_FAILURE, "failed to encapsulate key");
buf_init(&b, d.buf, d.len);
BSTEP(&b, d.len);
if (s) GH_HASHBUF16(s->h, BBASE(&b), BLEN(&b));
/* --- Write the signature chunk --- */
if (s) {
- GC_ENCRYPT(cx, 0, bb, 1024);
+ GC_ENCRYPT(km->cx, 0, bb, 1024);
GH_HASH(s->h, bb, 1024);
dstr_reset(&d);
if ((en = s->ops->doit(s, &d)) != 0)
}
}
- assert(GC_CLASS(c)->blksz <= sizeof(bb));
- dstr_ensure(&d, sizeof(bb) + GM_CLASS(m)->hashsz);
+ n = bc->ops->overhead(bc);
+ dstr_ensure(&d, sizeof(bb) + n);
seq = 0;
- chsz = MASK16 - GM_CLASS(m)->hashsz;
- for (;;) {
- h = GM_INIT(m);
- GH_HASHU32(h, seq);
- seq++;
- if (GC_CLASS(c)->blksz) {
- GC_ENCRYPT(cx, 0, bb, GC_CLASS(c)->blksz);
- GC_SETIV(c, bb);
- }
+ chsz = MASK16 - n;
+ do {
n = fread(bb, 1, chsz, fp);
- if (!n) break;
if (f & f_progress) fprogress_update(&ff, n);
buf_init(&b, d.buf, d.sz);
- tag = buf_get(&b, GM_CLASS(m)->hashsz);
- ct = buf_get(&b, n);
- assert(tag); assert(ct);
- GC_ENCRYPT(c, bb, ct, n);
- GH_HASH(h, ct, n);
- GH_DONE(h, tag);
- GH_DESTROY(h);
+ if ((err = bc->ops->doit(bc, seq, &b, bb, n)) != 0) {
+ if (f & f_progress) fprogress_done(&ff);
+ die(EXIT_FAILURE, "failed to encrypt packet: %s\n", err);
+ }
+ seq++;
chunk_write(e, &b);
- }
-
- /* --- Final terminator packet --- */
-
- buf_init(&b, d.buf, d.sz);
- tag = buf_get(&b, GM_CLASS(m)->hashsz);
- assert(tag);
- GH_DONE(h, tag);
- GH_DESTROY(h);
- chunk_write(e, &b);
+ } while (n);
/* --- All done --- */
if (f & f_progress) fprogress_done(&ff);
e->ops->encdone(e);
- GM_DESTROY(m);
- GC_DESTROY(c);
- GC_DESTROY(cx);
+ bc->ops->destroy(bc);
freeenc(e);
if (s) freesig(s);
freekem(km);
int i;
size_t n;
dstr d = DSTR_INIT;
+ char bb[65536];
buf b;
key_file kf;
size_t seq;
key *sk = 0;
kem *km;
sig *s = 0;
- gcipher *cx;
- gcipher *c;
- ghash *h;
- gmac *m;
- octet *tag;
+ bulk *bc;
unsigned f = 0;
const encops *eo;
const char *err;
/* --- Find the key --- */
- km = getkem(k, "cckem", 1);
+ km = getkem(k, "cckem", 1, &bc);
/* --- Read the KEM chunk --- */
chunk_read(e, &d, &b);
if (f & f_progress)
fprogress_update(&ff, BLEFT(&b)*e->ops->ncook/e->ops->nraw);
- if (setupkem(km, &d, &cx, &c, &m)) {
+ if (setupkem(km, &d, bc)) {
if (f & f_progress) fprogress_done(&ff);
if (verb) printf("FAIL failed to decapsulate key\n");
exit(EXIT_FAILURE);
if (sk) {
dstr_reset(&d);
dstr_ensure(&d, 1024);
- GC_ENCRYPT(cx, 0, d.buf, 1024);
+ GC_ENCRYPT(km->cx, 0, d.buf, 1024);
GH_HASH(s->h, d.buf, 1024);
chunk_read(e, &d, &b);
if (f & f_progress)
if ((ofp = fopen(of, "wb")) == 0) {
if (f & f_progress) fprogress_done(&ff);
die(EXIT_FAILURE, "couldn't open file `%s' for output: %s",
- ofp, strerror(errno));
+ of, strerror(errno));
}
rfp = ofp;
} else if ((rfp = tmpfile()) == 0) {
}
seq = 0;
- dstr_ensure(&d, GC_CLASS(c)->blksz);
+ dstr_ensure(&d, bc->ops->overhead(bc));
dstr_ensure(&d, 4);
for (;;) {
- if (GC_CLASS(c)->blksz) {
- GC_ENCRYPT(cx, 0, d.buf, GC_CLASS(c)->blksz);
- GC_SETIV(c, d.buf);
- }
- h = GM_INIT(m);
- GH_HASHU32(h, seq);
- seq++;
chunk_read(e, &d, &b);
if (f & f_progress)
fprogress_update(&ff, BLEFT(&b)*e->ops->ncook/e->ops->nraw);
- if ((tag = buf_get(&b, GM_CLASS(m)->hashsz)) == 0) {
+ buf_init(&b, bb, sizeof(bb));
+ if ((err = bc->ops->doit(bc, seq, &b, d.buf, d.len)) != 0) {
if (f & f_progress) fprogress_done(&ff);
- if (verb) printf("FAIL bad ciphertext chunk: no tag\n");
+ if (verb) printf("FAIL bad ciphertext chunk: %s\n", err);
exit(EXIT_FAILURE);
}
- GH_HASH(h, BCUR(&b), BLEFT(&b));
- if (memcmp(tag, GH_DONE(h, 0), GM_CLASS(m)->hashsz) != 0) {
- if (f & f_progress) fprogress_done(&ff);
- if (verb)
- printf("FAIL bad ciphertext chunk: authentication failure\n");
- exit(EXIT_FAILURE);
- }
- GH_DESTROY(h);
- if (!BLEFT(&b))
- break;
- GC_DECRYPT(c, BCUR(&b), BCUR(&b), BLEFT(&b));
- if (fwrite(BCUR(&b), 1, BLEFT(&b), rfp) != BLEFT(&b)) {
+ seq++;
+ if (!BLEN(&b)) break;
+ if (fwrite(BBASE(&b), 1, BLEN(&b), rfp) != BLEN(&b)) {
if (f & f_progress) fprogress_done(&ff);
if (verb) printf("FAIL error writing output: %s\n", strerror(errno));
exit(EXIT_FAILURE);
printf("OK decrypted successfully\n");
if (ofp && (fflush(ofp) || ferror(ofp) || fclose(ofp)))
die(EXIT_FAILURE, "error writing output: %s", strerror(errno));
+ bc->ops->destroy(bc);
freeenc(e);
- GC_DESTROY(c);
- GC_DESTROY(cx);
- GM_DESTROY(m);
freekem(km);
if (fp != stdin) fclose(fp);
key_close(&kf);
listtab[i].name, listtab[i].name) \
LI("Key-encapsulation mechanisms", kem, \
kemtab[i].name, kemtab[i].name) \
+ LI("Bulk crypto transforms", bulk, \
+ bulktab[i].name, bulktab[i].name) \
LI("Signature schemes", sig, \
sigtab[i].name, sigtab[i].name) \
LI("Encodings", enc, \
enctab[i].name, enctab[i].name) \
LI("Symmetric 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) \
LI("Message authentication codes", mac, \