blob: 793c646f12ba6cb0d39556df778b6d8d16416854 [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
Gregory P. Smith3015fb82018-11-12 22:01:22 -080023#ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -080024# include <sanitizer/msan_interface.h>
25#endif
26
Benjamin Peterson69e97272012-02-21 11:08:50 -050027#ifdef Py_DEBUG
28int _Py_HashSecret_Initialized = 0;
29#else
30static int _Py_HashSecret_Initialized = 0;
31#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010032
33#ifdef MS_WINDOWS
Georg Brandl2daf6ae2012-02-20 19:54:16 +010034static HCRYPTPROV hCryptProv = 0;
35
36static int
37win32_urandom_init(int raise)
38{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010039 /* Acquire context */
Martin v. Löwis3f50bf62013-01-25 14:06:18 +010040 if (!CryptAcquireContext(&hCryptProv, NULL, NULL,
41 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010042 goto error;
43
44 return 0;
45
46error:
Victor Stinner4bad3b62016-08-16 15:23:58 +020047 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010048 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020049 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010050 return -1;
51}
52
53/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
Victor Stinner4d6a3d62014-12-21 01:16:38 +010054 API. Return 0 on success, or raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +010055static int
56win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
57{
58 Py_ssize_t chunk;
59
60 if (hCryptProv == 0)
61 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020062 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010063 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020064 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010065 }
66
67 while (size > 0)
68 {
69 chunk = size > INT_MAX ? INT_MAX : size;
Victor Stinner0c083462013-11-15 23:26:25 +010070 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010071 {
72 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020073 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010074 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020075 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010076 return -1;
77 }
78 buffer += chunk;
79 size -= chunk;
80 }
81 return 0;
82}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010083
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010084#else /* !MS_WINDOWS */
85
Victor Stinner2f796432017-01-06 11:26:01 +010086#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020087#define PY_GETRANDOM 1
88
Victor Stinnerb27df6f2017-01-06 11:39:15 +010089/* Call getrandom() to get random bytes:
90
Victor Stinner6974cf22016-08-16 18:46:38 +020091 - Return 1 on success
Victor Stinnerb27df6f2017-01-06 11:39:15 +010092 - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
93 or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
94 initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +020095 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinnerb27df6f2017-01-06 11:39:15 +010096 if getrandom() failed with EINTR, raise is non-zero and the Python signal
97 handler raised an exception, or if getrandom() failed with a different
98 error.
99
100 getrandom() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100101static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700102py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +0100103{
Victor Stinnere66987e2016-09-06 16:33:52 -0700104 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200105 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200106 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100107 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700108 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200109 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200110 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100111
Victor Stinner6974cf22016-08-16 18:46:38 +0200112 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100113 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200114 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100115
Victor Stinnere66987e2016-09-06 16:33:52 -0700116 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200117 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100118 while (0 < size) {
Victor Stinner9d242712016-04-12 22:28:49 +0200119#ifdef sun
120 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100121 to 1024 bytes. Call it multiple times if more bytes are
122 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200123 n = Py_MIN(size, 1024);
124#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200125 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200126#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200127
Victor Stinner9d242712016-04-12 22:28:49 +0200128 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200129#ifdef HAVE_GETRANDOM
130 if (raise) {
131 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200132 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200133 Py_END_ALLOW_THREADS
134 }
135 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200136 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200137 }
138#else
139 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200140 expose the Linux getrandom() syscall yet. See:
141 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200142 if (raise) {
143 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200144 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200145 Py_END_ALLOW_THREADS
146 }
147 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200148 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200149 }
Gregory P. Smith3015fb82018-11-12 22:01:22 -0800150# ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -0800151 if (n > 0) {
152 __msan_unpoison(dest, n);
153 }
154# endif
Victor Stinnerbae2d622015-10-01 09:47:30 +0200155#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200156
Victor Stinner59f7fb22015-03-18 14:39:33 +0100157 if (n < 0) {
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100158 /* ENOSYS: the syscall is not supported by the kernel.
159 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
160 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200161 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100162 getrandom_works = 0;
163 return 0;
164 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200165
Victor Stinnere66987e2016-09-06 16:33:52 -0700166 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100167 is not initialiazed yet. For _PyRandom_Init(), we ignore the
Victor Stinnere66987e2016-09-06 16:33:52 -0700168 error and fall back on reading /dev/urandom which never blocks,
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100169 even if the system urandom is not initialized yet:
170 see the PEP 524. */
Victor Stinnere66987e2016-09-06 16:33:52 -0700171 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200172 return 0;
173 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100174
175 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200176 if (raise) {
177 if (PyErr_CheckSignals()) {
178 return -1;
179 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100180 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200181
182 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100183 continue;
184 }
185
Victor Stinner4bad3b62016-08-16 15:23:58 +0200186 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100187 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200188 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100189 return -1;
190 }
191
Victor Stinnercfb19612016-06-08 10:16:50 +0200192 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100193 size -= n;
194 }
195 return 1;
196}
Victor Stinner2f796432017-01-06 11:26:01 +0100197
198#elif defined(HAVE_GETENTROPY)
199#define PY_GETENTROPY 1
200
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100201/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100202
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100203 - Return 1 on success
204 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
205 EPERM).
206 - Raise an exception (if raise is non-zero) and return -1 on error:
207 if getentropy() failed with EINTR, raise is non-zero and the Python signal
208 handler raised an exception, or if getentropy() failed with a different
209 error.
210
211 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner2f796432017-01-06 11:26:01 +0100212static int
213py_getentropy(char *buffer, Py_ssize_t size, int raise)
214{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100215 /* Is getentropy() supported by the running kernel? Set to 0 if
216 getentropy() failed with ENOSYS or EPERM. */
217 static int getentropy_works = 1;
218
219 if (!getentropy_works) {
220 return 0;
221 }
222
Victor Stinner2f796432017-01-06 11:26:01 +0100223 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100224 /* getentropy() is limited to returning up to 256 bytes. Call it
225 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100226 Py_ssize_t len = Py_MIN(size, 256);
227 int res;
228
229 if (raise) {
230 Py_BEGIN_ALLOW_THREADS
231 res = getentropy(buffer, len);
232 Py_END_ALLOW_THREADS
233 }
234 else {
235 res = getentropy(buffer, len);
236 }
237
238 if (res < 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100239 /* ENOSYS: the syscall is not supported by the running kernel.
240 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
241 or something else. */
242 if (errno == ENOSYS || errno == EPERM) {
243 getentropy_works = 0;
244 return 0;
245 }
246
247 if (errno == EINTR) {
248 if (raise) {
249 if (PyErr_CheckSignals()) {
250 return -1;
251 }
252 }
253
254 /* retry getentropy() if it was interrupted by a signal */
255 continue;
256 }
257
Victor Stinner2f796432017-01-06 11:26:01 +0100258 if (raise) {
259 PyErr_SetFromErrno(PyExc_OSError);
260 }
261 return -1;
262 }
263
264 buffer += len;
265 size -= len;
266 }
267 return 1;
268}
269#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100270
Victor Stinner59f7fb22015-03-18 14:39:33 +0100271
Antoine Pitroue472aea2014-04-26 14:33:03 +0200272static struct {
273 int fd;
274 dev_t st_dev;
275 ino_t st_ino;
276} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100277
Victor Stinnera49a2072017-01-06 11:17:52 +0100278/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200279
Victor Stinnera49a2072017-01-06 11:17:52 +0100280 - Return 0 on success
281 - Raise an exception (if raise is non-zero) and return -1 on error
282
283 Possible causes of errors:
284
285 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
286 was not found. For example, it was removed manually or not exposed in a
287 chroot or container.
288 - open() failed with a different error
289 - fstat() failed
290 - read() failed or returned 0
291
292 read() is retried if it failed with EINTR: interrupted by a signal.
293
294 The file descriptor of the device is kept open between calls to avoid using
295 many file descriptors when run in parallel from multiple threads:
296 see the issue #18756.
297
298 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
299 check if the file descriptor was replaced by a different file (which is
300 likely a bug in the application): see the issue #21207.
301
302 If the file descriptor was closed or replaced, open a new file descriptor
303 but don't close the old file descriptor: it probably points to something
304 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200305static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100306dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100307{
308 int fd;
309 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200310
311 if (raise) {
312 struct _Py_stat_struct st;
Nir Soffer4484f9d2018-03-12 01:39:22 +0200313 int fstat_result;
Victor Stinner6974cf22016-08-16 18:46:38 +0200314
Antoine Pitroue472aea2014-04-26 14:33:03 +0200315 if (urandom_cache.fd >= 0) {
Nir Soffer4484f9d2018-03-12 01:39:22 +0200316 Py_BEGIN_ALLOW_THREADS
317 fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
318 Py_END_ALLOW_THREADS
319
Victor Stinner6974cf22016-08-16 18:46:38 +0200320 /* Does the fd point to the same thing as before? (issue #21207) */
Nir Soffer4484f9d2018-03-12 01:39:22 +0200321 if (fstat_result
Victor Stinner6974cf22016-08-16 18:46:38 +0200322 || st.st_dev != urandom_cache.st_dev
323 || st.st_ino != urandom_cache.st_ino) {
324 /* Something changed: forget the cached fd (but don't close it,
325 since it probably points to something important for some
326 third-party code). */
327 urandom_cache.fd = -1;
328 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200329 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200330 if (urandom_cache.fd >= 0)
331 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200332 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200333 fd = _Py_open("/dev/urandom", O_RDONLY);
334 if (fd < 0) {
335 if (errno == ENOENT || errno == ENXIO ||
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100336 errno == ENODEV || errno == EACCES) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200337 PyErr_SetString(PyExc_NotImplementedError,
338 "/dev/urandom (or equivalent) not found");
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100339 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200340 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200341 return -1;
342 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200343 if (urandom_cache.fd >= 0) {
344 /* urandom_fd was initialized by another thread while we were
345 not holding the GIL, keep it. */
346 close(fd);
347 fd = urandom_cache.fd;
348 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200349 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200350 if (_Py_fstat(fd, &st)) {
351 close(fd);
352 return -1;
353 }
354 else {
355 urandom_cache.fd = fd;
356 urandom_cache.st_dev = st.st_dev;
357 urandom_cache.st_ino = st.st_ino;
358 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200359 }
360 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100361
Victor Stinner6974cf22016-08-16 18:46:38 +0200362 do {
363 n = _Py_read(fd, buffer, (size_t)size);
364 if (n == -1)
365 return -1;
366 if (n == 0) {
367 PyErr_Format(PyExc_RuntimeError,
368 "Failed to read %zi bytes from /dev/urandom",
369 size);
370 return -1;
371 }
372
373 buffer += n;
374 size -= n;
375 } while (0 < size);
376 }
377 else {
378 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
379 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100380 return -1;
381 }
382
Victor Stinner6974cf22016-08-16 18:46:38 +0200383 while (0 < size)
384 {
385 do {
386 n = read(fd, buffer, (size_t)size);
387 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100388
Victor Stinner6974cf22016-08-16 18:46:38 +0200389 if (n <= 0) {
390 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200391 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200392 return -1;
393 }
394
395 buffer += n;
396 size -= n;
397 }
398 close(fd);
399 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100400 return 0;
401}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200402
403static void
404dev_urandom_close(void)
405{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200406 if (urandom_cache.fd >= 0) {
407 close(urandom_cache.fd);
408 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200409 }
410}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100411#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200412
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100413
414/* Fill buffer with pseudo-random bytes generated by a linear congruent
415 generator (LCG):
416
417 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
418
419 Use bits 23..16 of x(n) to generate a byte. */
420static void
421lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
422{
423 size_t index;
424 unsigned int x;
425
426 x = x0;
427 for (index=0; index < size; index++) {
428 x *= 214013;
429 x += 2531011;
430 /* modulo 2 ^ (8 * sizeof(int)) */
431 buffer[index] = (x >> 16) & 0xff;
432 }
433}
434
Victor Stinnera49a2072017-01-06 11:17:52 +0100435/* Read random bytes:
436
437 - Return 0 on success
438 - Raise an exception (if raise is non-zero) and return -1 on error
439
440 Used sources of entropy ordered by preference, preferred source first:
441
442 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100443 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100444 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100445 - /dev/urandom device
446
447 Read from the /dev/urandom device if getrandom() or getentropy() function
448 is not available or does not work.
449
Victor Stinner2f796432017-01-06 11:26:01 +0100450 Prefer getrandom() over getentropy() because getrandom() supports blocking
451 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
452 startup to initialize its hash secret, but os.urandom() must block until the
453 system urandom is initialized (at least on Linux 3.17 and newer).
454
Victor Stinnera49a2072017-01-06 11:17:52 +0100455 Prefer getrandom() and getentropy() over reading directly /dev/urandom
456 because these functions don't need file descriptors and so avoid ENFILE or
457 EMFILE errors (too many open files): see the issue #18756.
458
459 Only the getrandom() function supports non-blocking mode.
460
461 Only use RNG running in the kernel. They are more secure because it is
462 harder to get the internal state of a RNG running in the kernel land than a
463 RNG running in the user land. The kernel has a direct access to the hardware
464 and has access to hardware RNG, they are used as entropy sources.
465
466 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
467 its RNG on fork(), two child processes (with the same pid) generate the same
468 random numbers: see issue #18747. Kernel RNGs don't have this issue,
469 they have access to good quality entropy sources.
470
471 If raise is zero:
472
473 - Don't raise an exception on error
474 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
475 a function fails with EINTR: retry directly the interrupted function
476 - Don't release the GIL to call functions.
477*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200478static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700479pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200480{
Victor Stinnera49a2072017-01-06 11:17:52 +0100481#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
482 int res;
483#endif
484
Victor Stinner4bad3b62016-08-16 15:23:58 +0200485 if (size < 0) {
486 if (raise) {
487 PyErr_Format(PyExc_ValueError,
488 "negative argument not allowed");
489 }
490 return -1;
491 }
492
493 if (size == 0) {
494 return 0;
495 }
496
497#ifdef MS_WINDOWS
498 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200499#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100500
501#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Victor Stinner2f796432017-01-06 11:26:01 +0100502#ifdef PY_GETRANDOM
Victor Stinnera49a2072017-01-06 11:17:52 +0100503 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100504#else
505 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100506#endif
507 if (res < 0) {
508 return -1;
509 }
510 if (res == 1) {
511 return 0;
512 }
513 /* getrandom() or getentropy() function is not available: failed with
514 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
515#endif
516
517 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200518#endif
519}
520
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200521/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200522 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200523 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100524
Victor Stinnere66987e2016-09-06 16:33:52 -0700525 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
526 block until the system urandom entropy pool is initialized (128 bits are
527 collected by the kernel).
528
529 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100530int
531_PyOS_URandom(void *buffer, Py_ssize_t size)
532{
Victor Stinnere66987e2016-09-06 16:33:52 -0700533 return pyurandom(buffer, size, 1, 1);
534}
535
536/* Fill buffer with size pseudo-random bytes from the operating system random
537 number generator (RNG). It is not suitable for cryptographic purpose.
538
539 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
540 urandom is not initialized yet, the function returns "weak" entropy read
541 from /dev/urandom.
542
543 Return 0 on success. Raise an exception and return -1 on error. */
544int
545_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
546{
547 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100548}
549
Victor Stinner358e5e12017-12-15 00:51:22 +0100550
551_PyInitError
552_Py_HashRandomization_Init(const _PyCoreConfig *config)
Eric Snow6b4be192017-05-22 21:36:03 -0700553{
554 void *secret = &_Py_HashSecret;
555 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100556
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800557 if (_Py_HashSecret_Initialized) {
558 return _Py_INIT_OK();
559 }
Benjamin Peterson69e97272012-02-21 11:08:50 -0500560 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100561
Victor Stinner358e5e12017-12-15 00:51:22 +0100562 if (config->use_hash_seed) {
563 if (config->hash_seed == 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100564 /* disable the randomized hash */
565 memset(secret, 0, secret_size);
566 }
567 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700568 /* use the specified hash seed */
Victor Stinner358e5e12017-12-15 00:51:22 +0100569 lcg_urandom(config->hash_seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100570 }
571 }
572 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700573 /* use a random hash seed */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200574 int res;
575
576 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700577 and so exceptions cannot be used (use raise=0).
578
579 _PyRandom_Init() must not block Python initialization: call
580 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
581 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200582 if (res < 0) {
Victor Stinnera7368ac2017-11-15 18:11:45 -0800583 return _Py_INIT_USER_ERR("failed to get random numbers "
584 "to initialize Python");
Victor Stinner4bad3b62016-08-16 15:23:58 +0200585 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100586 }
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800587 return _Py_INIT_OK();
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100588}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200589
Eric Snow6b4be192017-05-22 21:36:03 -0700590
591void
592_Py_HashRandomization_Fini(void)
Antoine Pitrou4879a962013-08-31 00:26:02 +0200593{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200594#ifdef MS_WINDOWS
595 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100596 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200597 hCryptProv = 0;
598 }
599#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200600 dev_urandom_close();
601#endif
602}