#include <stdlib.h>
+#include <mLib/macros.h>
#include <mLib/report.h>
#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"
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 {
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);
}
{ "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 }
};
if ((q = key_getattr(0, k, "sig")) != 0) {
dstr_puts(&d, q);
p = d.buf;
- } else if (strncmp(k->type, app, n) == 0 && k->type[n] == '-') {
+ } else if (STRNCMP(k->type, ==, app, n) && k->type[n] == '-') {
dstr_puts(&d, k->type);
p = d.buf + n + 1;
} else
/* --- Look up the algorithms in the table --- */
for (st = sigtab; st->name; st++) {
- if (strcmp(st->name, salg) == 0)
+ if (STRCMP(st->name, ==, salg))
goto s_found;
}
die(EXIT_FAILURE, "signature algorithm `%s' not found in key `%s'",