From 5c4c02314ca241c437b28f301658fee743323739 Mon Sep 17 00:00:00 2001 Message-Id: <5c4c02314ca241c437b28f301658fee743323739.1716878892.git.mdw@distorted.org.uk> From: Mark Wooding Date: Thu, 11 May 2017 10:42:15 +0100 Subject: [PATCH] pubkey.c: Support the `ed2559ctx' signature scheme from RFC8032. Organization: Straylight/Edgeware From: Mark Wooding Main difference is the addition of a personalization string. In the wrapper classes, forward unknown keyword arguments on to the underlying implementation. --- catacomb.c | 1 + catacomb/__init__.py | 8 ++++---- pubkey.c | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/catacomb.c b/catacomb.c index 9c83c9d..9e3b9cb 100644 --- a/catacomb.c +++ b/catacomb.c @@ -48,6 +48,7 @@ static const struct nameval consts[] = { C(X25519_KEYSZ), C(X25519_PUBSZ), C(X25519_OUTSZ), C(X448_KEYSZ), C(X448_PUBSZ), C(X448_OUTSZ), C(ED25519_KEYSZ), C(ED25519_PUBSZ), C(ED25519_SIGSZ), + C(ED25519_MAXPERSOSZ), #define ENTRY(tag, val, str) C(KERR_##tag), KEY_ERRORS(ENTRY) #undef ENTRY diff --git a/catacomb/__init__.py b/catacomb/__init__.py index b9818e7..4840eef 100644 --- a/catacomb/__init__.py +++ b/catacomb/__init__.py @@ -901,14 +901,14 @@ class _EdDSAPriv (_BasePriv, _EdDSAPub): class Ed25519Pub (_EdDSAPub): _PUBSZ = KeySZSet(ED25519_PUBSZ) _HASH = sha512 - def verify(me, msg, sig): - return ed25519_verify(me.pub, msg, sig) + def verify(me, msg, sig, **kw): + return ed25519_verify(me.pub, msg, sig, **kw) class Ed25519Priv (_EdDSAPriv, Ed25519Pub): _KEYSZ = KeySZAny(ED25519_KEYSZ) def _pubkey(me, priv): return ed25519_pubkey(priv) - def sign(me, msg): - return ed25519_sign(me.priv, msg, pub = me.pub) + def sign(me, msg, **kw): + return ed25519_sign(me.priv, msg, pub = me.pub, **kw) ###-------------------------------------------------------------------------- ### Built-in named curves and prime groups. diff --git a/pubkey.c b/pubkey.c index 642da3e..7374429 100644 --- a/pubkey.c +++ b/pubkey.c @@ -1164,9 +1164,9 @@ XDHS(DEFXDH) /*----- Ed25519 and related algorithms ------------------------------------*/ #define EDDSAS(_) \ - _(ED25519, ed25519) + _(ED25519, ed25519, -1, ctx) -#define DEFEDDSA(ED, ed) \ +#define DEFEDDSA(ED, ed, phdflt, sigver) \ \ static PyObject *meth_##ed##_pubkey(PyObject *me, PyObject *arg) \ { \ @@ -1185,21 +1185,26 @@ XDHS(DEFXDH) static PyObject *meth_##ed##_sign(PyObject *me, PyObject *arg, \ PyObject *kw) \ { \ - const char *k, *p = 0, *m; \ - Py_ssize_t ksz, psz, msz; \ + const char *k, *p = 0, *c = 0, *m; \ + Py_ssize_t ksz, psz, csz = 0, msz; \ + int ph = phdflt; \ PyObject *rc = 0; \ octet pp[ED##_PUBSZ]; \ - char *kwlist[] = { "key", "msg", "pub", 0 }; \ + char *kwlist[] = { "key", "msg", "pub", "perso", "phflag", 0 }; \ if (!PyArg_ParseTupleAndKeywords(arg, kw, \ - "s#s#|s#:" #ed "_sign", \ + "s#s#|s#s#O&:" #ed "_sign", \ kwlist, \ - &k, &ksz, &m, &msz, &p, &psz)) \ + &k, &ksz, &m, &msz, &p, &psz, \ + &c, &csz, convbool, &ph)) \ goto end; \ if (p && psz != ED##_PUBSZ) VALERR("bad public length"); \ + if (c && csz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c && ph == -1) ph = 0; \ if (!p) { p = (const char *)pp; ed##_pubkey(pp, k, ksz); } \ rc = bytestring_pywrap(0, ED##_SIGSZ); \ - ed##_sign((octet *)PyString_AS_STRING(rc), k, ksz, \ - (const octet *)p, m, msz); \ + ed##sigver##_sign((octet *)PyString_AS_STRING(rc), k, ksz, \ + (const octet *)p, ph, c, csz, m, msz); \ return (rc); \ end: \ return (0); \ @@ -1208,19 +1213,24 @@ XDHS(DEFXDH) static PyObject *meth_##ed##_verify(PyObject *me, \ PyObject *arg, PyObject *kw) \ { \ - const char *p, *m, *s; \ - Py_ssize_t psz, msz, ssz; \ + const char *p, *c = 0, *m, *s; \ + Py_ssize_t psz, csz = 0, msz, ssz; \ + int ph = phdflt; \ PyObject *rc = 0; \ - char *kwlist[] = { "pub", "msg", "sig", 0 }; \ + char *kwlist[] = { "pub", "msg", "sig", "perso", "phflag", 0 }; \ if (!PyArg_ParseTupleAndKeywords(arg, kw, \ - "s#s#s#:" #ed "_verify", \ + "s#s#s#|s#O&:" #ed "_verify", \ kwlist, \ - &p, &psz, &m, &msz, &s, &ssz)) \ + &p, &psz, &m, &msz, &s, &ssz, \ + &c, &csz, convbool, &ph)) \ goto end; \ if (psz != ED##_PUBSZ) VALERR("bad public length"); \ if (ssz != ED##_SIGSZ) VALERR("bad signature length"); \ - rc = getbool(!ed##_verify((const octet *)p, \ - m, msz, (const octet *)s)); \ + if (c && csz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c && ph == -1) ph = 0; \ + rc = getbool(!ed##sigver##_verify((const octet *)p, ph, c, csz, \ + m, msz, (const octet *)s)); \ return (rc); \ end: \ return (0); \ @@ -1247,7 +1257,7 @@ generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0]) -> R") " #x "(KEY, PUBLIC) -> SHARED") XDHS(DEFMETH) #undef DEFMETH -#define DEFMETH(ED, ed) \ +#define DEFMETH(ED, ed, phdflt, sigver) \ METH (ed##_pubkey, "\ " #ed "_pubkey(KEY) -> PUBLIC") \ KWMETH(ed##_sign, "\ -- [mdw]