blob: bc96226309b002ed337be25d58abbaf20281c440 [file] [log] [blame]
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001#include "Python.h"
2#ifdef MS_WINDOWS
Victor Stinner59f7fb22015-03-18 14:39:33 +01003# include <windows.h>
Martin Panterd2f87472016-07-29 04:00:44 +00004/* All sample MSDN wincrypt programs include the header below. It is at least
5 * required with Min GW. */
6# include <wincrypt.h>
Georg Brandl2daf6ae2012-02-20 19:54:16 +01007#else
Victor Stinner59f7fb22015-03-18 14:39:33 +01008# include <fcntl.h>
9# ifdef HAVE_SYS_STAT_H
10# include <sys/stat.h>
11# endif
Victor Stinnerdddf4842016-06-07 11:21:42 +020012# ifdef HAVE_LINUX_RANDOM_H
13# include <linux/random.h>
14# endif
Benjamin Peterson493ac1b2017-01-01 22:29:36 -060015# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY))
Victor Stinnerbae2d622015-10-01 09:47:30 +020016# include <sys/random.h>
Ned Deily7ae41122016-11-12 16:35:48 -050017# endif
18# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinner59f7fb22015-03-18 14:39:33 +010019# include <sys/syscall.h>
Victor Stinner59f7fb22015-03-18 14:39:33 +010020# endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010021#endif
22
Benjamin Peterson69e97272012-02-21 11:08:50 -050023#ifdef Py_DEBUG
24int _Py_HashSecret_Initialized = 0;
25#else
26static int _Py_HashSecret_Initialized = 0;
27#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010028
29#ifdef MS_WINDOWS
Georg Brandl2daf6ae2012-02-20 19:54:16 +010030static HCRYPTPROV hCryptProv = 0;
31
32static int
33win32_urandom_init(int raise)
34{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010035 /* Acquire context */
Martin v. Löwis3f50bf62013-01-25 14:06:18 +010036 if (!CryptAcquireContext(&hCryptProv, NULL, NULL,
37 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010038 goto error;
39
40 return 0;
41
42error:
Victor Stinner4bad3b62016-08-16 15:23:58 +020043 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010044 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020045 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010046 return -1;
47}
48
49/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
Victor Stinner4d6a3d62014-12-21 01:16:38 +010050 API. Return 0 on success, or raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +010051static int
52win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
53{
54 Py_ssize_t chunk;
55
56 if (hCryptProv == 0)
57 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020058 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010059 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020060 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010061 }
62
63 while (size > 0)
64 {
65 chunk = size > INT_MAX ? INT_MAX : size;
Victor Stinner0c083462013-11-15 23:26:25 +010066 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010067 {
68 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020069 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010070 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020071 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010072 return -1;
73 }
74 buffer += chunk;
75 size -= chunk;
76 }
77 return 0;
78}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010079
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010080#else /* !MS_WINDOWS */
81
Victor Stinner2f796432017-01-06 11:26:01 +010082#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020083#define PY_GETRANDOM 1
84
Victor Stinner6974cf22016-08-16 18:46:38 +020085/* Call getrandom()
86 - Return 1 on success
Victor Stinner6d8bc462016-09-20 22:46:02 +020087 - Return 0 if getrandom() syscall is not available (failed with ENOSYS or
88 EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom
Victor Stinneraf597322016-09-20 22:26:18 +020089 not initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +020090 - Raise an exception (if raise is non-zero) and return -1 on error:
91 getrandom() failed with EINTR and the Python signal handler raised an
92 exception, or getrandom() failed with a different error. */
Victor Stinner59f7fb22015-03-18 14:39:33 +010093static int
Victor Stinnere66987e2016-09-06 16:33:52 -070094py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +010095{
Victor Stinnere66987e2016-09-06 16:33:52 -070096 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +020097 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +020098 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +010099 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700100 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200101 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200102 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100103
Victor Stinner6974cf22016-08-16 18:46:38 +0200104 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100105 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200106 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100107
Victor Stinnere66987e2016-09-06 16:33:52 -0700108 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200109 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100110 while (0 < size) {
Victor Stinner9d242712016-04-12 22:28:49 +0200111#ifdef sun
112 /* Issue #26735: On Solaris, getrandom() is limited to returning up
113 to 1024 bytes */
114 n = Py_MIN(size, 1024);
115#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200116 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200117#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200118
Victor Stinner9d242712016-04-12 22:28:49 +0200119 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200120#ifdef HAVE_GETRANDOM
121 if (raise) {
122 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200123 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200124 Py_END_ALLOW_THREADS
125 }
126 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200127 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200128 }
129#else
130 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200131 expose the Linux getrandom() syscall yet. See:
132 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200133 if (raise) {
134 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200135 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200136 Py_END_ALLOW_THREADS
137 }
138 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200139 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200140 }
Victor Stinnerbae2d622015-10-01 09:47:30 +0200141#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200142
Victor Stinner59f7fb22015-03-18 14:39:33 +0100143 if (n < 0) {
Victor Stinneraf597322016-09-20 22:26:18 +0200144 /* ENOSYS: getrandom() syscall not supported by the kernel (but
Victor Stinner6d8bc462016-09-20 22:46:02 +0200145 * maybe supported by the host which built Python). EPERM:
146 * getrandom() syscall blocked by SECCOMP or something else. */
147 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100148 getrandom_works = 0;
149 return 0;
150 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200151
Victor Stinnere66987e2016-09-06 16:33:52 -0700152 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
153 is not initialiazed yet. For _PyRandom_Init(), we ignore their
154 error and fall back on reading /dev/urandom which never blocks,
155 even if the system urandom is not initialized yet. */
156 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200157 return 0;
158 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100159
160 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200161 if (raise) {
162 if (PyErr_CheckSignals()) {
163 return -1;
164 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100165 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200166
167 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100168 continue;
169 }
170
Victor Stinner4bad3b62016-08-16 15:23:58 +0200171 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100172 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200173 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100174 return -1;
175 }
176
Victor Stinnercfb19612016-06-08 10:16:50 +0200177 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100178 size -= n;
179 }
180 return 1;
181}
Victor Stinner2f796432017-01-06 11:26:01 +0100182
183#elif defined(HAVE_GETENTROPY)
184#define PY_GETENTROPY 1
185
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100186/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100187
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100188 - Return 1 on success
189 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
190 EPERM).
191 - Raise an exception (if raise is non-zero) and return -1 on error:
192 if getentropy() failed with EINTR, raise is non-zero and the Python signal
193 handler raised an exception, or if getentropy() failed with a different
194 error.
195
196 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner2f796432017-01-06 11:26:01 +0100197static int
198py_getentropy(char *buffer, Py_ssize_t size, int raise)
199{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100200 /* Is getentropy() supported by the running kernel? Set to 0 if
201 getentropy() failed with ENOSYS or EPERM. */
202 static int getentropy_works = 1;
203
204 if (!getentropy_works) {
205 return 0;
206 }
207
Victor Stinner2f796432017-01-06 11:26:01 +0100208 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100209 /* getentropy() is limited to returning up to 256 bytes. Call it
210 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100211 Py_ssize_t len = Py_MIN(size, 256);
212 int res;
213
214 if (raise) {
215 Py_BEGIN_ALLOW_THREADS
216 res = getentropy(buffer, len);
217 Py_END_ALLOW_THREADS
218 }
219 else {
220 res = getentropy(buffer, len);
221 }
222
223 if (res < 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100224 /* ENOSYS: the syscall is not supported by the running kernel.
225 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
226 or something else. */
227 if (errno == ENOSYS || errno == EPERM) {
228 getentropy_works = 0;
229 return 0;
230 }
231
232 if (errno == EINTR) {
233 if (raise) {
234 if (PyErr_CheckSignals()) {
235 return -1;
236 }
237 }
238
239 /* retry getentropy() if it was interrupted by a signal */
240 continue;
241 }
242
Victor Stinner2f796432017-01-06 11:26:01 +0100243 if (raise) {
244 PyErr_SetFromErrno(PyExc_OSError);
245 }
246 return -1;
247 }
248
249 buffer += len;
250 size -= len;
251 }
252 return 1;
253}
254#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100255
Victor Stinner59f7fb22015-03-18 14:39:33 +0100256
Antoine Pitroue472aea2014-04-26 14:33:03 +0200257static struct {
258 int fd;
259 dev_t st_dev;
260 ino_t st_ino;
261} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100262
Victor Stinnera49a2072017-01-06 11:17:52 +0100263/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200264
Victor Stinnera49a2072017-01-06 11:17:52 +0100265 - Return 0 on success
266 - Raise an exception (if raise is non-zero) and return -1 on error
267
268 Possible causes of errors:
269
270 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
271 was not found. For example, it was removed manually or not exposed in a
272 chroot or container.
273 - open() failed with a different error
274 - fstat() failed
275 - read() failed or returned 0
276
277 read() is retried if it failed with EINTR: interrupted by a signal.
278
279 The file descriptor of the device is kept open between calls to avoid using
280 many file descriptors when run in parallel from multiple threads:
281 see the issue #18756.
282
283 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
284 check if the file descriptor was replaced by a different file (which is
285 likely a bug in the application): see the issue #21207.
286
287 If the file descriptor was closed or replaced, open a new file descriptor
288 but don't close the old file descriptor: it probably points to something
289 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200290static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100291dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100292{
293 int fd;
294 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200295
296 if (raise) {
297 struct _Py_stat_struct st;
298
Antoine Pitroue472aea2014-04-26 14:33:03 +0200299 if (urandom_cache.fd >= 0) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200300 /* Does the fd point to the same thing as before? (issue #21207) */
301 if (_Py_fstat_noraise(urandom_cache.fd, &st)
302 || st.st_dev != urandom_cache.st_dev
303 || st.st_ino != urandom_cache.st_ino) {
304 /* Something changed: forget the cached fd (but don't close it,
305 since it probably points to something important for some
306 third-party code). */
307 urandom_cache.fd = -1;
308 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200309 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200310 if (urandom_cache.fd >= 0)
311 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200312 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200313 fd = _Py_open("/dev/urandom", O_RDONLY);
314 if (fd < 0) {
315 if (errno == ENOENT || errno == ENXIO ||
316 errno == ENODEV || errno == EACCES)
317 PyErr_SetString(PyExc_NotImplementedError,
318 "/dev/urandom (or equivalent) not found");
319 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200320 return -1;
321 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200322 if (urandom_cache.fd >= 0) {
323 /* urandom_fd was initialized by another thread while we were
324 not holding the GIL, keep it. */
325 close(fd);
326 fd = urandom_cache.fd;
327 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200328 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200329 if (_Py_fstat(fd, &st)) {
330 close(fd);
331 return -1;
332 }
333 else {
334 urandom_cache.fd = fd;
335 urandom_cache.st_dev = st.st_dev;
336 urandom_cache.st_ino = st.st_ino;
337 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200338 }
339 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100340
Victor Stinner6974cf22016-08-16 18:46:38 +0200341 do {
342 n = _Py_read(fd, buffer, (size_t)size);
343 if (n == -1)
344 return -1;
345 if (n == 0) {
346 PyErr_Format(PyExc_RuntimeError,
347 "Failed to read %zi bytes from /dev/urandom",
348 size);
349 return -1;
350 }
351
352 buffer += n;
353 size -= n;
354 } while (0 < size);
355 }
356 else {
357 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
358 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100359 return -1;
360 }
361
Victor Stinner6974cf22016-08-16 18:46:38 +0200362 while (0 < size)
363 {
364 do {
365 n = read(fd, buffer, (size_t)size);
366 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100367
Victor Stinner6974cf22016-08-16 18:46:38 +0200368 if (n <= 0) {
369 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200370 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200371 return -1;
372 }
373
374 buffer += n;
375 size -= n;
376 }
377 close(fd);
378 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100379 return 0;
380}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200381
382static void
383dev_urandom_close(void)
384{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200385 if (urandom_cache.fd >= 0) {
386 close(urandom_cache.fd);
387 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200388 }
389}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100390#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200391
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100392
393/* Fill buffer with pseudo-random bytes generated by a linear congruent
394 generator (LCG):
395
396 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
397
398 Use bits 23..16 of x(n) to generate a byte. */
399static void
400lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
401{
402 size_t index;
403 unsigned int x;
404
405 x = x0;
406 for (index=0; index < size; index++) {
407 x *= 214013;
408 x += 2531011;
409 /* modulo 2 ^ (8 * sizeof(int)) */
410 buffer[index] = (x >> 16) & 0xff;
411 }
412}
413
Victor Stinnera49a2072017-01-06 11:17:52 +0100414/* Read random bytes:
415
416 - Return 0 on success
417 - Raise an exception (if raise is non-zero) and return -1 on error
418
419 Used sources of entropy ordered by preference, preferred source first:
420
421 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100422 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100423 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100424 - /dev/urandom device
425
426 Read from the /dev/urandom device if getrandom() or getentropy() function
427 is not available or does not work.
428
Victor Stinner2f796432017-01-06 11:26:01 +0100429 Prefer getrandom() over getentropy() because getrandom() supports blocking
430 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
431 startup to initialize its hash secret, but os.urandom() must block until the
432 system urandom is initialized (at least on Linux 3.17 and newer).
433
Victor Stinnera49a2072017-01-06 11:17:52 +0100434 Prefer getrandom() and getentropy() over reading directly /dev/urandom
435 because these functions don't need file descriptors and so avoid ENFILE or
436 EMFILE errors (too many open files): see the issue #18756.
437
438 Only the getrandom() function supports non-blocking mode.
439
440 Only use RNG running in the kernel. They are more secure because it is
441 harder to get the internal state of a RNG running in the kernel land than a
442 RNG running in the user land. The kernel has a direct access to the hardware
443 and has access to hardware RNG, they are used as entropy sources.
444
445 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
446 its RNG on fork(), two child processes (with the same pid) generate the same
447 random numbers: see issue #18747. Kernel RNGs don't have this issue,
448 they have access to good quality entropy sources.
449
450 If raise is zero:
451
452 - Don't raise an exception on error
453 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
454 a function fails with EINTR: retry directly the interrupted function
455 - Don't release the GIL to call functions.
456*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200457static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700458pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200459{
Victor Stinnera49a2072017-01-06 11:17:52 +0100460#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
461 int res;
462#endif
463
Victor Stinner4bad3b62016-08-16 15:23:58 +0200464 if (size < 0) {
465 if (raise) {
466 PyErr_Format(PyExc_ValueError,
467 "negative argument not allowed");
468 }
469 return -1;
470 }
471
472 if (size == 0) {
473 return 0;
474 }
475
476#ifdef MS_WINDOWS
477 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200478#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100479
480#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Victor Stinner2f796432017-01-06 11:26:01 +0100481#ifdef PY_GETRANDOM
Victor Stinnera49a2072017-01-06 11:17:52 +0100482 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100483#else
484 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100485#endif
486 if (res < 0) {
487 return -1;
488 }
489 if (res == 1) {
490 return 0;
491 }
492 /* getrandom() or getentropy() function is not available: failed with
493 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
494#endif
495
496 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200497#endif
498}
499
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200500/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200501 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200502 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100503
Victor Stinnere66987e2016-09-06 16:33:52 -0700504 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
505 block until the system urandom entropy pool is initialized (128 bits are
506 collected by the kernel).
507
508 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100509int
510_PyOS_URandom(void *buffer, Py_ssize_t size)
511{
Victor Stinnere66987e2016-09-06 16:33:52 -0700512 return pyurandom(buffer, size, 1, 1);
513}
514
515/* Fill buffer with size pseudo-random bytes from the operating system random
516 number generator (RNG). It is not suitable for cryptographic purpose.
517
518 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
519 urandom is not initialized yet, the function returns "weak" entropy read
520 from /dev/urandom.
521
522 Return 0 on success. Raise an exception and return -1 on error. */
523int
524_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
525{
526 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100527}
528
529void
530_PyRandom_Init(void)
531{
532 char *env;
Christian Heimes985ecdc2013-11-20 11:46:18 +0100533 unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500534 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Serhiy Storchakafad85aa2015-11-07 15:42:38 +0200535 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100536
Benjamin Peterson69e97272012-02-21 11:08:50 -0500537 if (_Py_HashSecret_Initialized)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100538 return;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500539 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100540
541 /*
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100542 Hash randomization is enabled. Generate a per-process secret,
543 using PYTHONHASHSEED if provided.
544 */
545
546 env = Py_GETENV("PYTHONHASHSEED");
Georg Brandl12897d72012-02-20 23:49:29 +0100547 if (env && *env != '\0' && strcmp(env, "random") != 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100548 char *endptr = env;
549 unsigned long seed;
550 seed = strtoul(env, &endptr, 10);
551 if (*endptr != '\0'
552 || seed > 4294967295UL
553 || (errno == ERANGE && seed == ULONG_MAX))
554 {
555 Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
556 "in range [0; 4294967295]");
557 }
558 if (seed == 0) {
559 /* disable the randomized hash */
560 memset(secret, 0, secret_size);
561 }
562 else {
Christian Heimes985ecdc2013-11-20 11:46:18 +0100563 lcg_urandom(seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100564 }
565 }
566 else {
Victor Stinner4bad3b62016-08-16 15:23:58 +0200567 int res;
568
569 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700570 and so exceptions cannot be used (use raise=0).
571
572 _PyRandom_Init() must not block Python initialization: call
573 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
574 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200575 if (res < 0) {
576 Py_FatalError("failed to get random numbers to initialize Python");
577 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100578 }
579}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200580
581void
582_PyRandom_Fini(void)
583{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200584#ifdef MS_WINDOWS
585 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100586 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200587 hCryptProv = 0;
588 }
589#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200590 dev_urandom_close();
591#endif
592}