summaryrefslogtreecommitdiff
path: root/src/winrand.c
diff options
context:
space:
mode:
authormoraes <moraes@rivest.dlitz.net>2002-10-23 04:52:20 -0700
committermoraes <moraes@rivest.dlitz.net>2002-10-23 04:52:20 -0700
commita317dcc290cd7eab22cb23e83e5e88fc33a40fc7 (patch)
treece6b935eecf95fce89be0030862e01ab7d1d4482 /src/winrand.c
parent8ad4547afb76a4bd5474e1f04877895ff83ce241 (diff)
downloadpycrypto-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.c86
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 */