X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/9c1437f372e62f0b3b3a7162aabee73bdc96ce4b..734a933080d78496fb41100a17815c4f21a41057:/progs/cc-kem.c diff --git a/progs/cc-kem.c b/progs/cc-kem.c index 5b0cbf79..cf53eaf1 100644 --- a/progs/cc-kem.c +++ b/progs/cc-kem.c @@ -604,135 +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 -}; - -/* --- X448 --- */ - -static kem *x448_encinit(key *k, void *kd) { return (CREATE(kem)); } -static void x448_encdestroy(kem *k) { DESTROY(k); } - -static const char *x448_enccheck(kem *k) -{ - x448_pub *kd = k->kd; - - if (kd->pub.sz != X448_PUBSZ) - return ("incorrect X448 public key length"); - return (0); -} - -static int x448_encdoit(kem *k, dstr *d, ghash *h) -{ - octet t[X448_KEYSZ], z[X448_OUTSZ]; - x448_pub *kd = k->kd; - - rand_get(RAND_GLOBAL, t, sizeof(t)); - dstr_ensure(d, X448_PUBSZ); - x448((octet *)d->buf, t, x448_base); - x448(z, t, kd->pub.k); - d->len += X448_PUBSZ; - GH_HASH(h, d->buf, X448_PUBSZ); - GH_HASH(h, z, X448_OUTSZ); - return (0); -} - -static const char *x448_deccheck(kem *k) -{ - x448_priv *kd = k->kd; - - if (kd->priv.sz != X448_KEYSZ) - return ("incorrect X448 private key length"); - if (kd->pub.sz != X448_PUBSZ) - return ("incorrect X448 public key length"); - return (0); -} - -static int x448_decdoit(kem *k, dstr *d, ghash *h) -{ - octet z[X448_OUTSZ]; - x448_priv *kd = k->kd; - int rc = -1; - - if (d->len != X448_PUBSZ) goto done; - x448(z, kd->priv.k, (const octet *)d->buf); - GH_HASH(h, d->buf, X448_PUBSZ); - GH_HASH(h, z, X448_OUTSZ); - rc = 0; -done: - return (rc); -} - -static const kemops x448_encops = { - x448_pubfetch, sizeof(x448_pub), - x448_encinit, x448_encdoit, x448_enccheck, x448_encdestroy -}; - -static const kemops x448_decops = { - x448_privfetch, sizeof(x448_priv), - x448_encinit, x448_decdoit, x448_deccheck, x448_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 --- */ @@ -802,8 +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 }, - { "x448", &x448_encops, &x448_decops }, +#define XDHTAB(xdh, XDH) \ + { #xdh, &xdh##_encops, &xdh##_decops }, + XDHS(XDHTAB) +#undef XDHTAB { "symm", &symm_encops, &symm_decops }, { 0, 0, 0 } };