chiark / gitweb /
@@@ py_buffer/freebin wip mdw/freebin
authorMark Wooding <mdw@distorted.org.uk>
Sat, 25 Apr 2020 12:55:09 +0000 (13:55 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 25 Apr 2020 12:55:09 +0000 (13:55 +0100)
algorithms.c
pyke/pyke.c
pyke/pyke.h

index ead615a25052f7ce666a155113c4af76ec72ba71..3aef273c1109223c4bdc111e38e2fc6178072c69 100644 (file)
@@ -543,15 +543,16 @@ static PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c)
 static PyObject *gcipher_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "k", 0 };
-  struct bin k;
+  struct bin k = BIN_INIT;
+  PyObject *rc = 0;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &k))
     goto end;
   if (keysz(k.sz, GCCIPHER_CC(ty)->keysz) != k.sz) VALERR("bad key length");
-  return (gcipher_pywrap((PyObject *)ty,
-                        GC_INIT(GCCIPHER_CC(ty), k.p, k.sz)));
+  rc = gcipher_pywrap((PyObject *)ty, GC_INIT(GCCIPHER_CC(ty), k.p, k.sz));
 end:
-  return (0);
+  freebin(&k);
+  return (rc);
 }
 
 PyObject *gccipher_pywrap(gccipher *cc)
@@ -589,12 +590,14 @@ static PyObject *gccget_blksz(PyObject *me, void *hunoz)
 
 static PyObject *gcmeth_encrypt(PyObject *me, PyObject *arg)
 {
-  struct bin m;
+  struct bin m = BIN_INIT;
   PyObject *rc = 0;
 
-  if (!PyArg_ParseTuple(arg, "O&:encrypt", convbin, &m)) return (0);
+  if (!PyArg_ParseTuple(arg, "O&:encrypt", convbin, &m)) goto end;
   rc = bytestring_pywrap(0, m.sz);
   GC_ENCRYPT(GCIPHER_C(me), m.p, BIN_PTR(rc), m.sz);
+end:
+  freebin(&m);
   return (rc);
 }
 
@@ -614,12 +617,14 @@ static PyObject *gcmeth_enczero(PyObject *me, PyObject *arg)
 
 static PyObject *gcmeth_decrypt(PyObject *me, PyObject *arg)
 {
-  struct bin c;
+  struct bin c = BIN_INIT;
   PyObject *rc = 0;
 
-  if (!PyArg_ParseTuple(arg, "O&:decrypt", convbin, &c)) return (0);
+  if (!PyArg_ParseTuple(arg, "O&:decrypt", convbin, &c)) goto end;
   rc = bytestring_pywrap(0, c.sz);
   GC_DECRYPT(GCIPHER_C(me), c.p, BIN_PTR(rc), c.sz);
+end:
+  freebin(&c);
   return (rc);
 }
 
@@ -639,16 +644,18 @@ static PyObject *gcmeth_deczero(PyObject *me, PyObject *arg)
 
 static PyObject *gcmeth_setiv(PyObject *me, PyObject *arg)
 {
-  struct bin iv;
+  struct bin iv = BIN_INIT;
+  PyObject *rc = 0;
 
   if (!PyArg_ParseTuple(arg, "O&:setiv", convbin, &iv)) goto end;
   if (!GCIPHER_C(me)->ops->setiv) VALERR("`setiv' not supported");
   if (!GC_CLASS(GCIPHER_C(me))->blksz) VALERR("not a block cipher mode");
   if (iv.sz != GC_CLASS(GCIPHER_C(me))->blksz) VALERR("bad IV length");
   GC_SETIV(GCIPHER_C(me), iv.p);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
 end:
-  return (0);
+  freebin(&iv);
+  return (rc);
 }
 
 static PyObject *gcmeth_bdry(PyObject *me)
@@ -899,15 +906,17 @@ static PyObject *gaeadkey_pynew(PyTypeObject *ty,
                                PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "k", 0 };
-  struct bin k;
+  struct bin k = BIN_INIT;
+  PyObject *rc = 0;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &k))
     goto end;
   if (keysz(k.sz, GCAEAD_AEC(ty)->keysz) != k.sz) VALERR("bad key length");
-  return (gaeadkey_pywrap((PyObject *)ty,
-                         GAEAD_KEY(GCAEAD_AEC(ty), k.p, k.sz)));
+  rc = gaeadkey_pywrap((PyObject *)ty,
+                      GAEAD_KEY(GCAEAD_AEC(ty), k.p, k.sz));
 end:
-  return (0);
+  freebin(&k);
+  return (rc);
 }
 
 static PyObject *gcaead_pywrap(gcaead *aec)
@@ -1030,7 +1039,7 @@ static PyObject *gaekmeth_enc(PyObject *me, PyObject *arg, PyObject *kw)
   const gaead_key *k = GAEADKEY_K(me);
   gaead_enc *e;
   PyObject *rc = 0;
