X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/fc2d44af772db6c046820007555609c8352e101e..c90ce6bb395bac18afa5b189e4664151d4d8ea2c:/progs/cc-kem.c?ds=sidebyside diff --git a/progs/cc-kem.c b/progs/cc-kem.c index 71c89e47..1e99e05d 100644 --- a/progs/cc-kem.c +++ b/progs/cc-kem.c @@ -44,6 +44,7 @@ #include "dh.h" #include "rsa.h" #include "x25519.h" +#include "x448.h" #include "rmd160.h" #include "blowfish-cbc.h" @@ -603,70 +604,79 @@ static const kemops ec_decops = { ec_decinit, dh_decdoit, dh_enccheck, dh_encdestroy }; -/* --- X25519 --- */ - -static kem *x25519_encinit(key *k, void *kd) { return (CREATE(kem)); } -static void x25519_encdestroy(kem *k) { DESTROY(k); } - -static const char *x25519_enccheck(kem *k) -{ - x25519_pub *kd = k->kd; - - if (kd->pub.sz != X25519_PUBSZ) - return ("incorrect X25519 public key length"); - return (0); -} - -static int x25519_encdoit(kem *k, dstr *d, ghash *h) -{ - octet t[X25519_KEYSZ], z[X25519_OUTSZ]; - x25519_pub *kd = k->kd; - - rand_get(RAND_GLOBAL, t, sizeof(t)); - dstr_ensure(d, X25519_PUBSZ); - x25519((octet *)d->buf, t, x25519_base); - x25519(z, t, kd->pub.k); - d->len += X25519_PUBSZ; - GH_HASH(h, d->buf, X25519_PUBSZ); - GH_HASH(h, z, X25519_OUTSZ); - return (0); -} - -static const char *x25519_deccheck(kem *k) -{ - x25519_priv *kd = k->kd; - - if (kd->priv.sz != X25519_KEYSZ) - return ("incorrect X25519 private key length"); - if (kd->pub.sz != X25519_PUBSZ) - return ("incorrect X25519 public key length"); - return (0); -} - -static int x25519_decdoit(kem *k, dstr *d, ghash *h) -{ - octet z[X25519_OUTSZ]; - x25519_priv *kd = k->kd; - int rc = -1; - - if (d->len != X25519_PUBSZ) goto done; - x25519(z, kd->priv.k, (const octet *)d->buf); - GH_HASH(h, d->buf, X25519_PUBSZ); - GH_HASH(h, z, X25519_OUTSZ); - rc = 0; -done: - return (rc); -} - -static const kemops x25519_encops = { - x25519_pubfetch, sizeof(x25519_pub), - x25519_encinit, x25519_encdoit, x25519_enccheck, x25519_encdestroy -}; - -static const kemops x25519_decops = { - x25519_privfetch, sizeof(x25519_priv), - x25519_encinit, x25519_decdoit, x25519_deccheck, x25519_encdestroy -}; +/* --- X25519 and similar schemes --- */ + +#define XDHS(_) \ + _(x25519, X25519) \ + _(x448, X448) + +#define XDHDEF(xdh, XDH) \ + \ + static kem *xdh##_encinit(key *k, void *kd) { return (CREATE(kem)); } \ + static void xdh##_encdestroy(kem *k) { DESTROY(k); } \ + \ + static const char *xdh##_enccheck(kem *k) \ + { \ + xdh##_pub *kd = k->kd; \ + \ + if (kd->pub.sz != XDH##_PUBSZ) \ + return ("incorrect " #XDH "public key length"); \ + return (0); \ + } \ + \ + static int xdh##_encdoit(kem *k, dstr *d, ghash *h) \ + { \ + octet t[XDH##_KEYSZ], z[XDH##_OUTSZ]; \ + xdh##_pub *kd = k->kd; \ + \ + rand_get(RAND_GLOBAL, t, sizeof(t)); \ + dstr_ensure(d, XDH##_PUBSZ); \ + xdh((octet *)d->buf, t, xdh##_base); \ + xdh(z, t, kd->pub.k); \ + d->len += XDH##_PUBSZ; \ + GH_HASH(h, d->buf, XDH##_PUBSZ); \ + GH_HASH(h, z, XDH##_OUTSZ); \ + return (0); \ + } \ + \ + static const char *xdh##_deccheck(kem *k) \ + { \ + xdh##_priv *kd = k->kd; \ + \ + if (kd->priv.sz != XDH##_KEYSZ) \ + return ("incorrect " #XDH " private key length"); \ + if (kd->pub.sz != XDH##_PUBSZ) \ + return ("incorrect " #XDH " public key length"); \ + return (0); \ + } \ + \ + static int xdh##_decdoit(kem *k, dstr *d, ghash *h) \ + { \ + octet z[XDH##_OUTSZ]; \ + xdh##_priv *kd = k->kd; \ + int rc = -1; \ + \ + if (d->len != XDH##_PUBSZ) goto done; \ + xdh(z, kd->priv.k, (const octet *)d->buf); \ + GH_HASH(h, d->buf, XDH##_PUBSZ); \ + GH_HASH(h, z, XDH##_OUTSZ); \ + rc = 0; \ + done: \ + return (rc); \ + } \ + \ + static const kemops xdh##_encops = { \ + xdh##_pubfetch, sizeof(xdh##_pub), \ + xdh##_encinit, xdh##_encdoit, xdh##_enccheck, xdh##_encdestroy \ + }; \ + \ + static const kemops xdh##_decops = { \ + xdh##_privfetch, sizeof(xdh##_priv), \ + xdh##_encinit, xdh##_decdoit, xdh##_deccheck, xdh##_encdestroy \ + }; + +XDHS(XDHDEF) +#undef XDHDEF /* --- Symmetric --- */ @@ -736,7 +746,10 @@ const struct kemtab kemtab[] = { { "dh", &dh_encops, &dh_decops }, { "bindh", &bindh_encops, &bindh_decops }, { "ec", &ec_encops, &ec_decops }, - { "x25519", &x25519_encops, &x25519_decops }, +#define XDHTAB(xdh, XDH) \ + { #xdh, &xdh##_encops, &xdh##_decops }, + XDHS(XDHTAB) +#undef XDHTAB { "symm", &symm_encops, &symm_decops }, { 0, 0, 0 } }; @@ -847,16 +860,6 @@ k_found:; halg, t.buf); } - dstr_reset(&d); - if ((q = key_getattr(0, k, "kdf")) == 0) { - dstr_putf(&d, "%s-mgf", kk->hc->name); - q = d.buf; - } - if ((kk->cxc = gcipher_byname(q)) == 0) { - die(EXIT_FAILURE, "encryption scheme (KDF) `%s' not found in key `%s'", - q, t.buf); - } - if (!balg) bt = bulktab; else { @@ -874,6 +877,16 @@ k_found:; *bc = bo->init(k, balg, kk->hc->name); (*bc)->ops = bo; + dstr_reset(&d); + if ((q = key_getattr(0, k, "kdf")) == 0) { + dstr_putf(&d, "%s-mgf", kk->hc->name); + q = d.buf; + } + if ((kk->cxc = gcipher_byname(q)) == 0) { + die(EXIT_FAILURE, "encryption scheme (KDF) `%s' not found in key `%s'", + q, t.buf); + } + /* --- Tidy up --- */ dstr_destroy(&d);