debian/changelog: Prepare for next minor version.
[catacomb] / progs / cc-sig.c
index 7303c56..4c1defc 100644 (file)
 
 #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"
@@ -46,6 +48,7 @@
 #include "gkcdsa.h"
 #include "rsa.h"
 #include "ed25519.h"
+#include "ed448.h"
 
 #include "cc.h"
 
@@ -577,33 +580,49 @@ static const sigops eckcdsa_vrf = {
 /* --- EdDSA --- */
 
 #define EDDSAS(_)                                                      \
-  _(ed25519, ED25519, "Ed25519", sha512)
+  _(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)
 {
-  sig *s = CREATE(sig);
-  s->h = 0;
-  return (s);
+  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) { DESTROY(s); }
+static void eddsa_sigdestroy(sig *s)
+  { eddsa_sigctx *es = (eddsa_sigctx *)s; DESTROY(es); }
 
-#define EDDSADEF(ed, ED, name, hash)                                   \
+#define EDDSADEF(ed, sigver, ED, name, hash)                           \
                                                                        \
   static int ed##_sigdoit(sig *s, dstr *d)                             \
   {                                                                    \
-    ed##_priv *k = s->kd;                                              \
+    eddsa_sigctx *es = (eddsa_sigctx *)s;                              \
+    ed##_priv *k = es->s.kd;                                           \
                                                                        \
     dstr_ensure(d, ED##_SIGSZ);                                                \
-    ed##_sign((octet *)d->buf, k->priv.k, k->priv.sz, k->pub.k,                \
-             GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz);                \
+    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)                             \
   {                                                                    \
-    ed##_priv *k = s->kd;                                              \
+    eddsa_sigctx *es = (eddsa_sigctx *)s;                              \
+    ed##_priv *k = es->s.kd;                                           \
                                                                        \
     if (k->pub.sz != ED##_PUBSZ)                                       \
       return ("incorrect " #name " public key length");                        \
@@ -617,12 +636,15 @@ static void eddsa_sigdestroy(sig *s) { DESTROY(s); }
                                                                        \
   static int ed##_vrfdoit(sig *s, dstr *d)                             \
   {                                                                    \
-    ed##_pub *k = s->kd;                                               \
+    eddsa_sigctx *es = (eddsa_sigctx *)s;                              \
+    ed##_pub *k = es->s.kd;                                            \
                                                                        \
     if (d->len != ED##_SIGSZ) return (-1);                             \
-    return (ed##_verify(k->pub.k,                                      \
-                       GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz,       \
-                       (const octet *)d->buf));                        \
+    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)                             \
@@ -740,7 +762,7 @@ 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, ED, name, hash)                                   \
+#define EDDSATAB(ed, sigver, ED, name, hash)                           \
   { #ed,       &ed##_sig,      &ed##_vrf,      &hash },
   EDDSAS(EDDSATAB)
 #undef EDDSATAB
@@ -788,7 +810,7 @@ sig *getsig(key *k, const char *app, int wantpriv)
   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
@@ -811,7 +833,7 @@ sig *getsig(key *k, const char *app, int wantpriv)
   /* --- 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'",