-  struct bin n;
+  struct bin n = BIN_INIT;
   PyObject *hszobj = Py_None, *mszobj = Py_None, *tszobj = Py_None;
   size_t hsz = 0, msz = 0, tsz = 0;
   unsigned f;
@@ -1046,6 +1055,7 @@ static PyObject *gaekmeth_enc(PyObject *me, PyObject *arg, PyObject *kw)
   rc = gaeadenc_pywrap((PyObject *)GCAEAD_ENC(Py_TYPE(me)),
                       e, f, hsz, msz, tsz);
 end:
+  freebin(&n);
   return (rc);
 }
 
@@ -1055,7 +1065,7 @@ static PyObject *gaekmeth_dec(PyObject *me, PyObject *arg, PyObject *kw)
   const gaead_key *k = GAEADKEY_K(me);
   gaead_dec *d;
   PyObject *rc = 0;
-  struct bin n;
+  struct bin n = BIN_INIT;
   PyObject *hszobj = Py_None, *cszobj = Py_None, *tszobj = Py_None;
   size_t hsz = 0, csz = 0, tsz = 0;
   unsigned f;
@@ -1071,6 +1081,7 @@ static PyObject *gaekmeth_dec(PyObject *me, PyObject *arg, PyObject *kw)
   rc = gaeaddec_pywrap((PyObject *)GCAEAD_DEC(Py_TYPE(me)),
                       d, f, hsz, csz, tsz);
 end:
+  freebin(&n);
   return (rc);
 }
 
