diff options
author | moraes <moraes@rivest.dlitz.net> | 2002-10-23 04:52:20 -0700 |
---|---|---|
committer | moraes <moraes@rivest.dlitz.net> | 2002-10-23 04:52:20 -0700 |
commit | a317dcc290cd7eab22cb23e83e5e88fc33a40fc7 (patch) | |
tree | ce6b935eecf95fce89be0030862e01ab7d1d4482 /src/winrand.c | |
parent | 8ad4547afb76a4bd5474e1f04877895ff83ce241 (diff) | |
download | pycrypto-a317dcc290cd7eab22cb23e83e5e88fc33a40fc7.tar.gz |
[project @ moraes-20021023115220-7b961936f27ecd5b]
[project @ 2002-10-23 04:52:20 by moraes]
Added Crypto.Util.winrandom.winrandom C extension code
to get randomness from Windows CryptGenRandom.
Diffstat (limited to 'src/winrand.c')
-rw-r--r-- | src/winrand.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/winrand.c b/src/winrand.c new file mode 100644 index 0000000..00b6f4b --- /dev/null +++ b/src/winrand.c @@ -0,0 +1,86 @@ +/* -*- C -*- */ +/* + * Uses Windows CryptoAPI CryptGenRandom to get random bytes + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. This software is provided "as is" without + * warranty of fitness for use or suitability for any purpose, express + * or implied. Use at your own risk or not at all. + * + */ + +/* Author: Mark Moraes */ + +#include "Python.h" + +#ifdef MS_WIN32 + +#define _WIN32_WINNT 0x400 +#define WINSOCK + +#include <windows.h> +#include <wincrypt.h> + +static char winrandom__doc__[] = +"winrandom(nbytes): Returns nbytes of random data from Windows CryptGenRandom," +"a cryptographically strong pseudo-random generator using system entropy"; + +static PyObject * +winrandom(PyObject *self, PyObject *args) +{ + HCRYPTPROV hcp = 0; + int n, nbytes; + PyObject *res; + char *buf; + + if (!PyArg_ParseTuple(args, "i", &n)) { + return NULL; + } + /* Just in case char != BYTE */ + nbytes = (n * sizeof(char)) / sizeof(BYTE); + if (nbytes <= 0) { + PyErr_SetString(PyExc_ValueError, "nbytes must be positive number"); + return NULL; + } + if ((buf = (char *) PyMem_Malloc(nbytes)) == NULL) + return PyErr_NoMemory(); + + if (! CryptAcquireContext(&hcp, NULL, NULL, PROV_RSA_FULL, 0)) { + PyErr_Format(PyExc_SystemError, + "CryptAcquireContext failed, error %i", + GetLastError()); + PyMem_Free(buf); + return NULL; + } else if (! CryptGenRandom(hcp, (DWORD) nbytes, (BYTE *) buf)) { + PyErr_Format(PyExc_SystemError, + "CryptGenRandom failed, error %i", + GetLastError()); + PyMem_Free(buf); + (void) CryptReleaseContext(hcp, 0); + return NULL; + } + if (! CryptReleaseContext(hcp, 0)) { + PyErr_Format(PyExc_SystemError, + "CryptReleaseContext failed, error %i", + GetLastError()); + return NULL; + } + res = PyString_FromStringAndSize(buf, n); + PyMem_Free(buf); + return res; +} + +static PyMethodDef WRMethods[] = { + {"winrandom", (PyCFunction) winrandom, METH_VARARGS, winrandom__doc__}, + {NULL, NULL} /* Sentinel */ +}; + + +void +initwinrandom() +{ + (void) Py_InitModule("winrandom", WRMethods); +} + +#endif /* MS_WIN32 */ |