blob: f1c8440ec3263b367b44dc311d7e30c070cf0ae9 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * rand.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * PRNG management routines, thin wrappers.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
12
13/*
14 * In order to get the RAND_screen definition from the rand.h
15 * WIN32 or WINDOWS needs to be defined, otherwise we get a
16 * warning.
17 */
Jean-Paul Calderone7ef4ee22008-12-29 16:45:27 -050018#ifdef MS_WINDOWS
19# ifndef WIN32
20# define WIN32
21# endif
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050022#endif
23#include <openssl/rand.h>
24
25static char rand_doc[] = "\n\
26PRNG management routines, thin wrappers.\n\
27See the file RATIONALE for a short explanation of why this module was written.\n\
28";
29
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050030static char rand_add_doc[] = "\n\
31Add data with a given entropy to the PRNG\n\
32\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040033@param buffer: Buffer with random data\n\
34@param entropy: The entropy (in bytes) measurement of the buffer\n\
35@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050036";
37
38static PyObject *
39rand_add(PyObject *spam, PyObject *args)
40{
41 char *buf;
42 int size;
43 double entropy;
44
45 if (!PyArg_ParseTuple(args, "s#d:add", &buf, &size, &entropy))
46 return NULL;
47
48 RAND_add(buf, size, entropy);
49
50 Py_INCREF(Py_None);
51 return Py_None;
52}
53
54static char rand_seed_doc[] = "\n\
55Alias for rand_add, with entropy equal to length\n\
56\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040057@param buffer: Buffer with random data\n\
58@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050059";
60
61static PyObject *
62rand_seed(PyObject *spam, PyObject *args)
63{
64 char *buf;
65 int size;
66
67 if (!PyArg_ParseTuple(args, "s#:seed", &buf, &size))
68 return NULL;
69
70 RAND_seed(buf, size);
71
72 Py_INCREF(Py_None);
73 return Py_None;
74}
75
76static char rand_status_doc[] = "\n\
77Retrieve the status of the PRNG\n\
78\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040079@return: True if the PRNG is seeded enough, false otherwise\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050080";
81
82static PyObject *
83rand_status(PyObject *spam, PyObject *args)
84{
85 if (!PyArg_ParseTuple(args, ":status"))
86 return NULL;
87
88 return PyInt_FromLong((long)RAND_status());
89}
90
91#ifdef MS_WINDOWS
92static char rand_screen_doc[] = "\n\
93Add the current contents of the screen to the PRNG state. Availability:\n\
94Windows.\n\
95\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040096@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050097";
98
99static PyObject *
100rand_screen(PyObject *spam, PyObject *args)
101{
102 if (!PyArg_ParseTuple(args, ":screen"))
103 return NULL;
104
105 RAND_screen();
106 Py_INCREF(Py_None);
107 return Py_None;
108}
109#endif
110
111static char rand_egd_doc[] = "\n\
112Query an entropy gathering daemon (EGD) for random data and add it to the\n\
113PRNG. I haven't found any problems when the socket is missing, the function\n\
114just returns 0.\n\
115\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400116@param path: The path to the EGD socket\n\
117@param bytes: (optional) The number of bytes to read, default is 255\n\
118@returns: The number of bytes read (NB: a value of 0 isn't necessarily an\n\
119 error, check rand.status())\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500120";
121
122static PyObject *
123rand_egd(PyObject *spam, PyObject *args)
124{
125 char *path;
126 int bytes = 255;
127
128 if (!PyArg_ParseTuple(args, "s|i:egd", &path, &bytes))
129 return NULL;
130
131 return PyInt_FromLong((long)RAND_egd_bytes(path, bytes));
132}
133
134static char rand_cleanup_doc[] = "\n\
135Erase the memory used by the PRNG.\n\
136\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400137@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500138";
139
140static PyObject *
141rand_cleanup(PyObject *spam, PyObject *args)
142{
143 if (!PyArg_ParseTuple(args, ":cleanup"))
144 return NULL;
145
146 RAND_cleanup();
147
148 Py_INCREF(Py_None);
149 return Py_None;
150}
151
152static char rand_load_file_doc[] = "\n\
153Seed the PRNG with data from a file\n\
154\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400155@param filename: The file to read data from\n\
156@param maxbytes: (optional) The number of bytes to read, default is\n\
157 to read the entire file\n\
158@return: The number of bytes read\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500159";
160
161static PyObject *
162rand_load_file(PyObject *spam, PyObject *args)
163{
164 char *filename;
165 int maxbytes = -1;
166
167 if (!PyArg_ParseTuple(args, "s|i:load_file", &filename, &maxbytes))
168 return NULL;
169
170 return PyInt_FromLong((long)RAND_load_file(filename, maxbytes));
171}
172
173static char rand_write_file_doc[] = "\n\
174Save PRNG state to a file\n\
175\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400176@param filename: The file to write data to\n\
177@return: The number of bytes written\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500178";
179
180static PyObject *
181rand_write_file(PyObject *spam, PyObject *args)
182{
183 char *filename;
184
185 if (!PyArg_ParseTuple(args, "s:write_file", &filename))
186 return NULL;
187
188 return PyInt_FromLong((long)RAND_write_file(filename));
189}
190
191
192/* Methods in the OpenSSL.rand module */
193static PyMethodDef rand_methods[] = {
194 { "add", (PyCFunction)rand_add, METH_VARARGS, rand_add_doc },
195 { "seed", (PyCFunction)rand_seed, METH_VARARGS, rand_seed_doc },
196 { "status", (PyCFunction)rand_status, METH_VARARGS, rand_status_doc },
197#ifdef MS_WINDOWS
198 { "screen", (PyCFunction)rand_screen, METH_VARARGS, rand_screen_doc },
199#endif
200 { "egd", (PyCFunction)rand_egd, METH_VARARGS, rand_egd_doc },
201 { "cleanup", (PyCFunction)rand_cleanup, METH_VARARGS, rand_cleanup_doc },
202 { "load_file", (PyCFunction)rand_load_file, METH_VARARGS, rand_load_file_doc },
203 { "write_file",(PyCFunction)rand_write_file, METH_VARARGS, rand_write_file_doc },
204 { NULL, NULL }
205};
206
207
208/*
209 * Initialize the rand sub module
210 *
211 * Arguments: None
212 * Returns: None
213 */
214void
215initrand(void)
216{
217 PyObject *module;
218
219 ERR_load_RAND_strings();
220
221 if ((module = Py_InitModule3("rand", rand_methods, rand_doc)) == NULL)
222 return;
223}
224