@@ -1172,17 +1183,22 @@ end:
 
 static PyObject *gaeameth_hash(PyObject *me, PyObject *arg)
 {
-  struct bin h;
+  struct bin h = BIN_INIT;
+  PyObject *rc = 0;
 
-  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &h)) return (0);
-  if (gaeadaad_hash(me, h.p, h.sz)) return (0);
-  RETURN_ME;
+  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &h)) goto end;
+  if (gaeadaad_hash(me, h.p, h.sz)) goto end;
+  rc = me; Py_INCREF(rc);
+end:
+  freebin(&h);
+  return (rc);
 }
 
 #define GAEAMETH_HASHU_(n, W, w)                                       \
   static PyObject *gaeameth_hashu##w(PyObject *me, PyObject *arg)      \
   {                                                                    \
     uint##n x; octet b[SZ_##W];                                                \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     STORE##W(b, x); if (gaeadaad_hash(me, b, sizeof(b))) return (0);   \
     RETURN_ME;                                                         \
@@ -1192,14 +1208,17 @@ DOUINTCONV(GAEAMETH_HASHU_)
 #define GAEAMETH_HASHBUF_(n, W, w)                                     \
   static PyObject *gaeameth_hashbuf##w(PyObject *me, PyObject *arg)    \
   {                                                                    \
-    struct bin in; octet b[SZ_##W];                                    \
+    struct bin in = BIN_INIT; octet b[SZ_##W];                         \
+    PyObject *rc = 0;                                                  \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashbuf" #w, convbin, &in)) goto end; \
     if (in.sz > MASK##n) VALERR("too large");                          \
     STORE##W(b, in.sz); if (gaeadaad_hash(me, b, sizeof(b))) goto end; \
     if (gaeadaad_hash(me, in.p, in.sz)) goto end;                      \
-    RETURN_ME;                                                         \
+    rc = me; Py_INCREF(rc);                                            \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                       \
   }
 DOUINTCONV(GAEAMETH_HASHBUF_)
 
@@ -1304,9 +1323,10 @@ static PyObject *gaeemeth_reinit(PyObject *me, PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "nonce", "hsz", "msz", "tsz", 0 };
   gaeadenc_pyobj *ge = (gaeadenc_pyobj *)me;
-  struct bin n;
+  struct bin n = BIN_INIT;
   PyObject *hszobj = Py_None, *mszobj = Py_None, *tszobj = Py_None;
   size_t hsz = 0, msz = 0, tsz = 0;
+  PyObject *rc = 0;
   unsigned f;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|OOO:enc", KWLIST,
@@ -1319,14 +1339,16 @@ static PyObject *gaeemeth_reinit(PyObject *me, PyObject *arg, PyObject *kw)
     VALERR("bad aead parameter combination");
   gaea_sever(&ge->aad);
   ge->f = f; ge->hsz = hsz; ge->msz = msz; ge->tsz = tsz;
+  rc = me; Py_INCREF(rc);
 end:
-  return (0);
+  freebin(&n);
+  return (rc);
 }
 
 static PyObject *gaeemeth_encrypt(PyObject *me, PyObject *arg)
 {
   gaeadenc_pyobj *ge = (gaeadenc_pyobj *)me;
-  struct bin m;
+  struct bin m = BIN_INIT;
   char *c = 0; size_t csz; buf b;
   int err;
   PyObject *rc = 0;
@@ -1343,7 +1365,7 @@ static PyObject *gaeemeth_encrypt(PyObject *me, PyObject *arg)
   err = GAEAD_ENCRYPT(ge->e, m.p, m.sz, &b); assert(!err); (void)err;
   buf_flip(&b); rc = bytestring_pywrapbuf(&b); ge->mlen += m.sz;
 end:
-  xfree(c);
+  freebin(&m); xfree(c);
   return (rc);
 }
 
@@ -1473,9 +1495,10 @@ static PyObject *gaedmeth_reinit(PyObject *me, PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "nonce", "hsz", "csz", "tsz", 0 };
   gaeaddec_pyobj *gd = (gaeaddec_pyobj *)me;
-  struct bin n;
+  struct bin n = BIN_INIT;
   PyObject *hszobj = Py_None, *cszobj = Py_None, *tszobj = Py_None;
   size_t hsz = 0, csz = 0, tsz = 0;
+  PyObject *rc = 0;
   unsigned f;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|OOO:enc", KWLIST,
@@ -1488,14 +1511,16 @@ static PyObject *gaedmeth_reinit(PyObject *me, PyObject *arg, PyObject *kw)
     VALERR("bad aead parameter combination");
   gaea_sever(&gd->aad);
   gd->f = f; gd->hsz = hsz; gd->csz = csz; gd->tsz = tsz;
+  rc = me; Py_INCREF(rc);
 end:
+  freebin(&n);
   return (0);
 }
 
 static PyObject *gaedmeth_decrypt(PyObject *me, PyObject *arg)
 {
   gaeaddec_pyobj *gd = (gaeaddec_pyobj *)me;
-  struct bin c;
+  struct bin c = BIN_INIT;
   char *m = 0; size_t msz; buf b;
   int err;
   PyObject *rc = 0;
@@ -1512,7 +1537,7 @@ static PyObject *gaedmeth_decrypt(PyObject *me, PyObject *arg)
   err = GAEAD_DECRYPT(gd->d, c.p, c.sz, &b); assert(!err); (void)err;
   buf_flip(&b); rc = bytestring_pywrapbuf(&b); gd->clen += c.sz;
 end:
-  xfree(m);
+  freebin(&c); xfree(m);
   return (rc);
 }
 
@@ -1521,7 +1546,7 @@ static PyObject *gaedmeth_done(PyObject *me, PyObject *arg, PyObject *kw)
   static const char *const kwlist[] = { "tag", "aad", 0 };
   gaeaddec_pyobj *gd = (gaeaddec_pyobj *)me;
   PyObject *aad = Py_None;
-  struct bin t;
+  struct bin t = BIN_INIT;
   char *m = 0; size_t msz; buf b;
   int err;
   PyObject *rc = 0;
@@ -1550,7 +1575,7 @@ static PyObject *gaedmeth_done(PyObject *me, PyObject *arg, PyObject *kw)
   if (!err) VALERR("decryption failed");
   buf_flip(&b); rc = bytestring_pywrapbuf(&b);
 end:
-  xfree(m);
+  freebin(&t); xfree(m);
   return (rc);
 }
 
@@ -2023,16 +2048,22 @@ static PyObject *ghmeth_copy(PyObject *me)
 
 static PyObject *ghmeth_hash(PyObject *me, PyObject *arg)
 {
-  struct bin m;
-  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) return (0);
+  struct bin m = BIN_INIT;
+  PyObject *rc = 0;
+
+  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) goto end;
   GH_HASH(GHASH_H(me), m.p, m.sz);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
+end:
+  freebin(&m);
+  return (rc);
 }
 
 #define GHMETH_HASHU_(n, W, w)                                         \
   static PyObject *ghmeth_hashu##w(PyObject *me, PyObject *arg)                \
   {                                                                    \
     uint##n x;                                                         \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     GH_HASHU##W(GHASH_H(me), x);                                       \
     RETURN_ME;                                                         \
@@ -2042,12 +2073,15 @@ DOUINTCONV(GHMETH_HASHU_)
 #define GHMETH_HASHBUF_(n, W, w)                                       \
   static PyObject *ghmeth_hashbuf##w(PyObject *me, PyObject *arg)      \
   {                                                                    \
-    struct bin in;                                                     \
+    struct bin in = BIN_INIT;                                          \
+    PyObject *rc = 0;                                                  \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashbuf" #w, convbin, &in)) goto end; \
     if (in.sz > MASK##n) VALERR("too large");                          \
     GH_HASHBUF##W(GHASH_H(me), in.p, in.sz);                           \
-    RETURN_ME;                                                         \
+    rc = me; Py_INCREF(rc);                                            \
   end:                                                                 \
+    freebin(&in);                                                      \
     return (0);                                                                \
   }
 DOUINTCONV(GHMETH_HASHBUF_)
@@ -2222,14 +2256,15 @@ extern int convgmac(PyObject *, void *);
 static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "k", 0 };
-  struct bin k;
+  struct bin k = BIN_INIT;
+  PyObject *rc = 0;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &k))
     goto end;
   if (keysz(k.sz, GCMAC_CM(ty)->keysz) != k.sz) VALERR("bad key length");
