streamciphers = '''
rc4 seal
'''.split()
+latindances = '''
+salsa20 salsa20/12 salsa20/8 xsalsa20 xsalsa20/12 xsalsa20/8
+chacha20 chacha12 chacha8 xchacha20 xchacha12 xchacha8
+'''.split()
+streamciphers += map(lambda s: s.translate(None, '/'), latindances)
hashes = '''
md2 md4 md5 tiger has160
sha sha224 sha256 sha384 sha512
print '#define RNGS(_) \\'
for i in (cross(prps, ['ofb', 'counter'])):
print ('\t_("%(prim)s-%(mode)s", %(prim)s_keysz, ' +
- '%(prim)s_%(mode)srand, 0) \\') % \
+ '%(prim)s_%(mode)srand, 0, 0) \\') % \
{'prim': i[0], 'mode': i[1]}
for i in (cross(hashes, 'mgf')):
print ('\t_("%(prim)s-%(mode)s", %(prim)s_%(mode)skeysz, ' +
- '%(prim)s_%(mode)srand, 0) \\') % \
+ '%(prim)s_%(mode)srand, 0, 0) \\') % \
{'prim': i[0], 'mode': i[1]}
-print '\t_("rc4", rc4_keysz, rc4_rand, 0) \\'
-print '\t_("seal", seal_keysz, seal_rand, RNGF_INT) \\'
+print '\t_("rc4", rc4_keysz, rc4_rand, 0, 0) \\'
+print '\t_("seal", seal_keysz, seal_rand, RNGF_INT, 0) \\'
+for i in latindances:
+ for r in ['salsa20', 'xsalsa20', 'chacha', 'xchacha']:
+ if i.startswith(r):
+ root = r
+ break
+ else:
+ raise ValueError, 'failed to find root name for %s' % i
+ print ('\t_("%(name)s", %(root)s_keysz, %(id)s_rand, ' +
+ 'RNGF_NONCE, %(ROOT)s_NONCESZ) \\') % \
+ {'name': i, 'id': i.translate(None, '/'),
+ 'root': root, 'ROOT': root.upper()}
print '\t/* end */'
print
typedef grand *gcrand_func(const void *, size_t sz);
typedef grand *gcirand_func(const void *, size_t sz, uint32);
+typedef grand *gcnrand_func(const void *, size_t sz, const void *);
typedef struct gccrand_info {
const char *name;
const octet *keysz;
unsigned f;
+ size_t noncesz;
gcrand_func *func;
} gccrand_info;
#define RNGF_INT 1u
+#define RNGF_NONCE 2u
typedef struct gccrand_pyobj {
PyHeapTypeObject ty;
} gccrand_pyobj;
#define GCCRAND_INFO(o) (((gccrand_pyobj *)(o))->info)
-#define GCCRAND_DEF(name, ksz, func, f) \
+#define GCCRAND_DEF(name, ksz, func, f, nsz) \
static const gccrand_info func##_info = \
- { name, ksz, f, (gcrand_func *)func };
+ { name, ksz, f, nsz, (gcrand_func *)func };
RNGS(GCCRAND_DEF)
static const gccrand_info *const gcrandtab[] = {
-#define GCCRAND_ENTRY(name, ksz, func, f) &func##_info,
+#define GCCRAND_ENTRY(name, ksz, func, f, nsz) &func##_info,
RNGS(GCCRAND_ENTRY)
0
};
return (0);
}
+static PyObject *gcnrand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
+{
+ const gccrand_info *info = GCCRAND_INFO(ty);
+ static char *kwlist[] = { "key", "nonce", 0 };
+ char *k, *n;
+ int ksz, nsz;
+
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#s#:new", kwlist,
+ &k, &ksz, &n, &nsz))
+ goto end;
+ if (keysz(ksz, info->keysz) != ksz) VALERR("bad key length");
+ if (nsz != info->noncesz) VALERR("bad nonce length");
+ return (grand_dopywrap(ty,
+ ((gcnrand_func *)info->func)(k, ksz, n),
+ f_freeme));
+end:
+ return (0);
+}
+
static PyObject *gccrand_pywrap(const gccrand_info *info)
{
gccrand_pyobj *g = newtype(gccrand_pytype, 0, info->name);
Py_TPFLAGS_HEAPTYPE);
g->ty.ht_type.tp_alloc = PyType_GenericAlloc;
g->ty.ht_type.tp_free = 0;
- if (info->f & RNGF_INT)
- g->ty.ht_type.tp_new = gcirand_pynew;
- else
- g->ty.ht_type.tp_new = gcrand_pynew;
+ if (info->f & RNGF_INT) g->ty.ht_type.tp_new = gcirand_pynew;
+ else if (info->f & RNGF_NONCE) g->ty.ht_type.tp_new = gcnrand_pynew;
+ else g->ty.ht_type.tp_new = gcrand_pynew;
typeready(&g->ty.ht_type);
return ((PyObject *)g);
}