X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..7b0d1a63587f3cb1ae3bb8b248bbb1b82bdca7bd:/progs/cc-sig.c diff --git a/progs/cc-sig.c b/progs/cc-sig.c index 35f17016..a416c6e5 100644 --- a/progs/cc-sig.c +++ b/progs/cc-sig.c @@ -36,13 +36,18 @@ #include "rand.h" #include "sha.h" #include "has160.h" +#include "sha512.h" +#include "sha3.h" +#include "ct.h" #include "ec.h" #include "ec-keys.h" #include "dh.h" #include "gdsa.h" #include "gkcdsa.h" #include "rsa.h" +#include "ed25519.h" +#include "ed448.h" #include "cc.h" @@ -182,11 +187,11 @@ static sig *rsapss_siginit(key *k, void *kd, const gchash *hc) { rsapss_sigctx *rs = CREATE(rsapss_sigctx); rsa_privcreate(&rs->rp, kd, &rand_global); + rs->s.h = 0; rs->p.r = &rand_global; rs->p.cc = getmgf(k, hc); rs->p.ch = hc; rs->p.ssz = hc->hashsz; - rsa_privdestroy(&rs->rp); return (&rs->s); } @@ -233,6 +238,7 @@ static sig *rsapss_vrfinit(key *k, void *kd, const gchash *hc) { rsapss_vrfctx *rv = CREATE(rsapss_vrfctx); rsa_pubcreate(&rv->rp, kd); + rv->s.h = 0; rv->p.r = &rand_global; rv->p.cc = getmgf(k, hc); rv->p.ch = hc; @@ -570,6 +576,93 @@ static const sigops eckcdsa_vrf = { eckcdsa_vrfinit, kcdsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy }; +/* --- EdDSA --- */ + +#define EDDSAS(_) \ + _(ed25519, ed25519ctx, ED25519, "Ed25519", sha512) \ + _(ed448, ed448, ED448, "Ed448", shake256) + +typedef struct eddsa_sigctx { + sig s; + const char *perso; +} eddsa_sigctx; + +static sig *eddsa_siginit(key *k, void *kd, const gchash *hc) +{ + eddsa_sigctx *es = CREATE(eddsa_sigctx); + es->s.h = 0; + es->perso = key_getattr(0, k, "perso"); + if (es->perso && strlen(es->perso) > ED25519_MAXPERSOSZ) { + die(1, "EdDSA personalization string too long (max length %d)", + ED25519_MAXPERSOSZ); + } + return (&es->s); +} + +static void eddsa_sigdestroy(sig *s) + { eddsa_sigctx *es = (eddsa_sigctx *)s; DESTROY(es); } + +#define EDDSADEF(ed, sigver, ED, name, hash) \ + \ + static int ed##_sigdoit(sig *s, dstr *d) \ + { \ + eddsa_sigctx *es = (eddsa_sigctx *)s; \ + ed##_priv *k = es->s.kd; \ + \ + dstr_ensure(d, ED##_SIGSZ); \ + sigver##_sign((octet *)d->buf, k->priv.k, k->priv.sz, k->pub.k, \ + es->perso ? 1 : -1, es->perso, \ + es->perso ? strlen(es->perso) : 0, \ + GH_DONE(es->s.h, 0), GH_CLASS(es->s.h)->hashsz); \ + d->len += ED##_SIGSZ; \ + return (0); \ + } \ + \ + static const char *ed##_sigcheck(sig *s) \ + { \ + eddsa_sigctx *es = (eddsa_sigctx *)s; \ + ed##_priv *k = es->s.kd; \ + \ + if (k->pub.sz != ED##_PUBSZ) \ + return ("incorrect " #name " public key length"); \ + return (0); \ + } \ + \ + static const sigops ed##_sig = { \ + ed##_privfetch, sizeof(ed##_priv), \ + eddsa_siginit, ed##_sigdoit, ed##_sigcheck, eddsa_sigdestroy \ + }; \ + \ + static int ed##_vrfdoit(sig *s, dstr *d) \ + { \ + eddsa_sigctx *es = (eddsa_sigctx *)s; \ + ed##_pub *k = es->s.kd; \ + \ + if (d->len != ED##_SIGSZ) return (-1); \ + return (sigver##_verify(k->pub.k, \ + es->perso ? 1 : -1, es->perso, \ + es->perso ? strlen(es->perso) : 0, \ + GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, \ + (const octet *)d->buf)); \ + } \ + \ + static const char *ed##_vrfcheck(sig *s) \ + { \ + ed##_pub *k = s->kd; \ + \ + if (k->pub.sz != ED##_PUBSZ) \ + return ("incorrect " #name " public key length"); \ + return (0); \ + } \ + \ + static const sigops ed##_vrf = { \ + ed##_pubfetch, sizeof(ed##_pub), \ + eddsa_siginit, ed##_vrfdoit, ed##_vrfcheck, eddsa_sigdestroy \ + }; + +EDDSAS(EDDSADEF) +#undef EDDSADEF + /* --- Symmetric message authentication --- */ typedef struct mac_ctx { @@ -633,7 +726,7 @@ static int mac_vrfdoit(sig *s, dstr *d) const octet *t; t = GH_DONE(m->s.h, 0); - if (d->len != m->mc->hashsz || memcmp(d->buf, t, d->len) != 0) + if (d->len != m->mc->hashsz || !ct_memeq(d->buf, t, d->len)) return (-1); return (0); } @@ -668,6 +761,10 @@ const struct sigtab sigtab[] = { { "kcdsa", &kcdsa_sig, &kcdsa_vrf, &has160 }, { "binkcdsa", &binkcdsa_sig, &binkcdsa_vrf, &has160 }, { "eckcdsa", &eckcdsa_sig, &eckcdsa_vrf, &has160 }, +#define EDDSATAB(ed, sigver, ED, name, hash) \ + { #ed, &ed##_sig, &ed##_vrf, &hash }, + EDDSAS(EDDSATAB) +#undef EDDSATAB { "mac", &mac_sig, &mac_vrf, &rmd160 }, { 0, 0, 0 } };