-  return (gmac_pywrap((PyObject *)ty,
-                     GM_KEY(GCMAC_CM(ty), k.p, k.sz)));
+  rc = gmac_pywrap((PyObject *)ty, GM_KEY(GCMAC_CM(ty), k.p, k.sz));
 end:
+  freebin(&k);
   return (0);
 }
 
@@ -2495,19 +2530,21 @@ static PyObject *poly1305hash_pynew(PyTypeObject *ty,
   static const char *const kwlist[] = { "mask", 0 };
   poly1305key_pyobj *pk = (poly1305key_pyobj *)ty;
   poly1305hash_pyobj *ph;
-  struct bin m = { 0, 0 };
+  PyObject *rc = 0;
+  struct bin m = BIN_INIT;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:new", KWLIST, convbin, &m))
-    return (0);
+    goto end;
   if (m.p && m.sz != POLY1305_MASKSZ) VALERR("bad mask length");
   ph = PyObject_NEW(poly1305hash_pyobj, ty);
   ph->f = 0;
   if (m.p) ph->f |= f_mask;
   poly1305_macinit(&ph->ctx, &pk->k, m.p);
   Py_INCREF(ty);
-  return ((PyObject *)ph);
+  rc = (PyObject *)ph;
 end:
-  return (0);
+  freebin(&m);
+  return (rc);
 }
 
 static PyObject *poly1305key_pynew(PyTypeObject *ty,
@@ -2515,7 +2552,8 @@ static PyObject *poly1305key_pynew(PyTypeObject *ty,
 {
   static const char *const kwlist[] = { "k", 0 };
   poly1305key_pyobj *pk;
-  struct bin k;
+  struct bin k = BIN_INIT;
+  PyObject *rc = 0;
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &k))
     goto end;
@@ -2536,10 +2574,10 @@ static PyObject *poly1305key_pynew(PyTypeObject *ty,
   typeready(&pk->ty.ht_type);
 
   poly1305_keyinit(&pk->k, k.p, k.sz);
-  return ((PyObject *)pk);
-
+  rc = (PyObject *)pk;
 end:
-  return (0);
+  freebin(&k);
+  return (rc);
 }
 
 static PyObject *poly1305clsget_name(PyObject *me, void *hunoz)
@@ -2565,10 +2603,15 @@ static PyObject *polymeth_copy(PyObject *me)
 
 static PyObject *polymeth_hash(PyObject *me, PyObject *arg)
 {
-  struct bin m;
-  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) return (0);
+  struct bin m = BIN_INIT;
+  PyObject *rc = 0;
+
+  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) goto end;
   poly1305_hash(P1305_CTX(me), m.p, m.sz);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
+end:
+  freebin(&m);
+  return (rc);
 }
 
 #define POLYMETH_HASHU_(n, W, w)                                       \
@@ -2576,6 +2619,7 @@ static PyObject *polymeth_hash(PyObject *me, PyObject *arg)
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     STORE##W(b, x); poly1305_hash(P1305_CTX(me), b, sizeof(b));                \
     RETURN_ME;                                                         \
