7 /* The following #define is not needed on VC6 with the Platform SDK, and it
8 may not be needed on VC7, I'm not sure. I don't think it hurts anything.*/
9 #define _WIN32_WINNT 0x0400
14 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
15 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
17 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
19 typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
23 static PyObject* entropy(PyObject *self, PyObject *args)
26 HINSTANCE hAdvAPI32 = NULL;
27 CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
28 CRYPTGENRANDOM pCryptGenRandom = NULL;
29 CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
30 HCRYPTPROV hCryptProv = 0;
31 unsigned char* bytes = NULL;
32 PyObject* returnVal = NULL;
36 if (!PyArg_ParseTuple(args, "i", &howMany))
39 /* Obtain handle to the DLL containing CryptoAPI
40 This should not fail */
41 if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) {
42 PyErr_Format(PyExc_SystemError,
43 "Advapi32.dll not found");
47 /* Obtain pointers to the CryptoAPI functions
48 This will fail on some early version of Win95 */
49 pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\
50 "CryptAcquireContextA");
51 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\
53 pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\
54 "CryptReleaseContext");
55 if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL ||
56 pCryptReleaseContext == NULL) {
57 PyErr_Format(PyExc_NotImplementedError,
58 "CryptoAPI not available on this version of Windows");
63 if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
64 return PyErr_NoMemory();
68 if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
69 CRYPT_VERIFYCONTEXT)) {
70 PyErr_Format(PyExc_SystemError,
71 "CryptAcquireContext failed, error %d", GetLastError());
77 if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
78 PyErr_Format(PyExc_SystemError,
79 "CryptGenRandom failed, error %d", GetLastError());
81 CryptReleaseContext(hCryptProv, 0);
85 /* Build return value */
86 returnVal = Py_BuildValue("s#", bytes, howMany);
90 if (!pCryptReleaseContext(hCryptProv, 0)) {
91 PyErr_Format(PyExc_SystemError,
92 "CryptReleaseContext failed, error %d", GetLastError());
99 #elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
104 static PyObject* entropy(PyObject *self, PyObject *args)
108 unsigned char* bytes = NULL;
109 PyObject* returnVal = NULL;
113 if (!PyArg_ParseTuple(args, "i", &howMany))
117 if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
118 return PyErr_NoMemory();
121 if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
122 PyErr_Format(PyExc_NotImplementedError,
123 "No entropy source found");
128 /* Get random data */
129 if (read(fd, bytes, howMany) < howMany) {
130 PyErr_Format(PyExc_SystemError,
131 "Reading from /dev/urandom failed");
137 /* Build return value */
138 returnVal = Py_BuildValue("s#", bytes, howMany);
149 static PyObject* entropy(PyObject *self, PyObject *args)
151 PyErr_Format(PyExc_NotImplementedError,
152 "Function not supported");
160 /* List of functions exported by this module */
162 static struct PyMethodDef entropy_functions[] = {
163 {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."},
164 {NULL, NULL} /* Sentinel */
168 /* Initialize this module. */
170 PyMODINIT_FUNC initentropy(void)
172 Py_InitModule("entropy", entropy_functions);