blob: a212f69870ed10f314ecc5e017402c4fb098e182 [file] [log] [blame]
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001#include "Python.h"
Victor Stinner331a6a52019-05-27 16:39:22 +02002#include "pycore_initconfig.h"
Georg Brandl2daf6ae2012-02-20 19:54:16 +01003#ifdef MS_WINDOWS
Victor Stinner59f7fb22015-03-18 14:39:33 +01004# include <windows.h>
Martin Panterd2f87472016-07-29 04:00:44 +00005/* All sample MSDN wincrypt programs include the header below. It is at least
6 * required with Min GW. */
7# include <wincrypt.h>
Georg Brandl2daf6ae2012-02-20 19:54:16 +01008#else
Victor Stinner59f7fb22015-03-18 14:39:33 +01009# include <fcntl.h>
10# ifdef HAVE_SYS_STAT_H
11# include <sys/stat.h>
12# endif
Victor Stinnerdddf4842016-06-07 11:21:42 +020013# ifdef HAVE_LINUX_RANDOM_H
14# include <linux/random.h>
15# endif
Benjamin Peterson493ac1b2017-01-01 22:29:36 -060016# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY))
Victor Stinnerbae2d622015-10-01 09:47:30 +020017# include <sys/random.h>
Ned Deily7ae41122016-11-12 16:35:48 -050018# endif
19# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinner59f7fb22015-03-18 14:39:33 +010020# include <sys/syscall.h>
Victor Stinner59f7fb22015-03-18 14:39:33 +010021# endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010022#endif
23
Gregory P. Smith3015fb82018-11-12 22:01:22 -080024#ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -080025# include <sanitizer/msan_interface.h>
26#endif
27
Ronald Oussoren41761932020-11-08 10:05:27 +010028#if defined(__APPLE__) && defined(__has_builtin)
29# if __has_builtin(__builtin_available)
30# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME __builtin_available(macOS 10.12, iOS 10.10, tvOS 10.0, watchOS 3.0, *)
31# endif
32#endif
33#ifndef HAVE_GETENTRYPY_GETRANDOM_RUNTIME
34# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME 1
35#endif
36
37
Benjamin Peterson69e97272012-02-21 11:08:50 -050038#ifdef Py_DEBUG
39int _Py_HashSecret_Initialized = 0;
40#else
41static int _Py_HashSecret_Initialized = 0;
42#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010043
44#ifdef MS_WINDOWS
Georg Brandl2daf6ae2012-02-20 19:54:16 +010045static HCRYPTPROV hCryptProv = 0;
46
47static int
48win32_urandom_init(int raise)
49{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010050 /* Acquire context */
Minmin Gong98e42d12020-05-18 09:50:03 -070051 if (!CryptAcquireContextW(&hCryptProv, NULL, NULL,
52 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010053 goto error;
54
55 return 0;
56
57error:
Victor Stinner4bad3b62016-08-16 15:23:58 +020058 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010059 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020060 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010061 return -1;
62}
63
64/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
Victor Stinner4d6a3d62014-12-21 01:16:38 +010065 API. Return 0 on success, or raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +010066static int
67win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
68{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010069 if (hCryptProv == 0)
70 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020071 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010072 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020073 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010074 }
75
76 while (size > 0)
77 {
Victor Stinnerc48ff732018-11-22 14:43:07 +010078 DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX);
79 if (!CryptGenRandom(hCryptProv, chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010080 {
81 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020082 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010083 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020084 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010085 return -1;
86 }
87 buffer += chunk;
88 size -= chunk;
89 }
90 return 0;
91}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010092
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010093#else /* !MS_WINDOWS */
94
Victor Stinner2f796432017-01-06 11:26:01 +010095#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020096#define PY_GETRANDOM 1
97
Victor Stinnerb27df6f2017-01-06 11:39:15 +010098/* Call getrandom() to get random bytes:
99
Victor Stinner6974cf22016-08-16 18:46:38 +0200100 - Return 1 on success
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100101 - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
102 or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
103 initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +0200104 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100105 if getrandom() failed with EINTR, raise is non-zero and the Python signal
106 handler raised an exception, or if getrandom() failed with a different
107 error.
108
109 getrandom() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100110static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700111py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +0100112{
Victor Stinnere66987e2016-09-06 16:33:52 -0700113 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200114 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200115 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100116 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700117 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200118 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200119 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100120
Victor Stinner6974cf22016-08-16 18:46:38 +0200121 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100122 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200123 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100124
Victor Stinnere66987e2016-09-06 16:33:52 -0700125 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200126 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100127 while (0 < size) {
Jakub Kulík6f9bc722018-12-31 03:16:40 +0100128#if defined(__sun) && defined(__SVR4)
Victor Stinner9d242712016-04-12 22:28:49 +0200129 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100130 to 1024 bytes. Call it multiple times if more bytes are
131 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200132 n = Py_MIN(size, 1024);
133#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200134 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200135#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200136
Victor Stinner9d242712016-04-12 22:28:49 +0200137 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200138#ifdef HAVE_GETRANDOM
139 if (raise) {
140 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200141 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200142 Py_END_ALLOW_THREADS
143 }
144 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200145 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200146 }
147#else
148 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200149 expose the Linux getrandom() syscall yet. See:
150 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200151 if (raise) {
152 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200153 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200154 Py_END_ALLOW_THREADS
155 }
156 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200157 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200158 }
Gregory P. Smith3015fb82018-11-12 22:01:22 -0800159# ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -0800160 if (n > 0) {
161 __msan_unpoison(dest, n);
162 }
163# endif
Victor Stinnerbae2d622015-10-01 09:47:30 +0200164#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200165
Victor Stinner59f7fb22015-03-18 14:39:33 +0100166 if (n < 0) {
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100167 /* ENOSYS: the syscall is not supported by the kernel.
168 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
169 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200170 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100171 getrandom_works = 0;
172 return 0;
173 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200174
Victor Stinnere66987e2016-09-06 16:33:52 -0700175 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
Min ho Kimc4cacc82019-07-31 08:16:13 +1000176 is not initialized yet. For _PyRandom_Init(), we ignore the
Victor Stinnere66987e2016-09-06 16:33:52 -0700177 error and fall back on reading /dev/urandom which never blocks,
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100178 even if the system urandom is not initialized yet:
179 see the PEP 524. */
Victor Stinnere66987e2016-09-06 16:33:52 -0700180 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200181 return 0;
182 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100183
184 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200185 if (raise) {
186 if (PyErr_CheckSignals()) {
187 return -1;
188 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100189 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200190
191 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100192 continue;
193 }
194
Victor Stinner4bad3b62016-08-16 15:23:58 +0200195 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100196 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200197 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100198 return -1;
199 }
200
Victor Stinnercfb19612016-06-08 10:16:50 +0200201 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100202 size -= n;
203 }
204 return 1;
205}
Victor Stinner2f796432017-01-06 11:26:01 +0100206
207#elif defined(HAVE_GETENTROPY)
208#define PY_GETENTROPY 1
209
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100210/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100211
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100212 - Return 1 on success
213 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
214 EPERM).
215 - Raise an exception (if raise is non-zero) and return -1 on error:
216 if getentropy() failed with EINTR, raise is non-zero and the Python signal
217 handler raised an exception, or if getentropy() failed with a different
218 error.
219
220 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
Ronald Oussoren41761932020-11-08 10:05:27 +0100221
222#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
223static int
224py_getentropy(char *buffer, Py_ssize_t size, int raise)
225 __attribute__((availability(macos,introduced=10.12)))
226 __attribute__((availability(ios,introduced=10.0)))
227 __attribute__((availability(tvos,introduced=10.0)))
228 __attribute__((availability(watchos,introduced=3.0)));
229#endif
230
Victor Stinner2f796432017-01-06 11:26:01 +0100231static int
232py_getentropy(char *buffer, Py_ssize_t size, int raise)
233{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100234 /* Is getentropy() supported by the running kernel? Set to 0 if
235 getentropy() failed with ENOSYS or EPERM. */
236 static int getentropy_works = 1;
237
238 if (!getentropy_works) {
239 return 0;
240 }
241
Victor Stinner2f796432017-01-06 11:26:01 +0100242 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100243 /* getentropy() is limited to returning up to 256 bytes. Call it
244 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100245 Py_ssize_t len = Py_MIN(size, 256);
246 int res;
247
248 if (raise) {
249 Py_BEGIN_ALLOW_THREADS
250 res = getentropy(buffer, len);
251 Py_END_ALLOW_THREADS
252 }
253 else {
254 res = getentropy(buffer, len);
255 }
256
257 if (res < 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100258 /* ENOSYS: the syscall is not supported by the running kernel.
259 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
260 or something else. */
261 if (errno == ENOSYS || errno == EPERM) {
262 getentropy_works = 0;
263 return 0;
264 }
265
266 if (errno == EINTR) {
267 if (raise) {
268 if (PyErr_CheckSignals()) {
269 return -1;
270 }
271 }
272
273 /* retry getentropy() if it was interrupted by a signal */
274 continue;
275 }
276
Victor Stinner2f796432017-01-06 11:26:01 +0100277 if (raise) {
278 PyErr_SetFromErrno(PyExc_OSError);
279 }
280 return -1;
281 }
282
283 buffer += len;
284 size -= len;
285 }
286 return 1;
287}
Jakub Kulík6f9bc722018-12-31 03:16:40 +0100288#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100289
Victor Stinner59f7fb22015-03-18 14:39:33 +0100290
Antoine Pitroue472aea2014-04-26 14:33:03 +0200291static struct {
292 int fd;
293 dev_t st_dev;
294 ino_t st_ino;
295} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100296
Victor Stinnera49a2072017-01-06 11:17:52 +0100297/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200298
Victor Stinnera49a2072017-01-06 11:17:52 +0100299 - Return 0 on success
300 - Raise an exception (if raise is non-zero) and return -1 on error
301
302 Possible causes of errors:
303
304 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
305 was not found. For example, it was removed manually or not exposed in a
306 chroot or container.
307 - open() failed with a different error
308 - fstat() failed
309 - read() failed or returned 0
310
311 read() is retried if it failed with EINTR: interrupted by a signal.
312
313 The file descriptor of the device is kept open between calls to avoid using
314 many file descriptors when run in parallel from multiple threads:
315 see the issue #18756.
316
317 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
318 check if the file descriptor was replaced by a different file (which is
319 likely a bug in the application): see the issue #21207.
320
321 If the file descriptor was closed or replaced, open a new file descriptor
322 but don't close the old file descriptor: it probably points to something
323 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200324static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100325dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100326{
327 int fd;
328 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200329
330 if (raise) {
331 struct _Py_stat_struct st;
Nir Soffer4484f9d2018-03-12 01:39:22 +0200332 int fstat_result;
Victor Stinner6974cf22016-08-16 18:46:38 +0200333
Antoine Pitroue472aea2014-04-26 14:33:03 +0200334 if (urandom_cache.fd >= 0) {
Nir Soffer4484f9d2018-03-12 01:39:22 +0200335 Py_BEGIN_ALLOW_THREADS
336 fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
337 Py_END_ALLOW_THREADS
338
Victor Stinner6974cf22016-08-16 18:46:38 +0200339 /* Does the fd point to the same thing as before? (issue #21207) */
Nir Soffer4484f9d2018-03-12 01:39:22 +0200340 if (fstat_result
Victor Stinner6974cf22016-08-16 18:46:38 +0200341 || st.st_dev != urandom_cache.st_dev
342 || st.st_ino != urandom_cache.st_ino) {
343 /* Something changed: forget the cached fd (but don't close it,
344 since it probably points to something important for some
345 third-party code). */
346 urandom_cache.fd = -1;
347 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200348 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200349 if (urandom_cache.fd >= 0)
350 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200351 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200352 fd = _Py_open("/dev/urandom", O_RDONLY);
353 if (fd < 0) {
354 if (errno == ENOENT || errno == ENXIO ||
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100355 errno == ENODEV || errno == EACCES) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200356 PyErr_SetString(PyExc_NotImplementedError,
357 "/dev/urandom (or equivalent) not found");
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100358 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200359 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200360 return -1;
361 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200362 if (urandom_cache.fd >= 0) {
363 /* urandom_fd was initialized by another thread while we were
364 not holding the GIL, keep it. */
365 close(fd);
366 fd = urandom_cache.fd;
367 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200368 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200369 if (_Py_fstat(fd, &st)) {
370 close(fd);
371 return -1;
372 }
373 else {
374 urandom_cache.fd = fd;
375 urandom_cache.st_dev = st.st_dev;
376 urandom_cache.st_ino = st.st_ino;
377 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200378 }
379 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100380
Victor Stinner6974cf22016-08-16 18:46:38 +0200381 do {
382 n = _Py_read(fd, buffer, (size_t)size);
383 if (n == -1)
384 return -1;
385 if (n == 0) {
386 PyErr_Format(PyExc_RuntimeError,
387 "Failed to read %zi bytes from /dev/urandom",
388 size);
389 return -1;
390 }
391
392 buffer += n;
393 size -= n;
394 } while (0 < size);
395 }
396 else {
397 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
398 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100399 return -1;
400 }
401
Victor Stinner6974cf22016-08-16 18:46:38 +0200402 while (0 < size)
403 {
404 do {
405 n = read(fd, buffer, (size_t)size);
406 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100407
Victor Stinner6974cf22016-08-16 18:46:38 +0200408 if (n <= 0) {
409 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200410 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200411 return -1;
412 }
413
414 buffer += n;
415 size -= n;
416 }
417 close(fd);
418 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100419 return 0;
420}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200421
422static void
423dev_urandom_close(void)
424{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200425 if (urandom_cache.fd >= 0) {
426 close(urandom_cache.fd);
427 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200428 }
429}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100430#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200431
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100432
433/* Fill buffer with pseudo-random bytes generated by a linear congruent
434 generator (LCG):
435
436 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
437
438 Use bits 23..16 of x(n) to generate a byte. */
439static void
440lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
441{
442 size_t index;
443 unsigned int x;
444
445 x = x0;
446 for (index=0; index < size; index++) {
447 x *= 214013;
448 x += 2531011;
449 /* modulo 2 ^ (8 * sizeof(int)) */
450 buffer[index] = (x >> 16) & 0xff;
451 }
452}
453
Victor Stinnera49a2072017-01-06 11:17:52 +0100454/* Read random bytes:
455
456 - Return 0 on success
457 - Raise an exception (if raise is non-zero) and return -1 on error
458
459 Used sources of entropy ordered by preference, preferred source first:
460
461 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100462 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100463 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100464 - /dev/urandom device
465
466 Read from the /dev/urandom device if getrandom() or getentropy() function
467 is not available or does not work.
468
Victor Stinner2f796432017-01-06 11:26:01 +0100469 Prefer getrandom() over getentropy() because getrandom() supports blocking
470 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
471 startup to initialize its hash secret, but os.urandom() must block until the
472 system urandom is initialized (at least on Linux 3.17 and newer).
473
Victor Stinnera49a2072017-01-06 11:17:52 +0100474 Prefer getrandom() and getentropy() over reading directly /dev/urandom
475 because these functions don't need file descriptors and so avoid ENFILE or
476 EMFILE errors (too many open files): see the issue #18756.
477
478 Only the getrandom() function supports non-blocking mode.
479
480 Only use RNG running in the kernel. They are more secure because it is
481 harder to get the internal state of a RNG running in the kernel land than a
482 RNG running in the user land. The kernel has a direct access to the hardware
483 and has access to hardware RNG, they are used as entropy sources.
484
485 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
486 its RNG on fork(), two child processes (with the same pid) generate the same
487 random numbers: see issue #18747. Kernel RNGs don't have this issue,
488 they have access to good quality entropy sources.
489
490 If raise is zero:
491
492 - Don't raise an exception on error
493 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
494 a function fails with EINTR: retry directly the interrupted function
495 - Don't release the GIL to call functions.
496*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200497static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700498pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200499{
Victor Stinnera49a2072017-01-06 11:17:52 +0100500#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
501 int res;
502#endif
503
Victor Stinner4bad3b62016-08-16 15:23:58 +0200504 if (size < 0) {
505 if (raise) {
506 PyErr_Format(PyExc_ValueError,
507 "negative argument not allowed");
508 }
509 return -1;
510 }
511
512 if (size == 0) {
513 return 0;
514 }
515
516#ifdef MS_WINDOWS
517 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200518#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100519
520#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Ronald Oussoren41761932020-11-08 10:05:27 +0100521 if (HAVE_GETENTRYPY_GETRANDOM_RUNTIME) {
Victor Stinner2f796432017-01-06 11:26:01 +0100522#ifdef PY_GETRANDOM
Ronald Oussoren41761932020-11-08 10:05:27 +0100523 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100524#else
Ronald Oussoren41761932020-11-08 10:05:27 +0100525 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100526#endif
Ronald Oussoren41761932020-11-08 10:05:27 +0100527 if (res < 0) {
528 return -1;
529 }
530 if (res == 1) {
531 return 0;
532 }
533 /* getrandom() or getentropy() function is not available: failed with
534 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
535 } /* end of availability block */
Victor Stinnera49a2072017-01-06 11:17:52 +0100536#endif
537
538 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200539#endif
540}
541
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200542/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200543 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200544 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100545
Victor Stinnere66987e2016-09-06 16:33:52 -0700546 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
547 block until the system urandom entropy pool is initialized (128 bits are
548 collected by the kernel).
549
550 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100551int
552_PyOS_URandom(void *buffer, Py_ssize_t size)
553{
Victor Stinnere66987e2016-09-06 16:33:52 -0700554 return pyurandom(buffer, size, 1, 1);
555}
556
557/* Fill buffer with size pseudo-random bytes from the operating system random
558 number generator (RNG). It is not suitable for cryptographic purpose.
559
560 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
561 urandom is not initialized yet, the function returns "weak" entropy read
562 from /dev/urandom.
563
564 Return 0 on success. Raise an exception and return -1 on error. */
565int
566_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
567{
568 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100569}
570
Victor Stinner358e5e12017-12-15 00:51:22 +0100571
Victor Stinner331a6a52019-05-27 16:39:22 +0200572PyStatus
573_Py_HashRandomization_Init(const PyConfig *config)
Eric Snow6b4be192017-05-22 21:36:03 -0700574{
575 void *secret = &_Py_HashSecret;
576 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100577
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800578 if (_Py_HashSecret_Initialized) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200579 return _PyStatus_OK();
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800580 }
Benjamin Peterson69e97272012-02-21 11:08:50 -0500581 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100582
Victor Stinner358e5e12017-12-15 00:51:22 +0100583 if (config->use_hash_seed) {
584 if (config->hash_seed == 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100585 /* disable the randomized hash */
586 memset(secret, 0, secret_size);
587 }
588 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700589 /* use the specified hash seed */
Victor Stinner358e5e12017-12-15 00:51:22 +0100590 lcg_urandom(config->hash_seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100591 }
592 }
593 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700594 /* use a random hash seed */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200595 int res;
596
597 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700598 and so exceptions cannot be used (use raise=0).
599
600 _PyRandom_Init() must not block Python initialization: call
601 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
602 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200603 if (res < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200604 return _PyStatus_ERR("failed to get random numbers "
Victor Stinnere81f6e62020-06-08 18:12:59 +0200605 "to initialize Python");
Victor Stinner4bad3b62016-08-16 15:23:58 +0200606 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100607 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200608 return _PyStatus_OK();
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100609}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200610
Eric Snow6b4be192017-05-22 21:36:03 -0700611
612void
613_Py_HashRandomization_Fini(void)
Antoine Pitrou4879a962013-08-31 00:26:02 +0200614{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200615#ifdef MS_WINDOWS
616 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100617 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200618 hCryptProv = 0;
619 }
620#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200621 dev_urandom_close();
622#endif
623}