@@ -2585,15 +2629,18 @@ DOUINTCONV(POLYMETH_HASHU_)
 #define POLYMETH_HASHBUF_(n, W, w)                                     \
   static PyObject *polymeth_hashbuf##w(PyObject *me, PyObject *arg)    \
   {                                                                    \
-    struct bin in;                                                     \
+    struct bin in = BIN_INIT;                                          \
     octet b[SZ_##W];                                                   \
+    PyObject *rc = 0;                                                  \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashbuf" #w, convbin, &in)) goto end; \
     if (in.sz > MASK##n) VALERR("too large");                          \
     STORE##W(b, in.sz); poly1305_hash(P1305_CTX(me), b, sizeof(b));    \
     poly1305_hash(P1305_CTX(me), in.p, in.sz);                         \
-    RETURN_ME;                                                         \
+    rc = me; Py_INCREF(rc);                                            \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                       \
   }
 DOUINTCONV(POLYMETH_HASHBUF_)
 
@@ -2831,8 +2878,9 @@ static const PyTypeObject poly1305hash_pytype_skel = {
   static PyObject *meth_##hdance##_prf(PyObject *me, PyObject *arg)    \
   {                                                                    \
     dance##_ctx dance;                                                 \
-    struct bin k, n;                                                   \
-    PyObject *rc;                                                      \
+    struct bin k = BIN_INIT, n = BIN_INIT;                             \
+    PyObject *rc = 0;                                                  \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&O&:" #hdance "_prf",                 \
                          convbin, &k, convbin, &n))                    \
       goto end;                                                                \
@@ -2841,9 +2889,9 @@ static const PyTypeObject poly1305hash_pytype_skel = {
     rc = bytestring_pywrap(0, HSALSA20_OUTSZ);                         \
     dance##_init(&dance, k.p, k.sz, 0);                                        \
     hdance##_prf(&dance, n.p, BIN_PTR(rc));                            \
-    return (rc);                                                       \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&k); freebin(&n);                                          \
+    return (rc);                                                       \
   }
 
 DEF_HDANCE(SALSA20, HSALSA20, salsa20, hsalsa20)
@@ -2894,7 +2942,8 @@ static PyObject *kxvikmeth_mix(PyObject *me, PyObject *arg)
   const octet *q;
   octet buf[8];
   unsigned i;
-  struct bin in;
+  struct bin in = BIN_INIT;
+  PyObject *rc = 0;
   size_t n;
 
   if (!PyArg_ParseTuple(arg, "O&:mix", convbin, &in)) goto end;
@@ -2907,9 +2956,10 @@ static PyObject *kxvikmeth_mix(PyObject *me, PyObject *arg)
     LOAD64_L_(t[i], buf); i++;
   }
   keccak1600_mix(&k->s, t, i);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
 end:
-  return (0);
+  freebin(&in);
+  return (rc);
 }
 
 static PyObject *kxvikmeth_set(PyObject *me, PyObject *arg)
@@ -2918,7 +2968,8 @@ static PyObject *kxvikmeth_set(PyObject *me, PyObject *arg)
   kludge64 t[25];
   const octet *q;
   unsigned i;
-  struct bin in;
+  struct bin in = BIN_INIT;
+  PyObject *rc = 0;
   size_t n;
 
   if (!PyArg_ParseTuple(arg, "O&:set", convbin, &in)) goto end;
@@ -2928,9 +2979,10 @@ static PyObject *kxvikmeth_set(PyObject *me, PyObject *arg)
   while (n >= 8) { LOAD64_L_(t[i], q); i++; q += 8; n -= 8; }
   if (n) VALERR("not 64-bit aligned");
   keccak1600_set(&k->s, t, i);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
 end:
-  return (0);
+  freebin(&in);
+  return (rc);
 }
 
 static PyObject *kxvikmeth_extract(PyObject *me, PyObject *arg)
