blob: 073b2ea8dbda741d17e38012004e55c069f150ca [file] [log] [blame]
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001#include "Python.h"
2#ifdef MS_WINDOWS
Victor Stinner59f7fb22015-03-18 14:39:33 +01003# include <windows.h>
Martin Panterd2f87472016-07-29 04:00:44 +00004/* All sample MSDN wincrypt programs include the header below. It is at least
5 * required with Min GW. */
6# include <wincrypt.h>
Georg Brandl2daf6ae2012-02-20 19:54:16 +01007#else
Victor Stinner59f7fb22015-03-18 14:39:33 +01008# include <fcntl.h>
9# ifdef HAVE_SYS_STAT_H
10# include <sys/stat.h>
11# endif
Victor Stinnerdddf4842016-06-07 11:21:42 +020012# ifdef HAVE_LINUX_RANDOM_H
13# include <linux/random.h>
14# endif
Benjamin Peterson493ac1b2017-01-01 22:29:36 -060015# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY))
Victor Stinnerbae2d622015-10-01 09:47:30 +020016# include <sys/random.h>
Ned Deily7ae41122016-11-12 16:35:48 -050017# endif
18# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinner59f7fb22015-03-18 14:39:33 +010019# include <sys/syscall.h>
Victor Stinner59f7fb22015-03-18 14:39:33 +010020# endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010021#endif
22
Benjamin Peterson69e97272012-02-21 11:08:50 -050023#ifdef Py_DEBUG
24int _Py_HashSecret_Initialized = 0;
25#else
26static int _Py_HashSecret_Initialized = 0;
27#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010028
29#ifdef MS_WINDOWS
Georg Brandl2daf6ae2012-02-20 19:54:16 +010030static HCRYPTPROV hCryptProv = 0;
31
32static int
33win32_urandom_init(int raise)
34{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010035 /* Acquire context */
Martin v. Löwis3f50bf62013-01-25 14:06:18 +010036 if (!CryptAcquireContext(&hCryptProv, NULL, NULL,
37 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010038 goto error;
39
40 return 0;
41
42error:
Victor Stinner4bad3b62016-08-16 15:23:58 +020043 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010044 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020045 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010046 return -1;
47}
48
49/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
Victor Stinner4d6a3d62014-12-21 01:16:38 +010050 API. Return 0 on success, or raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +010051static int
52win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
53{
54 Py_ssize_t chunk;
55
56 if (hCryptProv == 0)
57 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020058 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010059 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020060 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010061 }
62
63 while (size > 0)
64 {
65 chunk = size > INT_MAX ? INT_MAX : size;
Victor Stinner0c083462013-11-15 23:26:25 +010066 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010067 {
68 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020069 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010070 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020071 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010072 return -1;
73 }
74 buffer += chunk;
75 size -= chunk;
76 }
77 return 0;
78}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010079
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010080#else /* !MS_WINDOWS */
81
Victor Stinner2f796432017-01-06 11:26:01 +010082#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020083#define PY_GETRANDOM 1
84
Victor Stinnerb27df6f2017-01-06 11:39:15 +010085/* Call getrandom() to get random bytes:
86
Victor Stinner6974cf22016-08-16 18:46:38 +020087 - Return 1 on success
Victor Stinnerb27df6f2017-01-06 11:39:15 +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) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +020091 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinnerb27df6f2017-01-06 11:39:15 +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
Victor Stinnere66987e2016-09-06 16:33:52 -070098py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +010099{
Victor Stinnere66987e2016-09-06 16:33:52 -0700100 /* 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 Stinnere66987e2016-09-06 16:33:52 -0700104 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200105 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200106 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100107
Victor Stinner6974cf22016-08-16 18:46:38 +0200108 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100109 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200110 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100111
Victor Stinnere66987e2016-09-06 16:33:52 -0700112 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200113 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100114 while (0 < size) {
Victor Stinner9d242712016-04-12 22:28:49 +0200115#ifdef sun
116 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100117 to 1024 bytes. Call it multiple times if more bytes are
118 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200119 n = Py_MIN(size, 1024);
120#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200121 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200122#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200123
Victor Stinner9d242712016-04-12 22:28:49 +0200124 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200125#ifdef HAVE_GETRANDOM
126 if (raise) {
127 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200128 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200129 Py_END_ALLOW_THREADS
130 }
131 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200132 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200133 }
134#else
135 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200136 expose the Linux getrandom() syscall yet. See:
137 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200138 if (raise) {
139 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200140 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200141 Py_END_ALLOW_THREADS
142 }
143 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200144 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200145 }
Victor Stinnerbae2d622015-10-01 09:47:30 +0200146#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200147
Victor Stinner59f7fb22015-03-18 14:39:33 +0100148 if (n < 0) {
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100149 /* ENOSYS: the syscall is not supported by the kernel.
150 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
151 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200152 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100153 getrandom_works = 0;
154 return 0;
155 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200156
Victor Stinnere66987e2016-09-06 16:33:52 -0700157 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100158 is not initialiazed yet. For _PyRandom_Init(), we ignore the
Victor Stinnere66987e2016-09-06 16:33:52 -0700159 error and fall back on reading /dev/urandom which never blocks,
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100160 even if the system urandom is not initialized yet:
161 see the PEP 524. */
Victor Stinnere66987e2016-09-06 16:33:52 -0700162 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200163 return 0;
164 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100165
166 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200167 if (raise) {
168 if (PyErr_CheckSignals()) {
169 return -1;
170 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100171 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200172
173 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100174 continue;
175 }
176
Victor Stinner4bad3b62016-08-16 15:23:58 +0200177 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100178 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200179 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100180 return -1;
181 }
182
Victor Stinnercfb19612016-06-08 10:16:50 +0200183 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100184 size -= n;
185 }
186 return 1;
187}
Victor Stinner2f796432017-01-06 11:26:01 +0100188
189#elif defined(HAVE_GETENTROPY)
190#define PY_GETENTROPY 1
191
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100192/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100193
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100194 - Return 1 on success
195 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
196 EPERM).
197 - Raise an exception (if raise is non-zero) and return -1 on error:
198 if getentropy() failed with EINTR, raise is non-zero and the Python signal
199 handler raised an exception, or if getentropy() failed with a different
200 error.
201
202 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner2f796432017-01-06 11:26:01 +0100203static int
204py_getentropy(char *buffer, Py_ssize_t size, int raise)
205{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100206 /* Is getentropy() supported by the running kernel? Set to 0 if
207 getentropy() failed with ENOSYS or EPERM. */
208 static int getentropy_works = 1;
209
210 if (!getentropy_works) {
211 return 0;
212 }
213
Victor Stinner2f796432017-01-06 11:26:01 +0100214 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100215 /* getentropy() is limited to returning up to 256 bytes. Call it
216 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100217 Py_ssize_t len = Py_MIN(size, 256);
218 int res;
219
220 if (raise) {
221 Py_BEGIN_ALLOW_THREADS
222 res = getentropy(buffer, len);
223 Py_END_ALLOW_THREADS
224 }
225 else {
226 res = getentropy(buffer, len);
227 }
228
229 if (res < 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100230 /* ENOSYS: the syscall is not supported by the running kernel.
231 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
232 or something else. */
233 if (errno == ENOSYS || errno == EPERM) {
234 getentropy_works = 0;
235 return 0;
236 }
237
238 if (errno == EINTR) {
239 if (raise) {
240 if (PyErr_CheckSignals()) {
241 return -1;
242 }
243 }
244
245 /* retry getentropy() if it was interrupted by a signal */
246 continue;
247 }
248
Victor Stinner2f796432017-01-06 11:26:01 +0100249 if (raise) {
250 PyErr_SetFromErrno(PyExc_OSError);
251 }
252 return -1;
253 }
254
255 buffer += len;
256 size -= len;
257 }
258 return 1;
259}
260#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100261
Victor Stinner59f7fb22015-03-18 14:39:33 +0100262
Antoine Pitroue472aea2014-04-26 14:33:03 +0200263static struct {
264 int fd;
265 dev_t st_dev;
266 ino_t st_ino;
267} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100268
Victor Stinnera49a2072017-01-06 11:17:52 +0100269/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200270
Victor Stinnera49a2072017-01-06 11:17:52 +0100271 - Return 0 on success
272 - Raise an exception (if raise is non-zero) and return -1 on error
273
274 Possible causes of errors:
275
276 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
277 was not found. For example, it was removed manually or not exposed in a
278 chroot or container.
279 - open() failed with a different error
280 - fstat() failed
281 - read() failed or returned 0
282
283 read() is retried if it failed with EINTR: interrupted by a signal.
284
285 The file descriptor of the device is kept open between calls to avoid using
286 many file descriptors when run in parallel from multiple threads:
287 see the issue #18756.
288
289 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
290 check if the file descriptor was replaced by a different file (which is
291 likely a bug in the application): see the issue #21207.
292
293 If the file descriptor was closed or replaced, open a new file descriptor
294 but don't close the old file descriptor: it probably points to something
295 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200296static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100297dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100298{
299 int fd;
300 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200301
302 if (raise) {
303 struct _Py_stat_struct st;
Nir Soffer4484f9d2018-03-12 01:39:22 +0200304 int fstat_result;
Victor Stinner6974cf22016-08-16 18:46:38 +0200305
Antoine Pitroue472aea2014-04-26 14:33:03 +0200306 if (urandom_cache.fd >= 0) {
Nir Soffer4484f9d2018-03-12 01:39:22 +0200307 Py_BEGIN_ALLOW_THREADS
308 fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
309 Py_END_ALLOW_THREADS
310
Victor Stinner6974cf22016-08-16 18:46:38 +0200311 /* Does the fd point to the same thing as before? (issue #21207) */
Nir Soffer4484f9d2018-03-12 01:39:22 +0200312 if (fstat_result
Victor Stinner6974cf22016-08-16 18:46:38 +0200313 || st.st_dev != urandom_cache.st_dev
314 || st.st_ino != urandom_cache.st_ino) {
315 /* Something changed: forget the cached fd (but don't close it,
316 since it probably points to something important for some
317 third-party code). */
318 urandom_cache.fd = -1;
319 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200320 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200321 if (urandom_cache.fd >= 0)
322 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200323 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200324 fd = _Py_open("/dev/urandom", O_RDONLY);
325 if (fd < 0) {
326 if (errno == ENOENT || errno == ENXIO ||
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100327 errno == ENODEV || errno == EACCES) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200328 PyErr_SetString(PyExc_NotImplementedError,
329 "/dev/urandom (or equivalent) not found");
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100330 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200331 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200332 return -1;
333 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200334 if (urandom_cache.fd >= 0) {
335 /* urandom_fd was initialized by another thread while we were
336 not holding the GIL, keep it. */
337 close(fd);
338 fd = urandom_cache.fd;
339 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200340 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200341 if (_Py_fstat(fd, &st)) {
342 close(fd);
343 return -1;
344 }
345 else {
346 urandom_cache.fd = fd;
347 urandom_cache.st_dev = st.st_dev;
348 urandom_cache.st_ino = st.st_ino;
349 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200350 }
351 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100352
Victor Stinner6974cf22016-08-16 18:46:38 +0200353 do {
354 n = _Py_read(fd, buffer, (size_t)size);
355 if (n == -1)
356 return -1;
357 if (n == 0) {
358 PyErr_Format(PyExc_RuntimeError,
359 "Failed to read %zi bytes from /dev/urandom",
360 size);
361 return -1;
362 }
363
364 buffer += n;
365 size -= n;
366 } while (0 < size);
367 }
368 else {
369 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
370 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100371 return -1;
372 }
373
Victor Stinner6974cf22016-08-16 18:46:38 +0200374 while (0 < size)
375 {
376 do {
377 n = read(fd, buffer, (size_t)size);
378 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100379
Victor Stinner6974cf22016-08-16 18:46:38 +0200380 if (n <= 0) {
381 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200382 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200383 return -1;
384 }
385
386 buffer += n;
387 size -= n;
388 }
389 close(fd);
390 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100391 return 0;
392}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200393
394static void
395dev_urandom_close(void)
396{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200397 if (urandom_cache.fd >= 0) {
398 close(urandom_cache.fd);
399 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200400 }
401}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100402#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200403
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100404
405/* Fill buffer with pseudo-random bytes generated by a linear congruent
406 generator (LCG):
407
408 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
409
410 Use bits 23..16 of x(n) to generate a byte. */
411static void
412lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
413{
414 size_t index;
415 unsigned int x;
416
417 x = x0;
418 for (index=0; index < size; index++) {
419 x *= 214013;
420 x += 2531011;
421 /* modulo 2 ^ (8 * sizeof(int)) */
422 buffer[index] = (x >> 16) & 0xff;
423 }
424}
425
Victor Stinnera49a2072017-01-06 11:17:52 +0100426/* Read random bytes:
427
428 - Return 0 on success
429 - Raise an exception (if raise is non-zero) and return -1 on error
430
431 Used sources of entropy ordered by preference, preferred source first:
432
433 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100434 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100435 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100436 - /dev/urandom device
437
438 Read from the /dev/urandom device if getrandom() or getentropy() function
439 is not available or does not work.
440
Victor Stinner2f796432017-01-06 11:26:01 +0100441 Prefer getrandom() over getentropy() because getrandom() supports blocking
442 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
443 startup to initialize its hash secret, but os.urandom() must block until the
444 system urandom is initialized (at least on Linux 3.17 and newer).
445
Victor Stinnera49a2072017-01-06 11:17:52 +0100446 Prefer getrandom() and getentropy() over reading directly /dev/urandom
447 because these functions don't need file descriptors and so avoid ENFILE or
448 EMFILE errors (too many open files): see the issue #18756.
449
450 Only the getrandom() function supports non-blocking mode.
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*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200469static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700470pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200471{
Victor Stinnera49a2072017-01-06 11:17:52 +0100472#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
473 int res;
474#endif
475
Victor Stinner4bad3b62016-08-16 15:23:58 +0200476 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);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200490#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100491
492#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Victor Stinner2f796432017-01-06 11:26:01 +0100493#ifdef PY_GETRANDOM
Victor Stinnera49a2072017-01-06 11:17:52 +0100494 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100495#else
496 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100497#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 or EPERM. Fall back on reading from /dev/urandom. */
506#endif
507
508 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200509#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 Stinnere66987e2016-09-06 16:33:52 -0700516 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
517 block until the system urandom entropy pool is initialized (128 bits are
518 collected by the kernel).
519
520 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100521int
522_PyOS_URandom(void *buffer, Py_ssize_t size)
523{
Victor Stinnere66987e2016-09-06 16:33:52 -0700524 return pyurandom(buffer, size, 1, 1);
525}
526
527/* Fill buffer with size pseudo-random bytes from the operating system random
528 number generator (RNG). It is not suitable for cryptographic purpose.
529
530 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
531 urandom is not initialized yet, the function returns "weak" entropy read
532 from /dev/urandom.
533
534 Return 0 on success. Raise an exception and return -1 on error. */
535int
536_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
537{
538 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100539}
540
Victor Stinner358e5e12017-12-15 00:51:22 +0100541int
542_Py_ReadHashSeed(const char *seed_text,
543 int *use_hash_seed,
544 unsigned long *hash_seed)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100545{
Serhiy Storchakafad85aa2015-11-07 15:42:38 +0200546 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
Eric Snow6b4be192017-05-22 21:36:03 -0700547 /* Convert a text seed to a numeric one */
548 if (seed_text && *seed_text != '\0' && strcmp(seed_text, "random") != 0) {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200549 const char *endptr = seed_text;
Eric Snow6b4be192017-05-22 21:36:03 -0700550 unsigned long seed;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200551 seed = strtoul(seed_text, (char **)&endptr, 10);
Eric Snow6b4be192017-05-22 21:36:03 -0700552 if (*endptr != '\0'
553 || seed > 4294967295UL
554 || (errno == ERANGE && seed == ULONG_MAX))
555 {
556 return -1;
557 }
558 /* Use a specific hash */
559 *use_hash_seed = 1;
560 *hash_seed = seed;
561 }
562 else {
563 /* Use a random hash */
564 *use_hash_seed = 0;
565 *hash_seed = 0;
566 }
567 return 0;
568}
569
Victor Stinner358e5e12017-12-15 00:51:22 +0100570
571_PyInitError
572_Py_HashRandomization_Init(const _PyCoreConfig *config)
Eric Snow6b4be192017-05-22 21:36:03 -0700573{
574 void *secret = &_Py_HashSecret;
575 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100576
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800577 if (_Py_HashSecret_Initialized) {
578 return _Py_INIT_OK();
579 }
Benjamin Peterson69e97272012-02-21 11:08:50 -0500580 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100581
Victor Stinner358e5e12017-12-15 00:51:22 +0100582 if (config->use_hash_seed) {
583 if (config->hash_seed == 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100584 /* disable the randomized hash */
585 memset(secret, 0, secret_size);
586 }
587 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700588 /* use the specified hash seed */
Victor Stinner358e5e12017-12-15 00:51:22 +0100589 lcg_urandom(config->hash_seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100590 }
591 }
592 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700593 /* use a random hash seed */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200594 int res;
595
596 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700597 and so exceptions cannot be used (use raise=0).
598
599 _PyRandom_Init() must not block Python initialization: call
600 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
601 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200602 if (res < 0) {
Victor Stinnera7368ac2017-11-15 18:11:45 -0800603 return _Py_INIT_USER_ERR("failed to get random numbers "
604 "to initialize Python");
Victor Stinner4bad3b62016-08-16 15:23:58 +0200605 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100606 }
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800607 return _Py_INIT_OK();
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100608}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200609
Eric Snow6b4be192017-05-22 21:36:03 -0700610
611void
612_Py_HashRandomization_Fini(void)
Antoine Pitrou4879a962013-08-31 00:26:02 +0200613{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200614#ifdef MS_WINDOWS
615 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100616 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200617 hCryptProv = 0;
618 }
619#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200620 dev_urandom_close();
621#endif
622}