blob: 32c85fc2ff0e39859301031f80cb0ef821213870 [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
Martin Panter39b10252016-06-10 08:07:11 +000082/* Issue #25003: Don't use getentropy() on Solaris (available since
Victor Stinnere66987e2016-09-06 16:33:52 -070083 * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010084#if defined(HAVE_GETENTROPY) && !defined(sun)
Victor Stinnerbae2d622015-10-01 09:47:30 +020085#define PY_GETENTROPY 1
86
Victor Stinner4d6a3d62014-12-21 01:16:38 +010087/* Fill buffer with size pseudo-random bytes generated by getentropy().
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010088 Return 1 on success, or raise an exception and return -1 on error.
Georg Brandl2daf6ae2012-02-20 19:54:16 +010089
Victor Stinner4bad3b62016-08-16 15:23:58 +020090 If raise is zero, don't raise an exception on error. */
Victor Stinner4d6a3d62014-12-21 01:16:38 +010091static int
Victor Stinner4bad3b62016-08-16 15:23:58 +020092py_getentropy(char *buffer, Py_ssize_t size, int raise)
Victor Stinner4d6a3d62014-12-21 01:16:38 +010093{
94 while (size > 0) {
95 Py_ssize_t len = Py_MIN(size, 256);
Victor Stinner9aa13312015-03-30 11:18:30 +020096 int res;
97
Victor Stinner4bad3b62016-08-16 15:23:58 +020098 if (raise) {
Victor Stinner9aa13312015-03-30 11:18:30 +020099 Py_BEGIN_ALLOW_THREADS
100 res = getentropy(buffer, len);
101 Py_END_ALLOW_THREADS
Victor Stinner4d6a3d62014-12-21 01:16:38 +0100102 }
Victor Stinner9aa13312015-03-30 11:18:30 +0200103 else {
104 res = getentropy(buffer, len);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200105 }
106
107 if (res < 0) {
108 if (raise) {
109 PyErr_SetFromErrno(PyExc_OSError);
110 }
111 return -1;
Victor Stinner9aa13312015-03-30 11:18:30 +0200112 }
113
Victor Stinner4d6a3d62014-12-21 01:16:38 +0100114 buffer += len;
115 size -= len;
116 }
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100117 return 1;
Victor Stinner4d6a3d62014-12-21 01:16:38 +0100118}
119
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100120#elif defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +0200121#define PY_GETRANDOM 1
122
Victor Stinner6974cf22016-08-16 18:46:38 +0200123/* Call getrandom()
124 - Return 1 on success
Victor Stinner6d8bc462016-09-20 22:46:02 +0200125 - Return 0 if getrandom() syscall is not available (failed with ENOSYS or
126 EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom
Victor Stinneraf597322016-09-20 22:26:18 +0200127 not initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +0200128 - Raise an exception (if raise is non-zero) and return -1 on error:
129 getrandom() failed with EINTR and the Python signal handler raised an
130 exception, or getrandom() failed with a different error. */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100131static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700132py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +0100133{
Victor Stinnere66987e2016-09-06 16:33:52 -0700134 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200135 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200136 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100137 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700138 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200139 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200140 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100141
Victor Stinner6974cf22016-08-16 18:46:38 +0200142 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100143 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200144 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100145
Victor Stinnere66987e2016-09-06 16:33:52 -0700146 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200147 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100148 while (0 < size) {
Victor Stinner9d242712016-04-12 22:28:49 +0200149#ifdef sun
150 /* Issue #26735: On Solaris, getrandom() is limited to returning up
151 to 1024 bytes */
152 n = Py_MIN(size, 1024);
153#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200154 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200155#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200156
Victor Stinner9d242712016-04-12 22:28:49 +0200157 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200158#ifdef HAVE_GETRANDOM
159 if (raise) {
160 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200161 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200162 Py_END_ALLOW_THREADS
163 }
164 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200165 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200166 }
167#else
168 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200169 expose the Linux getrandom() syscall yet. See:
170 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200171 if (raise) {
172 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200173 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200174 Py_END_ALLOW_THREADS
175 }
176 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200177 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200178 }
Victor Stinnerbae2d622015-10-01 09:47:30 +0200179#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200180
Victor Stinner59f7fb22015-03-18 14:39:33 +0100181 if (n < 0) {
Victor Stinneraf597322016-09-20 22:26:18 +0200182 /* ENOSYS: getrandom() syscall not supported by the kernel (but
Victor Stinner6d8bc462016-09-20 22:46:02 +0200183 * maybe supported by the host which built Python). EPERM:
184 * getrandom() syscall blocked by SECCOMP or something else. */
185 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100186 getrandom_works = 0;
187 return 0;
188 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200189
Victor Stinnere66987e2016-09-06 16:33:52 -0700190 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
191 is not initialiazed yet. For _PyRandom_Init(), we ignore their
192 error and fall back on reading /dev/urandom which never blocks,
193 even if the system urandom is not initialized yet. */
194 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200195 return 0;
196 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100197
198 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200199 if (raise) {
200 if (PyErr_CheckSignals()) {
201 return -1;
202 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100203 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200204
205 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100206 continue;
207 }
208
Victor Stinner4bad3b62016-08-16 15:23:58 +0200209 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100210 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200211 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100212 return -1;
213 }
214
Victor Stinnercfb19612016-06-08 10:16:50 +0200215 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100216 size -= n;
217 }
218 return 1;
219}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100220#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) */
221
Victor Stinner59f7fb22015-03-18 14:39:33 +0100222
Antoine Pitroue472aea2014-04-26 14:33:03 +0200223static struct {
224 int fd;
225 dev_t st_dev;
226 ino_t st_ino;
227} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100228
Victor Stinnera49a2072017-01-06 11:17:52 +0100229/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200230
Victor Stinnera49a2072017-01-06 11:17:52 +0100231 - Return 0 on success
232 - Raise an exception (if raise is non-zero) and return -1 on error
233
234 Possible causes of errors:
235
236 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
237 was not found. For example, it was removed manually or not exposed in a
238 chroot or container.
239 - open() failed with a different error
240 - fstat() failed
241 - read() failed or returned 0
242
243 read() is retried if it failed with EINTR: interrupted by a signal.
244
245 The file descriptor of the device is kept open between calls to avoid using
246 many file descriptors when run in parallel from multiple threads:
247 see the issue #18756.
248
249 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
250 check if the file descriptor was replaced by a different file (which is
251 likely a bug in the application): see the issue #21207.
252
253 If the file descriptor was closed or replaced, open a new file descriptor
254 but don't close the old file descriptor: it probably points to something
255 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200256static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100257dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100258{
259 int fd;
260 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200261
262 if (raise) {
263 struct _Py_stat_struct st;
264
Antoine Pitroue472aea2014-04-26 14:33:03 +0200265 if (urandom_cache.fd >= 0) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200266 /* Does the fd point to the same thing as before? (issue #21207) */
267 if (_Py_fstat_noraise(urandom_cache.fd, &st)
268 || st.st_dev != urandom_cache.st_dev
269 || st.st_ino != urandom_cache.st_ino) {
270 /* Something changed: forget the cached fd (but don't close it,
271 since it probably points to something important for some
272 third-party code). */
273 urandom_cache.fd = -1;
274 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200275 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200276 if (urandom_cache.fd >= 0)
277 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200278 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200279 fd = _Py_open("/dev/urandom", O_RDONLY);
280 if (fd < 0) {
281 if (errno == ENOENT || errno == ENXIO ||
282 errno == ENODEV || errno == EACCES)
283 PyErr_SetString(PyExc_NotImplementedError,
284 "/dev/urandom (or equivalent) not found");
285 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200286 return -1;
287 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200288 if (urandom_cache.fd >= 0) {
289 /* urandom_fd was initialized by another thread while we were
290 not holding the GIL, keep it. */
291 close(fd);
292 fd = urandom_cache.fd;
293 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200294 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200295 if (_Py_fstat(fd, &st)) {
296 close(fd);
297 return -1;
298 }
299 else {
300 urandom_cache.fd = fd;
301 urandom_cache.st_dev = st.st_dev;
302 urandom_cache.st_ino = st.st_ino;
303 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200304 }
305 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100306
Victor Stinner6974cf22016-08-16 18:46:38 +0200307 do {
308 n = _Py_read(fd, buffer, (size_t)size);
309 if (n == -1)
310 return -1;
311 if (n == 0) {
312 PyErr_Format(PyExc_RuntimeError,
313 "Failed to read %zi bytes from /dev/urandom",
314 size);
315 return -1;
316 }
317
318 buffer += n;
319 size -= n;
320 } while (0 < size);
321 }
322 else {
323 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
324 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100325 return -1;
326 }
327
Victor Stinner6974cf22016-08-16 18:46:38 +0200328 while (0 < size)
329 {
330 do {
331 n = read(fd, buffer, (size_t)size);
332 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100333
Victor Stinner6974cf22016-08-16 18:46:38 +0200334 if (n <= 0) {
335 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200336 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200337 return -1;
338 }
339
340 buffer += n;
341 size -= n;
342 }
343 close(fd);
344 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100345 return 0;
346}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200347
348static void
349dev_urandom_close(void)
350{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200351 if (urandom_cache.fd >= 0) {
352 close(urandom_cache.fd);
353 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200354 }
355}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100356#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200357
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100358
359/* Fill buffer with pseudo-random bytes generated by a linear congruent
360 generator (LCG):
361
362 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
363
364 Use bits 23..16 of x(n) to generate a byte. */
365static void
366lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
367{
368 size_t index;
369 unsigned int x;
370
371 x = x0;
372 for (index=0; index < size; index++) {
373 x *= 214013;
374 x += 2531011;
375 /* modulo 2 ^ (8 * sizeof(int)) */
376 buffer[index] = (x >> 16) & 0xff;
377 }
378}
379
Victor Stinnera49a2072017-01-06 11:17:52 +0100380/* Read random bytes:
381
382 - Return 0 on success
383 - Raise an exception (if raise is non-zero) and return -1 on error
384
385 Used sources of entropy ordered by preference, preferred source first:
386
387 - CryptGenRandom() on Windows
388 - getentropy() function (ex: OpenBSD): call py_getentropy()
389 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
390 - /dev/urandom device
391
392 Read from the /dev/urandom device if getrandom() or getentropy() function
393 is not available or does not work.
394
395 Prefer getrandom() and getentropy() over reading directly /dev/urandom
396 because these functions don't need file descriptors and so avoid ENFILE or
397 EMFILE errors (too many open files): see the issue #18756.
398
399 Only the getrandom() function supports non-blocking mode.
400
401 Only use RNG running in the kernel. They are more secure because it is
402 harder to get the internal state of a RNG running in the kernel land than a
403 RNG running in the user land. The kernel has a direct access to the hardware
404 and has access to hardware RNG, they are used as entropy sources.
405
406 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
407 its RNG on fork(), two child processes (with the same pid) generate the same
408 random numbers: see issue #18747. Kernel RNGs don't have this issue,
409 they have access to good quality entropy sources.
410
411 If raise is zero:
412
413 - Don't raise an exception on error
414 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
415 a function fails with EINTR: retry directly the interrupted function
416 - Don't release the GIL to call functions.
417*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200418static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700419pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200420{
Victor Stinnera49a2072017-01-06 11:17:52 +0100421#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
422 int res;
423#endif
424
Victor Stinner4bad3b62016-08-16 15:23:58 +0200425 if (size < 0) {
426 if (raise) {
427 PyErr_Format(PyExc_ValueError,
428 "negative argument not allowed");
429 }
430 return -1;
431 }
432
433 if (size == 0) {
434 return 0;
435 }
436
437#ifdef MS_WINDOWS
438 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200439#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100440
441#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
442#ifdef PY_GETENTROPY
443 res = py_getentropy(buffer, size, raise);
444#else
445 res = py_getrandom(buffer, size, blocking, raise);
446#endif
447 if (res < 0) {
448 return -1;
449 }
450 if (res == 1) {
451 return 0;
452 }
453 /* getrandom() or getentropy() function is not available: failed with
454 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
455#endif
456
457 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200458#endif
459}
460
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200461/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200462 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200463 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100464
Victor Stinnere66987e2016-09-06 16:33:52 -0700465 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
466 block until the system urandom entropy pool is initialized (128 bits are
467 collected by the kernel).
468
469 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100470int
471_PyOS_URandom(void *buffer, Py_ssize_t size)
472{
Victor Stinnere66987e2016-09-06 16:33:52 -0700473 return pyurandom(buffer, size, 1, 1);
474}
475
476/* Fill buffer with size pseudo-random bytes from the operating system random
477 number generator (RNG). It is not suitable for cryptographic purpose.
478
479 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
480 urandom is not initialized yet, the function returns "weak" entropy read
481 from /dev/urandom.
482
483 Return 0 on success. Raise an exception and return -1 on error. */
484int
485_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
486{
487 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100488}
489
490void
491_PyRandom_Init(void)
492{
493 char *env;
Christian Heimes985ecdc2013-11-20 11:46:18 +0100494 unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500495 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Serhiy Storchakafad85aa2015-11-07 15:42:38 +0200496 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100497
Benjamin Peterson69e97272012-02-21 11:08:50 -0500498 if (_Py_HashSecret_Initialized)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100499 return;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500500 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100501
502 /*
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100503 Hash randomization is enabled. Generate a per-process secret,
504 using PYTHONHASHSEED if provided.
505 */
506
507 env = Py_GETENV("PYTHONHASHSEED");
Georg Brandl12897d72012-02-20 23:49:29 +0100508 if (env && *env != '\0' && strcmp(env, "random") != 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100509 char *endptr = env;
510 unsigned long seed;
511 seed = strtoul(env, &endptr, 10);
512 if (*endptr != '\0'
513 || seed > 4294967295UL
514 || (errno == ERANGE && seed == ULONG_MAX))
515 {
516 Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
517 "in range [0; 4294967295]");
518 }
519 if (seed == 0) {
520 /* disable the randomized hash */
521 memset(secret, 0, secret_size);
522 }
523 else {
Christian Heimes985ecdc2013-11-20 11:46:18 +0100524 lcg_urandom(seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100525 }
526 }
527 else {
Victor Stinner4bad3b62016-08-16 15:23:58 +0200528 int res;
529
530 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700531 and so exceptions cannot be used (use raise=0).
532
533 _PyRandom_Init() must not block Python initialization: call
534 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
535 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200536 if (res < 0) {
537 Py_FatalError("failed to get random numbers to initialize Python");
538 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100539 }
540}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200541
542void
543_PyRandom_Fini(void)
544{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200545#ifdef MS_WINDOWS
546 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100547 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200548 hCryptProv = 0;
549 }
550#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200551 dev_urandom_close();
552#endif
553}