@@ -3046,7 +3098,7 @@ static PyObject *shake_dopynew(void (*initfn)(shake_ctx *,
 {
   shake_pyobj *rc = 0;
   PyObject *pobj = Py_None, *fobj = Py_None;
-  struct bin p = { 0, 0 }, f = { 0, 0 };
+  struct bin p = BIN_INIT, f = BIN_INIT;
   static const char *const kwlist[] = { "perso", "func", 0 };
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OO:new", KWLIST, &pobj, &fobj))
@@ -3057,6 +3109,7 @@ static PyObject *shake_dopynew(void (*initfn)(shake_ctx *,
   initfn(&rc->h, f.p, f.sz, p.p, p.sz);
   rc->st = 0;
 end:
+  freebin(&p); freebin(&f);
   return ((PyObject *)rc);
 }
 
@@ -3078,11 +3131,16 @@ end:
 
 static PyObject *shakemeth_hash(PyObject *me, PyObject *arg)
 {
-  struct bin m;
-  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) return (0);
-  if (shake_check(me, 0)) return (0);
+  struct bin m = BIN_INIT;
+  PyObject *rc = 0;
+
+  if (!PyArg_ParseTuple(arg, "O&:hash", convbin, &m)) goto end;
+  if (shake_check(me, 0)) goto end;
   shake_hash(SHAKE_H(me), m.p, m.sz);
-  RETURN_ME;
+  rc = me; Py_INCREF(rc);
+end:
+  freebin(&m);
+  return (rc);
 }
 
 #define SHAKEMETH_HASHU_(n, W, w)                                      \
@@ -3090,6 +3148,7 @@ static PyObject *shakemeth_hash(PyObject *me, PyObject *arg)
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     if (shake_check(me, 0)) return (0);                                        \
     STORE##W(b, x); shake_hash(SHAKE_H(me), b, sizeof(b));             \
@@ -3100,22 +3159,26 @@ DOUINTCONV(SHAKEMETH_HASHU_)
 #define SHAKEMETH_HASHBUF_(n, W, w)                                    \
   static PyObject *shakemeth_hashbuf##w(PyObject *me, PyObject *arg)   \
   {                                                                    \
-    struct bin in;                                                     \
+    struct bin in = BIN_INIT;                                          \
+    PyObject *rc = 0;                                                  \
     octet b[SZ_##W];                                                   \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:hashbuf" #w, convbin, &in)) goto end; \
     if (in.sz > MASK##n) VALERR("too large");                          \
     if (shake_check(me, 0)) goto end;                                  \
     STORE##W(b, in.sz); shake_hash(SHAKE_H(me), b, sizeof(b));         \
     shake_hash(SHAKE_H(me), in.p, in.sz);                              \
-    RETURN_ME;                                                         \
+    rc = me; Py_INCREF(rc);                                            \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                               \
   }
 DOUINTCONV(SHAKEMETH_HASHBUF_)
 
 static PyObject *shakemeth_hashstrz(PyObject *me, PyObject *arg)
 {
   char *p;
+
   if (!PyArg_ParseTuple(arg, "s:hashstrz", &p)) return (0);
   if (shake_check(me, 0)) return (0);
   shake_hash(SHAKE_H(me), p, strlen(p) + 1);
@@ -3137,6 +3200,7 @@ static PyObject *shakemeth_done(PyObject *me, PyObject *arg, PyObject *kw)
   PyObject *rc = 0;
   size_t n = 100 - SHAKE_H(me)->h.r/2;
   static const char *const kwlist[] = { "hsz", 0 };
+
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:done", KWLIST, convszt, &n))
     goto end;
   if (shake_check(me, 0)) goto end;
@@ -3173,13 +3237,14 @@ end:
 static PyObject *shakemeth_mask(PyObject *me, PyObject *arg)
 {
   PyObject *rc = 0;
-  struct bin in;
+  struct bin in = BIN_INIT;
 
   if (!PyArg_ParseTuple(arg, "O&:mask", convbin, &in)) goto end;
   if (shake_check(me, 1)) goto end;
   rc = bytestring_pywrap(0, in.sz);
   shake_mask(SHAKE_H(me), in.p, BIN_PTR(rc), in.sz);
 end:
+  freebin(&in);
   return (rc);
 }
 
@@ -3379,7 +3444,7 @@ static PyObject *kmac_dopynew(void (*initfn)(shake_ctx *,
 {
   shake_pyobj *rc = 0;
   PyObject *pobj = Py_None;
-  struct bin k = { 0, 0 }, p = { 0, 0 };
+  struct bin k = BIN_INIT, p = BIN_INIT;
   static const char *const kwlist[] = { "key", "perso", 0 };
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O:new", KWLIST,
@@ -3390,6 +3455,7 @@ static PyObject *kmac_dopynew(void (*initfn)(shake_ctx *,
   initfn(&rc->h, p.p, p.sz, k.p, k.sz);
   rc->st = 0;
 end:
+  freebin(&k); freebin(&p);
   return ((PyObject *)rc);
 }
 
@@ -3695,7 +3761,7 @@ end:
 static PyObject *strobemeth_process(PyObject *me, PyObject *arg)
 {
   PyObject *inobj;
-  struct bin in;
+  struct bin in = BIN_INIT;
   PyObject *rc = 0;
 
   in.p = 0;
@@ -3706,6 +3772,7 @@ static PyObject *strobemeth_process(PyObject *me, PyObject *arg)
   }
   rc = strobe_pyprocess(me, in.p, in.sz, 0, 0);
 end:
+  freebin(&in);
   return (rc);
 }
 
@@ -3725,6 +3792,7 @@ static PyObject *strobemeth_done(PyObject *me)
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:processu" #w, convu##n, &x)) return (0); \
     STORE##W(b, x); return (strobe_pyprocess(me, b, sizeof(b), 0, 0)); \
   }
@@ -3733,14 +3801,17 @@ DOUINTCONV(STROBEMETH_PROCESSU_)
 #define STROBEMETH_PROCESSBUF_(n, W, w)                                        \
   static PyObject *strobemeth_processbuf##w(PyObject *me, PyObject *arg) \
   {                                                                    \
-    struct bin in;                                                     \
+    struct bin in = BIN_INIT;                                          \
     octet b[SZ_##W];                                                   \
+    PyObject *rc = 0;                                                  \
+                                                                       \
     if (!PyArg_ParseTuple(arg, "O&:processbuf" #w, convbin, &in)) goto end; \
     if (in.sz > MASK##n) VALERR("too large");                          \
     STORE##W(b, in.sz);                                                        \
-    return (strobe_pyprocess(me, b, sizeof(b), in.p, in.sz));          \
+    rc = strobe_pyprocess(me, b, sizeof(b), in.p, in.sz);              \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                       \
   }
 DOUINTCONV(STROBEMETH_PROCESSBUF_)
 
@@ -3755,17 +3826,20 @@ static PyObject *strobemeth_processstrz(PyObject *me, PyObject *arg)
   static PyObject *strobemeth_##meth(PyObject *me,                     \
                                     PyObject *arg, PyObject *kw)       \
   {                                                                    \
-    struct bin in; unsigned f = 0;                                     \
+    struct bin in = BIN_INIT; unsigned f = 0;                          \
+    PyObject *rc = 0;                                                  \
     static const char *const kwlist[] = { #arg, "f", 0 };              \
+                                                                       \
     if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:" #meth, KWLIST,  \
                                     convbin, &in, convstrbf, &f))      \
       goto end;                                                                \
     if (f&~STRBF_M) VALERR("bad flags");                               \
     if (strobe_checkinactive(me)) goto end;                            \
     strobe_##meth(STROBE_CTX(me), f, in.p, in.sz);                     \
-    RETURN_ME;                                                         \
+    rc = me; Py_INCREF(rc);                                            \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                       \
   }
 
 #define STROBEMETH_OUTONLY_(meth)                                      \
@@ -3774,6 +3848,7 @@ static PyObject *strobemeth_processstrz(PyObject *me, PyObject *arg)
   {                                                                    \
     size_t sz; unsigned f = 0; PyObject *rc;                           \
     static const char *const kwlist[] = { "sz", "f", 0 };              \
+                                                                       \
     if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:" #meth, KWLIST,  \
                          convszt, &sz, convstrbf, &f))                 \
       goto end;                                                                \
@@ -3781,17 +3856,17 @@ static PyObject *strobemeth_processstrz(PyObject *me, PyObject *arg)
     if (strobe_checkinactive(me)) goto end;                            \
     rc = bytestring_pywrap(0, sz);                                     \
     strobe_##meth(STROBE_CTX(me), f, BIN_PTR(rc), sz);                 \
-    return (rc);                                                       \
   end:                                                                 \
-    return (0);                                                                \
+    return (rc);                                                       \
   }
 
 #define STROBEMETH_INOUT_(meth, arg)                                   \
   static PyObject *strobemeth_##meth(PyObject *me,                     \
                                     PyObject *arg, PyObject *kw)       \
   {                                                                    \
-    struct bin in; unsigned f = 0; PyObject *rc;                       \
+    struct bin in = BIN_INIT; unsigned f = 0; PyObject *rc;            \
     static const char *const kwlist[] = { #arg, "f", 0 };              \
+                                                                       \
     if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:" #meth, KWLIST,  \
                                     convbin, &in, convstrbf, &f))      \
       goto end;                                                                \
@@ -3799,9 +3874,9 @@ static PyObject *strobemeth_processstrz(PyObject *me, PyObject *arg)
     if (strobe_checkinactive(me)) goto end;                            \
     rc = bytestring_pywrap(0, in.sz);                                  \
     strobe_##meth(STROBE_CTX(me), f, in.p, BIN_PTR(rc), in.sz);                \
-    return (rc);                                                       \
   end:                                                                 \
-    return (0);                                                                \
+    freebin(&in);                                                      \
+    return (rc);                                                       \
   }
 
 STROBEMETH_INONLY_(key, key)
@@ -3815,16 +3890,19 @@ STROBEMETH_OUTONLY_(macout)
 
 static PyObject *strobemeth_macin(PyObject *me, PyObject *arg, PyObject *kw)
 {
-  struct bin in; unsigned f = 0;
+  struct bin in = BIN_INIT; unsigned f = 0;
+  PyObject *rc = 0;
   static const char *const kwlist[] = { "tag", "f", 0 };
+
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:macin", KWLIST,
                                   convbin, &in, convstrbf, &f))
     goto end;
   if (f&~STRBF_M) VALERR("bad flags");
   if (strobe_checkinactive(me)) goto end;
-  return (getbool(!strobe_macin(STROBE_CTX(me), f, in.p, in.sz)));
+  rc = getbool(!strobe_macin(STROBE_CTX(me), f, in.p, in.sz));
 end:
-  return (0);
+  freebin(&in);
+  return (rc);
 }
 
 static PyObject *strobemeth_ratchet(PyObject *me,
@@ -3832,6 +3910,7 @@ static PyObject *strobemeth_ratchet(PyObject *me,
 {
   size_t sz; unsigned f = 0;
   static const char *const kwlist[] = { "sz", "f", 0 };
+
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:ratchet", KWLIST,
                                   convszt, &sz, convstrbf, &f))
     goto end;
@@ -3997,7 +4076,7 @@ typedef struct prp {
 static PyObject *gprp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
   static const char *const kwlist[] = { "key", 0 };
-  struct bin k;
+  struct bin k = BIN_INIT;
   const prpinfo *prp = GCPRP_PRP(ty);
   PyObject *rc = 0;
 
@@ -4008,6 +4087,7 @@ static PyObject *gprp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   GPRP_PRP(me) = prp;
   prp->init(GPRP_CTX(me), k.p, k.sz);
 end:
+  freebin(&k);
   return (rc);
 }
 
@@ -4017,6 +4097,7 @@ static void gprp_pydealloc(PyObject *me)
 static PyObject *gcprp_pywrap(const prpinfo *prp)
 {
   gcprp_pyobj *g = newtype(gcprp_pytype, 0, prp->name);
+
   g->prp = prp;
   g->ty.ht_type.tp_basicsize = sizeof(gprp_pyobj) + prp->ctxsz;
   g->ty.ht_type.tp_base = gprp_pytype;
@@ -4040,7 +4121,7 @@ static PyObject *gcpget_blksz(PyObject *me, void *hunoz)
 
 static PyObject *gpmeth_encrypt(PyObject *me, PyObject *arg)
 {
-  struct bin m;
+  struct bin m = BIN_INIT;
   PyObject *rc = 0;
 
   if (!PyArg_ParseTuple(arg, "O&:encrypt", convbin, &m)) goto end;
@@ -4048,12 +4129,13 @@ static PyObject *gpmeth_encrypt(PyObject *me, PyObject *arg)
   rc = bytestring_pywrap(0, m.sz);
   GPRP_PRP(me)->eblk(GPRP_CTX(me), m.p, BIN_PTR(rc));
 end:
+  freebin(&m);
   return (rc);
 }
 
 static PyObject *gpmeth_decrypt(PyObject *me, PyObject *arg)
 {
-  struct bin c;
+  struct bin c = BIN_INIT;
   PyObject *rc = 0;
 
   if (!PyArg_ParseTuple(arg, "O&:decrypt", convbin, &c)) goto end;
@@ -4061,6 +4143,7 @@ static PyObject *gpmeth_decrypt(PyObject *me, PyObject *arg)
   rc = bytestring_pywrap(0, c.sz);
   GPRP_PRP(me)->dblk(GPRP_CTX(me), c.p, BIN_PTR(rc));
 end:
+  freebin(&c);
   return (rc);
 }
 
index 330f15cab6e95d2f88221d647993ad84be54d3dc..4233c2f708ff21ea46636d7f6ea398deb909e17e 100644 (file)
@@ -106,8 +106,10 @@ end:
 int convbin(PyObject *o, void *pp)
 {
   struct bin *r = pp;
+  int rc;
 
   if (BIN_CHECK(o)) {
+    r->vw.obj = 0;
     r->p = BIN_PTR(o);
     r->sz = BIN_LEN(o);
     return (1);
@@ -116,14 +118,25 @@ int convbin(PyObject *o, void *pp)
   if (PyUnicode_Check(o)) {
     o = _PyUnicode_AsDefaultEncodedString(o, 0);
     if (!o) return (0);
+    r->vw.obj = 0;
     r->p = PyString_AS_STRING(o);
     r->sz = PyString_GET_SIZE(o);
     return (1);
   }
 #endif
+#if PY_VERSION_HEX < 0x02060000
+  r->vw.buf = 0;
   return (PyObject_AsReadBuffer(o, &r->p, &r->sz) ? 0 : 1);
+#else
+  rc = PyObject_GetBuffer(o, &r->vw, PyBUF_SIMPLE); if (rc) return (0);
+  o->p = o->vw.buf; o->sz = o->vw.len;
+  return (1);
+#endif
 }
 
+void freebin(struct bin *r)
+  { if (r->vw.obj) PyBuffer_Release(&r->vw); }
+
 /*----- Miscellaneous utilities -------------------------------------------*/
 
 PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
index a60fd76a93f8e45682150920862787e8e0b75e4d..4390c9586082e984c9c1b6f00f412d0dd592a922 100644 (file)
@@ -355,12 +355,15 @@ extern void restore_exception(struct excinfo *, const char *, ...);
 /* Input conversion functions for standard kinds of objects, with overflow
  * checking where applicable.
  */
-struct bin { const void *p; Py_ssize_t sz; };
+struct bin { Py_buffer vw; const void *p; Py_ssize_t sz; };
+#define BIN_INIT { { 0 } 0, 0 }
+
 extern int convulong(PyObject *, void *); /* unsigned long */
 extern int convuint(PyObject *, void *); /* unsigned int */
 extern int convszt(PyObject *, void *);        /* size_t */
 extern int convbool(PyObject *, void *); /* bool */
 extern int convbin(PyObject *, void *); /* read buffer holding bytes */
+extern void freebin(struct bin *);
 
 /* Output conversions. */
 extern PyObject *getbool(int);         /* bool */