X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/4abb54de656f0d5c1b35de940fe75e7e3159dee4..8d2f989633404555a54fe35799412f2cd4cc82ee:/algorithms.c diff --git a/algorithms.c b/algorithms.c index d73981e..886c159 100644 --- a/algorithms.c +++ b/algorithms.c @@ -27,13 +27,33 @@ /*----- Header files ------------------------------------------------------*/ #include "catacomb-python.h" +PUBLIC_SYMBOLS; #include "algorithms.h" +PRIVATE_SYMBOLS; /*----- Key sizes ---------------------------------------------------------*/ -PyTypeObject *keysz_pytype; -PyTypeObject *keyszany_pytype, *keyszrange_pytype, *keyszset_pytype; -PyObject *sha_pyobj, *has160_pyobj; +static PyTypeObject *keysz_pytype; +static PyTypeObject *keyszany_pytype, *keyszrange_pytype, *keyszset_pytype; + +typedef struct keysz_pyobj { + PyObject_HEAD + int dfl; +} keysz_pyobj; + +typedef struct keyszrange_pyobj { + PyObject_HEAD + int dfl; + int min, max, mod; +} keyszrange_pyobj; + +typedef struct keyszset_pyobj { + PyObject_HEAD + int dfl; + PyObject *set; +} keyszset_pyobj; + +#define KEYSZ_PYCHECK(o) PyObject_TypeCheck((o), keysz_pytype) #ifndef KSZ_OPMASK # define KSZ_OPMASK 0x1f @@ -135,9 +155,8 @@ static PyObject *keyszset_pynew(PyTypeObject *ty, if (!set) set = PyTuple_New(0); else Py_INCREF(set); if (!PySequence_Check(set)) TYERR("want a sequence"); - n = PySequence_Size(set); - l = PyList_New(0); - if (PyErr_Occurred()) goto end; + n = PySequence_Size(set); if (n < 0) goto end; + l = PyList_New(0); if (!l) goto end; if (dfl < 0) VALERR("key size cannot be negative"); x = PyInt_FromLong(dfl); PyList_Append(l, x); @@ -174,9 +193,9 @@ static PyObject *ksget_min(PyObject *me, void *hunoz) { PyObject *set = ((keyszset_pyobj *)me)->set; int i, n, y, x = -1; - n = PyTuple_Size(set); + n = PyTuple_GET_SIZE(set); for (i = 0; i < n; i++) { - y = PyInt_AsLong(PyTuple_GetItem(set, i)); + y = PyInt_AS_LONG(PyTuple_GET_ITEM(set, i)); if (x == -1 || y < x) x = y; } return (PyInt_FromLong(x)); @@ -186,9 +205,9 @@ static PyObject *ksget_max(PyObject *me, void *hunoz) { PyObject *set = ((keyszset_pyobj *)me)->set; int i, n, y, x = -1; - n = PyTuple_Size(set); + n = PyTuple_GET_SIZE(set); for (i = 0; i < n; i++) { - y = PyInt_AsLong(PyTuple_GetItem(set, i)); + y = PyInt_AS_LONG(PyTuple_GET_ITEM(set, i)); if (y > x) x = y; } return (PyInt_FromLong(x)); @@ -206,7 +225,7 @@ static PyMemberDef keysz_pymembers[] = { static PyGetSetDef keyszany_pygetset[] = { #define GETSETNAME(op, name) ka##op##_##name GET (min, "KSZ.min -> smallest allowed key size") - GET (max, "KSZ.min -> largest allowed key size") + GET (max, "KSZ.max -> largest allowed key size") #undef GETSETNAME { 0 } }; @@ -214,7 +233,7 @@ static PyGetSetDef keyszany_pygetset[] = { static PyMemberDef keyszrange_pymembers[] = { #define MEMBERSTRUCT keyszrange_pyobj MEMBER(min, T_INT, READONLY, "KSZ.min -> smallest allowed key size") - MEMBER(max, T_INT, READONLY, "KSZ.min -> largest allowed key size") + MEMBER(max, T_INT, READONLY, "KSZ.max -> largest allowed key size") MEMBER(mod, T_INT, READONLY, "KSZ.mod -> key size must be a multiple of this") #undef MEMBERSTRUCT @@ -224,7 +243,7 @@ static PyMemberDef keyszrange_pymembers[] = { static PyGetSetDef keyszset_pygetset[] = { #define GETSETNAME(op, name) ks##op##_##name GET (min, "KSZ.min -> smallest allowed key size") - GET (max, "KSZ.min -> largest allowed key size") + GET (max, "KSZ.max -> largest allowed key size") #undef GETSETNAME { 0 } }; @@ -452,12 +471,27 @@ KSZCONVOP(toec) /*----- Symmetric encryption ----------------------------------------------*/ -PyTypeObject *gccipher_pytype, *gcipher_pytype; +static PyTypeObject *gccipher_pytype, *gcipher_pytype; + +typedef struct gccipher_pyobj { + PyHeapTypeObject ty; + gccipher *cc; +} gccipher_pyobj; + +#define GCCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gccipher_pytype) +#define GCCIPHER_CC(o) (((gccipher_pyobj *)(o))->cc) + +typedef struct gcipher_pyobj { + PyObject_HEAD + gcipher *c; +} gcipher_pyobj; + +#define GCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gcipher_pytype) +#define GCIPHER_C(o) (((gcipher_pyobj *)(o))->c) CONVFUNC(gccipher, gccipher *, GCCIPHER_CC) -CONVFUNC(gcipher, gcipher *, GCIPHER_C) -PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c) +static PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c) { gcipher_pyobj *g; if (!cobj) cobj = gccipher_pywrap((/*unconst*/ gccipher *)GC_CLASS(c)); @@ -712,15 +746,111 @@ static PyTypeObject gcipher_pytype_skel = { /*----- Authenticated encryption ------------------------------------------*/ -PyTypeObject *gcaead_pytype, *gaeadkey_pytype; -PyTypeObject *gcaeadaad_pytype, *gaeadaad_pytype; -PyTypeObject *gcaeadenc_pytype, *gaeadenc_pytype; -PyTypeObject *gcaeaddec_pytype, *gaeaddec_pytype; +static PyTypeObject *gcaead_pytype, *gaeadkey_pytype; +static PyTypeObject *gcaeadaad_pytype, *gaeadaad_pytype; +static PyTypeObject *gcaeadenc_pytype, *gaeadenc_pytype; +static PyTypeObject *gcaeaddec_pytype, *gaeaddec_pytype; + +typedef struct gcaead_pyobj { + PyHeapTypeObject ty; + gcaead *aec; + struct gcaeadaad_pyobj *aad; + struct gcaeadenc_pyobj *enc; + struct gcaeaddec_pyobj *dec; +} gcaead_pyobj; + +#define GCAEAD_PYCHECK(o) PyObject_TypeCheck((o), gcaead_pytype) +#define GCAEAD_AEC(o) (((gcaead_pyobj *)(o))->aec) +#define GCAEAD_AAD(o) (((gcaead_pyobj *)(o))->aad) +#define GCAEAD_ENC(o) (((gcaead_pyobj *)(o))->enc) +#define GCAEAD_DEC(o) (((gcaead_pyobj *)(o))->dec) +static PyObject *gcaead_pywrap(gcaead *); + +typedef struct gaeadkey_pyobj { + PyObject_HEAD + gaead_key *k; +} gaeadkey_pyobj; + +#define GAEADKEY_PYCHECK(o) PyObject_TypeCheck((o), gaeadkey_pytype) +#define GAEADKEY_K(o) (((gaeadkey_pyobj *)(o))->k) + +typedef struct gcaeadaad_pyobj { + PyHeapTypeObject ty; + gcaead_pyobj *key; +} gcaeadaad_pyobj; + +#define GCAEADAAD_KEY(o) (((gcaeadaad_pyobj *)(o))->key) +static PyObject *gaeadaad_pywrap(PyObject *, gaead_aad *, unsigned, size_t); -CONVFUNC(gcaead, gcaead *, GCAEAD_AEC) -CONVFUNC(gaeadkey, gaead_key *, GAEADKEY_K) +typedef struct gaeadaad_pyobj { + PyObject_HEAD + gaead_aad *a; + unsigned f; +#define AEADF_DEAD 32768u + size_t hsz, hlen; +} gaeadaad_pyobj; + +#define GAEADAAD_PYCHECK(o) PyObject_TypeCheck((o), gaeadaad_pytype) +#define GAEADAAD_A(o) (((gaeadaad_pyobj *)(o))->a) +#define GAEADAAD_F(o) (((gaeadaad_pyobj *)(o))->f) +#define GAEADAAD_HSZ(o) (((gaeadaad_pyobj *)(o))->hsz) +#define GAEADAAD_HLEN(o) (((gaeadaad_pyobj *)(o))->hlen) + +typedef struct gcaeadenc_pyobj { + PyHeapTypeObject ty; + gcaead_pyobj *key; +} gcaeadenc_pyobj; -PyObject *gaeadkey_pywrap(PyObject *cobj, gaead_key *k) +#define GCAEADENC_KEY(o) (((gcaeadenc_pyobj *)(o))->key) +static PyObject *gaeadenc_pywrap(PyObject *, gaead_enc *, unsigned, + size_t, size_t, size_t); + +typedef struct gaeadenc_pyobj { + PyObject_HEAD + gaead_enc *e; + gaeadaad_pyobj *aad; + unsigned f; + size_t hsz, msz, tsz; + size_t mlen; +} gaeadenc_pyobj; + +#define GAEADENC_PYCHECK(o) PyObject_TypeCheck((o), gaeadenc_pytype) +#define GAEADENC_AAD(o) (((gaeadenc_pyobj *)(o))->aad) +#define GAEADENC_E(o) (((gaeadenc_pyobj *)(o))->e) +#define GAEADENC_F(o) (((gaeadenc_pyobj *)(o))->f) +#define GAEADENC_HSZ(o) (((gaeadenc_pyobj *)(o))->hsz) +#define GAEADENC_MSZ(o) (((gaeadenc_pyobj *)(o))->msz) +#define GAEADENC_TSZ(o) (((gaeadenc_pyobj *)(o))->tsz) +#define GAEADENC_MLEN(o) (((gaeadenc_pyobj *)(o))->mlen) + +typedef struct gcaeaddec_pyobj { + PyHeapTypeObject ty; + gcaead_pyobj *key; +} gcaeaddec_pyobj; + +#define GCAEADDEC_KEY(o) (((gcaeaddec_pyobj *)(o))->key) +static PyObject *gaeaddec_pywrap(PyObject *, gaead_dec *, unsigned, + size_t, size_t, size_t); + +typedef struct gaeaddec_pyobj { + PyObject_HEAD + gaead_dec *d; + gaeadaad_pyobj *aad; + unsigned f; + size_t hsz, csz, tsz; + size_t clen; +} gaeaddec_pyobj; + +#define GAEADDEC_PYCHECK(o) PyObject_TypeCheck((o), gaeaddec_pytype) +#define GAEADDEC_AAD(o) (((gaeaddec_pyobj *)(o))->aad) +#define GAEADDEC_D(o) (((gaeaddec_pyobj *)(o))->d) +#define GAEADDEC_F(o) (((gaeaddec_pyobj *)(o))->f) +#define GAEADDEC_HSZ(o) (((gaeaddec_pyobj *)(o))->hsz) +#define GAEADDEC_CSZ(o) (((gaeaddec_pyobj *)(o))->csz) +#define GAEADDEC_TSZ(o) (((gaeaddec_pyobj *)(o))->tsz) +#define GAEADDEC_CLEN(o) (((gaeaddec_pyobj *)(o))->clen) + +static PyObject *gaeadkey_pywrap(PyObject *cobj, gaead_key *k) { gaeadkey_pyobj *gk; @@ -747,7 +877,7 @@ end: return (0); } -PyObject *gcaead_pywrap(gcaead *aec) +static PyObject *gcaead_pywrap(gcaead *aec) { gcaead_pyobj *gck; gcaeadaad_pyobj *gca; @@ -921,8 +1051,8 @@ static PyMethodDef gaeadkey_pymethods[] = { { 0 } }; -PyObject *gaeadaad_pywrap(PyObject *cobj, gaead_aad *a, - unsigned f, size_t hsz) +static PyObject *gaeadaad_pywrap(PyObject *cobj, gaead_aad *a, + unsigned f, size_t hsz) { gaeadaad_pyobj *ga; @@ -988,6 +1118,7 @@ static PyObject *gaeameth_copy(PyObject *me, PyObject *arg) VALERR("can't duplicate nonce-dependent aad"); rc = gaeadaad_pywrap((PyObject *)me->ob_type, GAEAD_DUP(GAEADAAD_A(me)), 0, 0); + GAEADAAD_HLEN(rc) = GAEADAAD_HLEN(me); end: return (rc); } @@ -1065,8 +1196,8 @@ static PyMethodDef gaeadaad_pymethods[] = { { 0 } }; -PyObject *gaeadenc_pywrap(PyObject *cobj, gaead_enc *e, unsigned f, - size_t hsz, size_t msz, size_t tsz) +static PyObject *gaeadenc_pywrap(PyObject *cobj, gaead_enc *e, unsigned f, + size_t hsz, size_t msz, size_t tsz) { gaeadenc_pyobj *ge; @@ -1131,7 +1262,8 @@ static PyObject *gaeemeth_aad(PyObject *me, PyObject *arg) if (!ge->aad) ge->aad = (gaeadaad_pyobj *) gaeadaad_pywrap((PyObject *)GCAEADENC_KEY(ge->ob_type)->aad, - GAEAD_AAD(ge->e), ge->f&AEADF_PCHSZ, ge->hsz); + GAEAD_AAD(ge->e), ge->f&(AEADF_PCHSZ | AEADF_NOAAD), + ge->hsz); Py_INCREF(ge->aad); rc = (PyObject *)ge->aad; } @@ -1240,8 +1372,8 @@ static PyMethodDef gaeadenc_pymethods[] = { { 0 } }; -PyObject *gaeaddec_pywrap(PyObject *cobj, gaead_dec *d, unsigned f, - size_t hsz, size_t csz, size_t tsz) +static PyObject *gaeaddec_pywrap(PyObject *cobj, gaead_dec *d, unsigned f, + size_t hsz, size_t csz, size_t tsz) { gaeaddec_pyobj *gd; assert(cobj); Py_INCREF(cobj); @@ -1302,7 +1434,8 @@ static PyObject *gaedmeth_aad(PyObject *me, PyObject *arg) if (!gd->aad) gd->aad = (gaeadaad_pyobj *) gaeadaad_pywrap((PyObject *)GCAEADENC_KEY(gd->ob_type)->aad, - GAEAD_AAD(gd->d), gd->f&AEADF_PCHSZ, gd->hsz); + GAEAD_AAD(gd->d), gd->f&(AEADF_PCHSZ | AEADF_NOAAD), + gd->hsz); Py_INCREF(gd->aad); return ((PyObject *)gd->aad); } @@ -1788,7 +1921,17 @@ static PyTypeObject gaeaddec_pytype_skel = { /*----- Hash functions ----------------------------------------------------*/ -PyTypeObject *gchash_pytype, *ghash_pytype; +PyTypeObject *gchash_pytype; +static PyTypeObject *ghash_pytype; +PyObject *sha_pyobj, *has160_pyobj; + +typedef struct ghash_pyobj { + PyObject_HEAD + ghash *h; +} ghash_pyobj; + +#define GHASH_PYCHECK(o) PyObject_TypeCheck((o), ghash_pytype) +#define GHASH_H(o) (((ghash_pyobj *)(o))->h) CONVFUNC(gchash, gchash *, GCHASH_CH) CONVFUNC(ghash, ghash *, GHASH_H) @@ -1803,7 +1946,7 @@ end: return (0); } -PyObject *gchash_pywrap(gchash *ch) +static PyObject *gchash_pywrap(gchash *ch) { gchash_pyobj *g = newtype(gchash_pytype, 0, ch->name); g->ch = ch; @@ -2028,11 +2171,30 @@ static PyTypeObject ghash_pytype_skel = { /*----- Message authentication --------------------------------------------*/ -PyTypeObject *gcmac_pytype, *gmac_pytype, *gmhash_pytype; +static PyTypeObject *gcmac_pytype, *gmac_pytype, *gmhash_pytype; + +typedef struct gcmac_pyobj { + PyHeapTypeObject ty; + gcmac *cm; +} gcmac_pyobj; +#define GCMAC_PYCHECK(o) PyObject_TypeCheck((o), gcmac_pytype) +#define GCMAC_CM(o) (((gcmac_pyobj *)(o))->cm) +#define GCMAC_F(o) (((gcmac_pyobj *)(o))->f) CONVFUNC(gcmac, gcmac *, GCMAC_CM) -CONVFUNC(gmac, gmac *, GMAC_M) -CONVFUNC(gmhash, ghash *, GHASH_H) +static PyObject *gmac_pywrap(PyObject *, gmac *); + +typedef struct gmac_pyobj { + PyHeapTypeObject ty; + gmac *m; +} gmac_pyobj; + +extern PyTypeObject *gmac_pytype; +#define GMAC_PYCHECK(o) PyObject_TypeCheck((o), gmac_pytype) +#define GMAC_M(o) (((gmac_pyobj *)(o))->m) +#define GMAC_F(o) (((gmac_pyobj *)(o))->f) +extern PyObject *gmac_pywrap(PyObject *, gmac *); +extern int convgmac(PyObject *, void *); static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { @@ -2061,7 +2223,7 @@ static PyObject *gmhash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) return ((PyObject *)g); } -PyObject *gcmac_pywrap(gcmac *cm) +static PyObject *gcmac_pywrap(gcmac *cm) { gcmac_pyobj *g = newtype(gcmac_pytype, 0, cm->name); g->cm = cm; @@ -2078,7 +2240,7 @@ PyObject *gcmac_pywrap(gcmac *cm) return ((PyObject *)g); } -PyObject *gmac_pywrap(PyObject *cobj, gmac *m) +static PyObject *gmac_pywrap(PyObject *cobj, gmac *m) { gmac_pyobj *g; if (!cobj) cobj = gcmac_pywrap((/*unconst*/ gcmac *)GM_CLASS(m)); @@ -2637,7 +2799,7 @@ static PyTypeObject poly1305hash_pytype_skel = { if (!PyArg_ParseTuple(arg, "s#s#:" #hdance "_prf", \ &k, &ksz, &n, &nsz)) \ goto end; \ - if (ksz != DANCE##_KEYSZ) VALERR("bad key length"); \ + if (ksz != keysz(ksz, dance##_keysz)) VALERR("bad key length"); \ if (nsz != HDANCE##_INSZ) VALERR("bad input length"); \ rc = bytestring_pywrap(0, HSALSA20_OUTSZ); \ dance##_init(&dance, k, ksz, 0); \ @@ -2665,8 +2827,7 @@ typedef struct kxvik_pyobj { unsigned n; } kxvik_pyobj; -static PyObject *kxvik_pynew(PyTypeObject *ty, - PyObject *arg, PyObject *kw) +static PyObject *kxvik_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { unsigned n = 24; kxvik_pyobj *rc = 0; @@ -2724,7 +2885,7 @@ static PyObject *kxvikmeth_extract(PyObject *me, PyObject *arg) unsigned i; unsigned n; - if (!PyArg_ParseTuple(arg, "O&:mix", convuint, &n)) goto end; + if (!PyArg_ParseTuple(arg, "O&:extract", convuint, &n)) goto end; if (n > 200) VALERR("out of range"); rc = bytestring_pywrap(0, n); q = (octet *)PyString_AS_STRING(rc); @@ -2754,10 +2915,14 @@ static int kxvikset_nround(PyObject *me, PyObject *val, void *hunoz) { kxvik_pyobj *k = (kxvik_pyobj *)me; unsigned n; + int rc = -1; - if (!convuint(val, &n)) return (-1); + if (!val) NIERR("__del__"); + if (!convuint(val, &n)) goto end; k->n = n; - return (0); + rc = 0; +end: + return (rc); } static PyGetSetDef kxvik_pygetset[] = { @@ -2954,7 +3119,7 @@ static PyObject *shakemeth_copy(PyObject *me, PyObject *arg) rc->h = *SHAKE_H(me); rc->st = SHAKE_ST(me); end: - return ((PyObject *)me); + return ((PyObject *)rc); } static PyObject *shakemeth_get(PyObject *me, PyObject *arg)