blob: 31f61d03b553a50675e441fc296401ce120af6c8 [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>
Victor Stinner035ba5d2017-01-09 11:18:53 +01004/* 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 Stinner035ba5d2017-01-09 11:18:53 +010043 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010044 PyErr_SetFromWindowsErr(0);
Victor Stinner035ba5d2017-01-09 11:18:53 +010045 }
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 Stinner035ba5d2017-01-09 11:18:53 +010058 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010059 return -1;
Victor Stinner035ba5d2017-01-09 11:18:53 +010060 }
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 Stinner035ba5d2017-01-09 11:18:53 +010069 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010070 PyErr_SetFromWindowsErr(0);
Victor Stinner035ba5d2017-01-09 11:18:53 +010071 }
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 Stinner035ba5d2017-01-09 11:18:53 +010080#else /* !MS_WINDOWS */
Victor Stinner59f7fb22015-03-18 14:39:33 +010081
Victor Stinnerbae2d622015-10-01 09:47:30 +020082#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
83#define PY_GETRANDOM 1
84
Victor Stinner035ba5d2017-01-09 11:18:53 +010085/* Call getrandom() to get random bytes:
86
Victor Stinneraf597322016-09-20 22:26:18 +020087 - Return 1 on success
Victor Stinner035ba5d2017-01-09 11:18:53 +010088 - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
89 or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
90 initialized yet).
Victor Stinneraf597322016-09-20 22:26:18 +020091 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinner035ba5d2017-01-09 11:18:53 +010092 if getrandom() failed with EINTR, raise is non-zero and the Python signal
93 handler raised an exception, or if getrandom() failed with a different
94 error.
95
96 getrandom() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner59f7fb22015-03-18 14:39:33 +010097static int
98py_getrandom(void *buffer, Py_ssize_t size, int raise)
99{
Victor Stinneraf597322016-09-20 22:26:18 +0200100 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200101 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200102 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100103 static int getrandom_works = 1;
Victor Stinnerdddf4842016-06-07 11:21:42 +0200104
105 /* getrandom() on Linux will block if called before the kernel has
106 * initialized the urandom entropy pool. This will cause Python
107 * to hang on startup if called very early in the boot process -
108 * see https://bugs.python.org/issue26839. To avoid this, use the
109 * GRND_NONBLOCK flag. */
110 const int flags = GRND_NONBLOCK;
Victor Stinner035ba5d2017-01-09 11:18:53 +0100111 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200112 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100113
Victor Stinneraf597322016-09-20 22:26:18 +0200114 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100115 return 0;
Victor Stinneraf597322016-09-20 22:26:18 +0200116 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100117
Victor Stinner035ba5d2017-01-09 11:18:53 +0100118 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100119 while (0 < size) {
Victor Stinner9d242712016-04-12 22:28:49 +0200120#ifdef sun
121 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinner035ba5d2017-01-09 11:18:53 +0100122 to 1024 bytes. Call it multiple times if more bytes are
123 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200124 n = Py_MIN(size, 1024);
125#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200126 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200127#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200128
Victor Stinner9d242712016-04-12 22:28:49 +0200129 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200130#ifdef HAVE_GETRANDOM
131 if (raise) {
132 Py_BEGIN_ALLOW_THREADS
Victor Stinner035ba5d2017-01-09 11:18:53 +0100133 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200134 Py_END_ALLOW_THREADS
135 }
136 else {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100137 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200138 }
139#else
140 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner035ba5d2017-01-09 11:18:53 +0100141 expose the Linux getrandom() syscall yet. See:
142 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200143 if (raise) {
144 Py_BEGIN_ALLOW_THREADS
Victor Stinner035ba5d2017-01-09 11:18:53 +0100145 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200146 Py_END_ALLOW_THREADS
147 }
148 else {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100149 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200150 }
Victor Stinnerbae2d622015-10-01 09:47:30 +0200151#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200152
Victor Stinner59f7fb22015-03-18 14:39:33 +0100153 if (n < 0) {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100154 /* ENOSYS: the syscall is not supported by the kernel.
155 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
156 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200157 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100158 getrandom_works = 0;
159 return 0;
160 }
Victor Stinner035ba5d2017-01-09 11:18:53 +0100161
Victor Stinnerdddf4842016-06-07 11:21:42 +0200162 if (errno == EAGAIN) {
Victor Stinneraf597322016-09-20 22:26:18 +0200163 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
164 urandom is not initialiazed yet. In this case, fall back on
165 reading from /dev/urandom.
166
167 Note: In this case the data read will not be random so
168 should not be used for cryptographic purposes. Retaining
169 the existing semantics for practical purposes. */
Victor Stinnerdddf4842016-06-07 11:21:42 +0200170 getrandom_works = 0;
171 return 0;
172 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100173
174 if (errno == EINTR) {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100175 if (raise) {
176 if (PyErr_CheckSignals()) {
177 return -1;
Victor Stinneraf597322016-09-20 22:26:18 +0200178 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100179 }
Victor Stinneraf597322016-09-20 22:26:18 +0200180
Victor Stinner035ba5d2017-01-09 11:18:53 +0100181 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100182 continue;
183 }
184
Victor Stinneraf597322016-09-20 22:26:18 +0200185 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100186 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinneraf597322016-09-20 22:26:18 +0200187 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100188 return -1;
189 }
190
Victor Stinner035ba5d2017-01-09 11:18:53 +0100191 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100192 size -= n;
193 }
194 return 1;
195}
Victor Stinner035ba5d2017-01-09 11:18:53 +0100196
197#elif defined(HAVE_GETENTROPY)
198#define PY_GETENTROPY 1
199
200/* Fill buffer with size pseudo-random bytes generated by getentropy():
201
202 - Return 1 on success
203 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
204 EPERM).
205 - Raise an exception (if raise is non-zero) and return -1 on error:
206 if getentropy() failed with EINTR, raise is non-zero and the Python signal
207 handler raised an exception, or if getentropy() failed with a different
208 error.
209
210 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
211static int
212py_getentropy(char *buffer, Py_ssize_t size, int raise)
213{
214 /* Is getentropy() supported by the running kernel? Set to 0 if
215 getentropy() failed with ENOSYS or EPERM. */
216 static int getentropy_works = 1;
217
218 if (!getentropy_works) {
219 return 0;
220 }
221
222 while (size > 0) {
223 /* getentropy() is limited to returning up to 256 bytes. Call it
224 multiple times if more bytes are requested. */
225 Py_ssize_t len = Py_MIN(size, 256);
226 int res;
227
228 if (raise) {
229 Py_BEGIN_ALLOW_THREADS
230 res = getentropy(buffer, len);
231 Py_END_ALLOW_THREADS
232 }
233 else {
234 res = getentropy(buffer, len);
235 }
236
237 if (res < 0) {
238 /* ENOSYS: the syscall is not supported by the running kernel.
239 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
240 or something else. */
241 if (errno == ENOSYS || errno == EPERM) {
242 getentropy_works = 0;
243 return 0;
244 }
245
246 if (errno == EINTR) {
247 if (raise) {
248 if (PyErr_CheckSignals()) {
249 return -1;
250 }
251 }
252
253 /* retry getentropy() if it was interrupted by a signal */
254 continue;
255 }
256
257 if (raise) {
258 PyErr_SetFromErrno(PyExc_OSError);
259 }
260 return -1;
261 }
262
263 buffer += len;
264 size -= len;
265 }
266 return 1;
267}
268#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
269
Victor Stinner59f7fb22015-03-18 14:39:33 +0100270
Antoine Pitroue472aea2014-04-26 14:33:03 +0200271static struct {
272 int fd;
273 dev_t st_dev;
274 ino_t st_ino;
275} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100276
Victor Stinner035ba5d2017-01-09 11:18:53 +0100277/* Read random bytes from the /dev/urandom device:
Victor Stinner59f7fb22015-03-18 14:39:33 +0100278
Victor Stinner035ba5d2017-01-09 11:18:53 +0100279 - Return 0 on success
280 - Raise an exception (if raise is non-zero) and return -1 on error
Victor Stinneraf597322016-09-20 22:26:18 +0200281
Victor Stinner035ba5d2017-01-09 11:18:53 +0100282 Possible causes of errors:
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100283
Victor Stinner035ba5d2017-01-09 11:18:53 +0100284 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
285 was not found. For example, it was removed manually or not exposed in a
286 chroot or container.
287 - open() failed with a different error
288 - fstat() failed
289 - read() failed or returned 0
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100290
Victor Stinner035ba5d2017-01-09 11:18:53 +0100291 read() is retried if it failed with EINTR: interrupted by a signal.
Victor Stinner59f7fb22015-03-18 14:39:33 +0100292
Victor Stinner035ba5d2017-01-09 11:18:53 +0100293 The file descriptor of the device is kept open between calls to avoid using
294 many file descriptors when run in parallel from multiple threads:
295 see the issue #18756.
Victor Stinnerc7cd12d2015-03-19 23:24:45 +0100296
Victor Stinner035ba5d2017-01-09 11:18:53 +0100297 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
298 check if the file descriptor was replaced by a different file (which is
299 likely a bug in the application): see the issue #21207.
Victor Stinneraf597322016-09-20 22:26:18 +0200300
Victor Stinner035ba5d2017-01-09 11:18:53 +0100301 If the file descriptor was closed or replaced, open a new file descriptor
302 but don't close the old file descriptor: it probably points to something
303 important for some third-party code. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100304static int
Victor Stinner035ba5d2017-01-09 11:18:53 +0100305dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100306{
307 int fd;
308 Py_ssize_t n;
309
Victor Stinner035ba5d2017-01-09 11:18:53 +0100310 if (raise) {
311 struct _Py_stat_struct st;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100312
Victor Stinner035ba5d2017-01-09 11:18:53 +0100313 if (urandom_cache.fd >= 0) {
314 /* Does the fd point to the same thing as before? (issue #21207) */
315 if (_Py_fstat_noraise(urandom_cache.fd, &st)
316 || st.st_dev != urandom_cache.st_dev
317 || st.st_ino != urandom_cache.st_ino) {
318 /* Something changed: forget the cached fd (but don't close it,
319 since it probably points to something important for some
320 third-party code). */
321 urandom_cache.fd = -1;
322 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200323 }
Victor Stinner035ba5d2017-01-09 11:18:53 +0100324 if (urandom_cache.fd >= 0)
325 fd = urandom_cache.fd;
326 else {
327 fd = _Py_open("/dev/urandom", O_RDONLY);
328 if (fd < 0) {
329 if (errno == ENOENT || errno == ENXIO ||
330 errno == ENODEV || errno == EACCES) {
331 PyErr_SetString(PyExc_NotImplementedError,
332 "/dev/urandom (or equivalent) not found");
333 }
334 /* otherwise, keep the OSError exception raised by _Py_open() */
335 return -1;
336 }
337 if (urandom_cache.fd >= 0) {
338 /* urandom_fd was initialized by another thread while we were
339 not holding the GIL, keep it. */
340 close(fd);
341 fd = urandom_cache.fd;
342 }
343 else {
344 if (_Py_fstat(fd, &st)) {
345 close(fd);
346 return -1;
347 }
348 else {
349 urandom_cache.fd = fd;
350 urandom_cache.st_dev = st.st_dev;
351 urandom_cache.st_ino = st.st_ino;
352 }
353 }
354 }
355
356 do {
357 n = _Py_read(fd, buffer, (size_t)size);
358 if (n == -1)
359 return -1;
360 if (n == 0) {
361 PyErr_Format(PyExc_RuntimeError,
362 "Failed to read %zi bytes from /dev/urandom",
363 size);
364 return -1;
365 }
366
367 buffer += n;
368 size -= n;
369 } while (0 < size);
Antoine Pitroue472aea2014-04-26 14:33:03 +0200370 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200371 else {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100372 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
Victor Stinnera555cfc2015-03-18 00:22:14 +0100373 if (fd < 0) {
Antoine Pitrou4879a962013-08-31 00:26:02 +0200374 return -1;
375 }
Victor Stinner035ba5d2017-01-09 11:18:53 +0100376
377 while (0 < size)
378 {
379 do {
380 n = read(fd, buffer, (size_t)size);
381 } while (n < 0 && errno == EINTR);
382
383 if (n <= 0) {
384 /* stop on error or if read(size) returned 0 */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200385 close(fd);
386 return -1;
387 }
Victor Stinner035ba5d2017-01-09 11:18:53 +0100388
389 buffer += n;
390 size -= n;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200391 }
Victor Stinner035ba5d2017-01-09 11:18:53 +0100392 close(fd);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100393 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100394 return 0;
395}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200396
397static void
398dev_urandom_close(void)
399{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200400 if (urandom_cache.fd >= 0) {
401 close(urandom_cache.fd);
402 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200403 }
404}
Victor Stinner035ba5d2017-01-09 11:18:53 +0100405#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200406
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100407
408/* Fill buffer with pseudo-random bytes generated by a linear congruent
409 generator (LCG):
410
411 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
412
413 Use bits 23..16 of x(n) to generate a byte. */
414static void
415lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
416{
417 size_t index;
418 unsigned int x;
419
420 x = x0;
421 for (index=0; index < size; index++) {
422 x *= 214013;
423 x += 2531011;
424 /* modulo 2 ^ (8 * sizeof(int)) */
425 buffer[index] = (x >> 16) & 0xff;
426 }
427}
428
Victor Stinner035ba5d2017-01-09 11:18:53 +0100429/* Read random bytes:
430
431 - Return 0 on success
432 - Raise an exception (if raise is non-zero) and return -1 on error
433
434 Used sources of entropy ordered by preference, preferred source first:
435
436 - CryptGenRandom() on Windows
437 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
438 - getentropy() function (ex: OpenBSD): call py_getentropy()
439 - /dev/urandom device
440
441 Read from the /dev/urandom device if getrandom() or getentropy() function
442 is not available or does not work.
443
444 Prefer getrandom() over getentropy() because getrandom() supports blocking
445 and non-blocking mode and Python requires non-blocking RNG at startup to
446 initialize its hash secret: see the PEP 524.
447
448 Prefer getrandom() and getentropy() over reading directly /dev/urandom
449 because these functions don't need file descriptors and so avoid ENFILE or
450 EMFILE errors (too many open files): see the issue #18756.
451
452 Only use RNG running in the kernel. They are more secure because it is
453 harder to get the internal state of a RNG running in the kernel land than a
454 RNG running in the user land. The kernel has a direct access to the hardware
455 and has access to hardware RNG, they are used as entropy sources.
456
457 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
458 its RNG on fork(), two child processes (with the same pid) generate the same
459 random numbers: see issue #18747. Kernel RNGs don't have this issue,
460 they have access to good quality entropy sources.
461
462 If raise is zero:
463
464 - Don't raise an exception on error
465 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
466 a function fails with EINTR: retry directly the interrupted function
467 - Don't release the GIL to call functions.
468*/
469static int
470pyurandom(void *buffer, Py_ssize_t size, int raise)
471{
472#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
473 int res;
474#endif
475
476 if (size < 0) {
477 if (raise) {
478 PyErr_Format(PyExc_ValueError,
479 "negative argument not allowed");
480 }
481 return -1;
482 }
483
484 if (size == 0) {
485 return 0;
486 }
487
488#ifdef MS_WINDOWS
489 return win32_urandom((unsigned char *)buffer, size, raise);
490#else
491
492#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
493#ifdef PY_GETRANDOM
494 res = py_getrandom(buffer, size, raise);
495#else
496 res = py_getentropy(buffer, size, raise);
497#endif
498 if (res < 0) {
499 return -1;
500 }
501 if (res == 1) {
502 return 0;
503 }
504 /* getrandom() or getentropy() function is not available: failed with
505 ENOSYS, EPERM or EAGAIN. Fall back on reading from /dev/urandom. */
506#endif
507
508 return dev_urandom(buffer, size, raise);
509#endif
510}
511
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200512/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200513 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200514 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100515
Victor Stinner035ba5d2017-01-09 11:18:53 +0100516 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100517int
518_PyOS_URandom(void *buffer, Py_ssize_t size)
519{
Victor Stinner035ba5d2017-01-09 11:18:53 +0100520 return pyurandom(buffer, size, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100521}
522
523void
524_PyRandom_Init(void)
525{
526 char *env;
Christian Heimes985ecdc2013-11-20 11:46:18 +0100527 unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500528 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Christian Heimes985ecdc2013-11-20 11:46:18 +0100529 assert(secret_size == sizeof(_Py_HashSecret.uc));
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100530
Benjamin Peterson69e97272012-02-21 11:08:50 -0500531 if (_Py_HashSecret_Initialized)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100532 return;
Benjamin Peterson69e97272012-02-21 11:08:50 -0500533 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100534
535 /*
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100536 Hash randomization is enabled. Generate a per-process secret,
537 using PYTHONHASHSEED if provided.
538 */
539
540 env = Py_GETENV("PYTHONHASHSEED");
Georg Brandl12897d72012-02-20 23:49:29 +0100541 if (env && *env != '\0' && strcmp(env, "random") != 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100542 char *endptr = env;
543 unsigned long seed;
544 seed = strtoul(env, &endptr, 10);
545 if (*endptr != '\0'
546 || seed > 4294967295UL
547 || (errno == ERANGE && seed == ULONG_MAX))
548 {
549 Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
550 "in range [0; 4294967295]");
551 }
552 if (seed == 0) {
553 /* disable the randomized hash */
554 memset(secret, 0, secret_size);
555 }
556 else {
Christian Heimes985ecdc2013-11-20 11:46:18 +0100557 lcg_urandom(seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100558 }
559 }
560 else {
Victor Stinner035ba5d2017-01-09 11:18:53 +0100561 int res;
562
563 /* _PyRandom_Init() is called very early in the Python initialization
564 and so exceptions cannot be used (use raise=0). */
565 res = pyurandom(secret, secret_size, 0);
566 if (res < 0) {
567 Py_FatalError("failed to get random numbers to initialize Python");
568 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100569 }
570}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200571
572void
573_PyRandom_Fini(void)
574{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200575#ifdef MS_WINDOWS
576 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100577 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200578 hCryptProv = 0;
579 }
580#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200581 dev_urandom_close();
582#endif
583}