From 850a4b483975ef7081ea7fabfa2e90f99a1844a9 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 28 Jan 2006 19:09:57 +0000 Subject: [PATCH] rand: Generators based on symmetric algorithms; fixing * Include support for the various generators based on symmetric algorithms: i.e., counter and OFB modes for block ciphers, and SEAL and RC4. * Recognise, and return correct subclass instance for, TLS and SSL generators, and the symmetric crypto-based generators. --- rand.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 223 insertions(+), 1 deletion(-) diff --git a/rand.c b/rand.c index d779846..4b40a75 100644 --- a/rand.c +++ b/rand.c @@ -29,6 +29,7 @@ /*----- Header files ------------------------------------------------------*/ #include "catacomb-python.h" +#include "algorithms.h" /*----- Main code ---------------------------------------------------------*/ @@ -38,6 +39,8 @@ PyTypeObject *dsarand_pytype, *bbs_pytype, *bbspriv_pytype; PyTypeObject *sslprf_pytype, *tlsdx_pytype, *tlsprf_pytype; PyObject *rand_pyobj; +static PyObject *gccrands_dict; + static PyObject *grand_dopywrap(PyTypeObject *ty, grand *r, unsigned f) { grand_pyobj *g; @@ -51,12 +54,18 @@ static PyObject *grand_dopywrap(PyTypeObject *ty, grand *r, unsigned f) PyObject *grand_pywrap(grand *r, unsigned f) { PyTypeObject *ty = grand_pytype; + PyObject *ob; if (strcmp(r->ops->name, "rand") == 0) ty = truerand_pytype; else if (strcmp(r->ops->name, "lcrand") == 0) ty = lcrand_pytype; else if (strcmp(r->ops->name, "fibrand") == 0) ty = fibrand_pytype; else if (strcmp(r->ops->name, "dsarand") == 0) ty = dsarand_pytype; else if (strcmp(r->ops->name, "bbs") == 0) ty = bbs_pytype; + else if (strcmp(r->ops->name, "sslprf") == 0) ty = sslprf_pytype; + else if (strcmp(r->ops->name, "tlsdx") == 0) ty = tlsdx_pytype; + else if (strcmp(r->ops->name, "tlsprf") == 0) ty = tlsprf_pytype; + else if ((ob = PyDict_GetItemString(gccrands_dict, r->ops->name)) != 0) + ty = (PyTypeObject *)ob; return (grand_dopywrap(ty, r, f)); } @@ -441,12 +450,22 @@ static PyObject *trmeth_stretch(PyObject *me, PyObject *arg) RETURN_ME; } +static PyObject *trmeth_add(PyObject *me, PyObject *arg) +{ + grand *r = GRAND_R(me); + char *p; int n; unsigned goodbits; + if (!PyArg_ParseTuple(arg, "s#O&:add", &p, &n, convuint, &goodbits)) + return (0); + r->ops->misc(r, RAND_ADD, p, (size_t)n, goodbits); + RETURN_ME; +} + static PyObject *trmeth_key(PyObject *me, PyObject *arg) { grand *r = GRAND_R(me); char *p; int n; if (!PyArg_ParseTuple(arg, "s#:key", &p, &n)) return (0); - r->ops->misc(r, RAND_KEY, p, n); + r->ops->misc(r, RAND_KEY, p, (size_t)n); RETURN_ME; } @@ -491,6 +510,7 @@ static PyMethodDef truerand_pymethods[] = { METH (stretch, "R.stretch()") METH (key, "R.key(BYTES)") METH (seed, "R.seed(NBITS)") + METH (add, "R.add(BYTES, GOODBITS") METH (timer, "R.timer()") #undef METHNAME { 0 } @@ -557,6 +577,199 @@ static PyTypeObject truerand_pytype_skel = { 0 /* @tp_is_gc@ */ }; +/*----- Generators from symmetric encryption algorithms -------------------*/ + +static PyTypeObject *gccrand_pytype, *gcrand_pytype; + +typedef grand *gcrand_func(const void *, size_t sz); +typedef grand *gcirand_func(const void *, size_t sz, uint32); +typedef struct gccrand_info { + const char *name; + const octet *keysz; + unsigned f; + gcrand_func *func; +} gccrand_info; + +typedef struct gccrand_pyobj { + PyHeapTypeObject ty; + const gccrand_info *info; +} gccrand_pyobj; +#define GCCRAND_INFO(o) (((gccrand_pyobj *)(o))->info) + +#define GCCRAND_DEF(name, ksz, func, f) \ + static const gccrand_info func##_info = \ + { name, ksz, f, (gcrand_func *)func }; +RNGS(GCCRAND_DEF) + +static const gccrand_info *const gcrandtab[] = { +#define GCCRAND_ENTRY(name, ksz, func, f) &func##_info, + RNGS(GCCRAND_ENTRY) + 0 +}; + +static PyObject *gcrand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) +{ + const gccrand_info *info = GCCRAND_INFO(ty); + static char *kwlist[] = { "key", 0 }; + char *k; + int n; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &n)) + goto end; + if (keysz(n, info->keysz) != n) VALERR("bad key length"); + return (grand_dopywrap(ty, info->func(k, n), f_freeme)); +end: + return (0); +} + +static PyObject *gcirand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) +{ + const gccrand_info *info = GCCRAND_INFO(ty); + uint32 i = 0; + static char *kwlist[] = { "key", "i", 0 }; + char *k; + int n; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&:new", kwlist, + &k, &n, convu32, &i)) + goto end; + if (keysz(n, info->keysz) != n) VALERR("bad key length"); + return (grand_dopywrap(ty, + ((gcirand_func *)info->func)(k, n, i), + f_freeme)); +end: + return (0); +} + +static PyObject *gccrand_pywrap(const gccrand_info *info) +{ + gccrand_pyobj *g = newtype(gccrand_pytype, 0, info->name); + g->info = info; + g->ty.type.tp_basicsize = sizeof(grand_pyobj); + g->ty.type.tp_base = gcrand_pytype; + Py_INCREF(gcrand_pytype); + g->ty.type.tp_flags = (Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HEAPTYPE); + g->ty.type.tp_alloc = PyType_GenericAlloc; + g->ty.type.tp_free = 0; + if (info->f & RNGF_INT) + g->ty.type.tp_new = gcirand_pynew; + else + g->ty.type.tp_new = gcrand_pynew; + PyType_Ready(&g->ty.type); + return ((PyObject *)g); +} + +static PyObject *gccrget_name(PyObject *me, void *hunoz) + { return (PyString_FromString(GCCRAND_INFO(me)->name)); } +static PyObject *gccrget_keysz(PyObject *me, void *hunoz) + { return (keysz_pywrap(GCCRAND_INFO(me)->keysz)); } + +static PyGetSetDef gccrand_pygetset[] = { +#define GETSETNAME(op, name) gccr##op##_##name + GET (keysz, "CR.keysz -> acceptable key sizes") + GET (name, "CR.name -> name of this kind of generator") +#undef GETSETNAME + { 0 } +}; + +static PyTypeObject gccrand_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "catacomb.GCCRand", /* @tp_name@ */ + sizeof(gccrand_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + 0, /* @tp_dealloc@ */ + 0, /* @tp_print@ */ + 0, /* @tp_getattr@ */ + 0, /* @tp_setattr@ */ + 0, /* @tp_compare@ */ + 0, /* @tp_repr@ */ + 0, /* @tp_as_number@ */ + 0, /* @tp_as_sequence@ */ + 0, /* @tp_as_mapping@ */ + 0, /* @tp_hash@ */ + 0, /* @tp_call@ */ + 0, /* @tp_str@ */ + 0, /* @tp_getattro@ */ + 0, /* @tp_setattro@ */ + 0, /* @tp_as_buffer@ */ + Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ + Py_TPFLAGS_BASETYPE, + + /* @tp_doc@ */ +"Metaclass for symmetric crypto-based generators.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + 0, /* @tp_methods@ */ + 0, /* @tp_members@ */ + gccrand_pygetset, /* @tp_getset@ */ + 0, /* @tp_base@ */ + 0, /* @tp_dict@ */ + 0, /* @tp_descr_get@ */ + 0, /* @tp_descr_set@ */ + 0, /* @tp_dictoffset@ */ + 0, /* @tp_init@ */ + PyType_GenericAlloc, /* @tp_alloc@ */ + abstract_pynew, /* @tp_new@ */ + 0, /* @tp_free@ */ + 0 /* @tp_is_gc@ */ +}; + +static PyTypeObject gcrand_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "catacomb.GCRand", /* @tp_name@ */ + sizeof(grand_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + grand_pydealloc, /* @tp_dealloc@ */ + 0, /* @tp_print@ */ + 0, /* @tp_getattr@ */ + 0, /* @tp_setattr@ */ + 0, /* @tp_compare@ */ + 0, /* @tp_repr@ */ + 0, /* @tp_as_number@ */ + 0, /* @tp_as_sequence@ */ + 0, /* @tp_as_mapping@ */ + 0, /* @tp_hash@ */ + 0, /* @tp_call@ */ + 0, /* @tp_str@ */ + 0, /* @tp_getattro@ */ + 0, /* @tp_setattro@ */ + 0, /* @tp_as_buffer@ */ + Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ + Py_TPFLAGS_BASETYPE, + + /* @tp_doc@ */ +"Abstract base class for symmetric crypto-based generators.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + 0, /* @tp_methods@ */ + 0, /* @tp_members@ */ + 0, /* @tp_getset@ */ + 0, /* @tp_base@ */ + 0, /* @tp_dict@ */ + 0, /* @tp_descr_get@ */ + 0, /* @tp_descr_set@ */ + 0, /* @tp_dictoffset@ */ + 0, /* @tp_init@ */ + PyType_GenericAlloc, /* @tp_alloc@ */ + abstract_pynew, /* @tp_new@ */ + 0, /* @tp_free@ */ + 0 /* @tp_is_gc@ */ +}; + /*----- SSL and TLS generators --------------------------------------------*/ static PyObject *sslprf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) @@ -1145,11 +1358,16 @@ void rand_pyinit(void) INITTYPE(sslprf, grand); INITTYPE(tlsdx, grand); INITTYPE(tlsprf, grand); + INITTYPE(gccrand, type); + INITTYPE(gcrand, grand); rand_noisesrc(RAND_GLOBAL, &noise_source); rand_seed(RAND_GLOBAL, 160); addmethods(methods); } +#define gccrand gccrand_info +GEN(gccrands, crand) + void rand_pyinsert(PyObject *mod) { INSERT("GRand", grand_pytype); @@ -1162,7 +1380,11 @@ void rand_pyinsert(PyObject *mod) INSERT("DSARand", dsarand_pytype); INSERT("BlumBlumShub", bbs_pytype); INSERT("BBSPriv", bbspriv_pytype); + INSERT("GCCRand", gccrand_pytype); + INSERT("GCRand", gcrand_pytype); rand_pyobj = grand_pywrap(&rand_global, 0); Py_INCREF(rand_pyobj); + gccrands_dict = gccrands(); Py_INCREF(gccrands_dict); + INSERT("gccrands", gccrands_dict); INSERT("rand", rand_pyobj); } -- 2.11.0