Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / tlslite / tlslite / utils / entropy.c
1
2 #include "Python.h"
3
4
5 #ifdef MS_WINDOWS
6
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
10
11 #include <windows.h>
12
13
14 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
15               LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
16               DWORD dwFlags );
17 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
18               BYTE *pbBuffer );
19 typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
20               DWORD dwFlags);
21
22
23 static PyObject* entropy(PyObject *self, PyObject *args)
24 {
25     int howMany = 0;
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;
33
34
35     /* Read arguments */
36     if (!PyArg_ParseTuple(args, "i", &howMany))
37         return(NULL);
38
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");
44         return NULL;
45         }
46
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,\
52                           "CryptGenRandom");
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");
59         return NULL;
60         }
61
62     /* Allocate bytes */
63     if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
64         return PyErr_NoMemory();
65
66
67     /* Acquire context */
68     if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
69                             CRYPT_VERIFYCONTEXT)) {
70         PyErr_Format(PyExc_SystemError,
71                      "CryptAcquireContext failed, error %d", GetLastError());
72         PyMem_Free(bytes);
73         return NULL;
74     }
75
76     /* Get random data */
77     if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
78         PyErr_Format(PyExc_SystemError,
79                      "CryptGenRandom failed, error %d", GetLastError());
80         PyMem_Free(bytes);
81         CryptReleaseContext(hCryptProv, 0);
82         return NULL;
83     }
84
85     /* Build return value */
86     returnVal = Py_BuildValue("s#", bytes, howMany);
87     PyMem_Free(bytes);
88
89     /* Release context */
90     if (!pCryptReleaseContext(hCryptProv, 0)) {
91         PyErr_Format(PyExc_SystemError,
92                      "CryptReleaseContext failed, error %d", GetLastError());
93         return NULL;
94     }
95
96     return returnVal;
97 }
98
99 #elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
100
101 #include <unistd.h>
102 #include <fcntl.h>
103
104 static PyObject* entropy(PyObject *self, PyObject *args)
105 {
106     int howMany;
107     int fd;
108     unsigned char* bytes = NULL;
109     PyObject* returnVal = NULL;
110
111
112     /* Read arguments */
113     if (!PyArg_ParseTuple(args, "i", &howMany))
114         return(NULL);
115
116     /* Allocate bytes */
117     if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
118         return PyErr_NoMemory();
119
120     /* Open device */
121     if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
122         PyErr_Format(PyExc_NotImplementedError,
123             "No entropy source found");
124         PyMem_Free(bytes);
125         return NULL;
126     }
127
128     /* Get random data */
129     if (read(fd, bytes, howMany) < howMany) {
130         PyErr_Format(PyExc_SystemError,
131             "Reading from /dev/urandom failed");
132         PyMem_Free(bytes);
133         close(fd);
134         return NULL;
135     }
136
137     /* Build return value */
138     returnVal = Py_BuildValue("s#", bytes, howMany);
139     PyMem_Free(bytes);
140
141     /* Close device */
142     close(fd);
143
144     return returnVal;
145 }
146
147 #else
148
149 static PyObject* entropy(PyObject *self, PyObject *args)
150 {
151     PyErr_Format(PyExc_NotImplementedError,
152             "Function not supported");
153     return NULL;
154 }
155
156 #endif
157
158
159
160 /* List of functions exported by this module */
161
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 */
165 };
166
167
168 /* Initialize this module. */
169
170 PyMODINIT_FUNC initentropy(void)
171 {
172     Py_InitModule("entropy", entropy_functions);
173 }