#include "dh.h"
#include "rsa.h"
#include "x25519.h"
+#include "x448.h"
#include "rmd160.h"
#include "blowfish-cbc.h"
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
+};
+
/* --- Symmetric --- */
typedef struct symm_ctx {
{ "bindh", &bindh_encops, &bindh_decops },
{ "ec", &ec_encops, &ec_decops },
{ "x25519", &x25519_encops, &x25519_decops },
+ { "x448", &x448_encops, &x448_decops },
{ "symm", &symm_encops, &symm_decops },
{ 0, 0, 0 }
};