From 4a39374fa30569620d62fdb4ac12669c8e66affd Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 20 Aug 2019 14:19:21 +0100 Subject: [PATCH] progs/cc-kem.c: Reimplement the `naclbox' bulk cipher in terms of AEAD. --- progs/catcrypt.1 | 5 ++ progs/cc-kem.c | 144 ++++++++++++++----------------------------------------- 2 files changed, 40 insertions(+), 109 deletions(-) diff --git a/progs/catcrypt.1 b/progs/catcrypt.1 index 97367a52..d944bfab 100644 --- a/progs/catcrypt.1 +++ b/progs/catcrypt.1 @@ -286,6 +286,11 @@ or .BR chacha8 ; the default is .BR salsa20 . +Nowadays, this is equivalent to the +.B aead +transform, using +.IB cipher -naclbox +as the cipher. .PP As well as the KEM itself, a number of supporting algorithms are used. These are taken from appropriately named attributes on the key or, diff --git a/progs/cc-kem.c b/progs/cc-kem.c index 0942a2e5..9159ade7 100644 --- a/progs/cc-kem.c +++ b/progs/cc-kem.c @@ -58,115 +58,6 @@ /*----- Bulk crypto -------------------------------------------------------*/ -/* --- NaCl `secretbox' --- */ - -typedef struct naclbox_encctx { - bulk b; - const gccipher *cc; - gcipher *c; -} naclbox_encctx; - -static bulk *naclbox_init(key *k, const char *calg, const char *halg) -{ - naclbox_encctx *ctx = CREATE(naclbox_encctx); - 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") == 0) ctx->cc = &salsa20; - else if (strcmp(calg, "salsa20/12") == 0) ctx->cc = &salsa2012; - else if (strcmp(calg, "salsa20/8") == 0) ctx->cc = &salsa208; - else if (strcmp(calg, "chacha20") == 0) ctx->cc = &chacha20; - else if (strcmp(calg, "chacha12") == 0) ctx->cc = &chacha12; - else if (strcmp(calg, "chacha8") == 0) ctx->cc = &chacha8; - else { - die(EXIT_FAILURE, - "unknown or inappropriate encryption scheme `%s' in key `%s'", - calg, t.buf); - } - - dstr_destroy(&t); - return (&ctx->b); -} - -static int naclbox_setup(bulk *b, gcipher *cx) -{ - naclbox_encctx *ctx = (naclbox_encctx *)b; - octet k[SALSA20_KEYSZ]; - - GC_ENCRYPT(cx, 0, k, sizeof(k)); - ctx->c = GC_INIT(ctx->cc, k, sizeof(k)); - return (0); -} - -static size_t naclbox_overhead(bulk *b) { return (POLY1305_TAGSZ); } - -static void naclbox_destroy(bulk *b) -{ - naclbox_encctx *ctx = (naclbox_encctx *)b; - - GC_DESTROY(ctx->c); - DESTROY(ctx); -} - -static const char *naclbox_encdoit(bulk *b, uint32 seq, buf *bb, - const void *p, size_t sz) -{ - naclbox_encctx *ctx = (naclbox_encctx *)b; - octet t[32]; - poly1305_key ak; - poly1305_ctx a; - octet *tag, *ct; - - STORE32(t, seq); STORE32(t + 4, 0); GC_SETIV(ctx->c, t); - GC_ENCRYPT(ctx->c, 0, t, POLY1305_KEYSZ + POLY1305_MASKSZ); - poly1305_keyinit(&ak, t, POLY1305_KEYSZ); - poly1305_macinit(&a, &ak, t + POLY1305_KEYSZ); - - tag = buf_get(bb, POLY1305_TAGSZ); assert(tag); - ct = buf_get(bb, sz); assert(ct); - GC_ENCRYPT(ctx->c, p, ct, sz); - poly1305_hash(&a, ct, sz); - poly1305_done(&a, tag); - return (0); -} - -static const char *naclbox_decdoit(bulk *b, uint32 seq, buf *bb, - const void *p, size_t sz) -{ - naclbox_encctx *ctx = (naclbox_encctx *)b; - buf bin; - octet t[32]; - poly1305_key ak; - poly1305_ctx a; - octet *tag, *ct, *pt; - - STORE32(t, seq); STORE32(t + 4, 0); GC_SETIV(ctx->c, t); - GC_ENCRYPT(ctx->c, 0, t, POLY1305_KEYSZ + POLY1305_MASKSZ); - poly1305_keyinit(&ak, t, POLY1305_KEYSZ); - poly1305_macinit(&a, &ak, t + POLY1305_KEYSZ); - - buf_init(&bin, (/*unconst*/ void *)p, sz); - if ((tag = buf_get(&bin, POLY1305_TAGSZ)) == 0) return ("no tag"); - ct = BCUR(&bin); sz = BLEFT(&bin); - poly1305_hash(&a, ct, sz); - poly1305_done(&a, t); - if (!ct_memeq(t, tag, POLY1305_TAGSZ)) return ("authentication failure"); - pt = buf_get(bb, sz); assert(pt); - GC_DECRYPT(ctx->c, ct, pt, sz); - return (0); -} - -static const bulkops naclbox_encops = { - naclbox_init, naclbox_setup, naclbox_overhead, - naclbox_encdoit, naclbox_destroy -}, naclbox_decops = { - naclbox_init, naclbox_setup, naclbox_overhead, - naclbox_decdoit, naclbox_destroy -}; - /* --- Authenticated encryption schemes --- */ typedef struct aead_encctx { @@ -308,6 +199,41 @@ static const struct bulkops aead_encops = { 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") == 0) aec = &salsa20_naclbox; + else if (strcmp(calg, "salsa20/12") == 0) aec = &salsa2012_naclbox; + else if (strcmp(calg, "salsa20/8") == 0) aec = &salsa208_naclbox; + else if (strcmp(calg, "chacha20") == 0) aec = &chacha20_naclbox; + else if (strcmp(calg, "chacha12") == 0) aec = &chacha12_naclbox; + else if (strcmp(calg, "chacha8") == 0) 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)); +} + +static const bulkops naclbox_encops = { + naclbox_init, aead_encsetup, aead_overhead, + aead_encdoit, aead_encdestroy +}, naclbox_decops = { + naclbox_init, aead_decsetup, aead_overhead, + aead_decdoit, aead_decdestroy +}; + /* --- Generic composition --- */ typedef struct gencomp_encctx { -- 2.11.0