blob: aa3a3dfd964edb19d6c8db1748e743b8586c63d6 [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
Benjamin Peterson69e97272012-02-21 11:08:50 -050028#ifdef Py_DEBUG
29int _Py_HashSecret_Initialized = 0;
30#else
31static int _Py_HashSecret_Initialized = 0;
32#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010033
34#ifdef MS_WINDOWS
Georg Brandl2daf6ae2012-02-20 19:54:16 +010035static HCRYPTPROV hCryptProv = 0;
36
37static int
38win32_urandom_init(int raise)
39{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010040 /* Acquire context */
Martin v. Löwis3f50bf62013-01-25 14:06:18 +010041 if (!CryptAcquireContext(&hCryptProv, NULL, NULL,
42 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010043 goto error;
44
45 return 0;
46
47error:
Victor Stinner4bad3b62016-08-16 15:23:58 +020048 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010049 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020050 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010051 return -1;
52}
53
54/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
Victor Stinner4d6a3d62014-12-21 01:16:38 +010055 API. Return 0 on success, or raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +010056static int
57win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
58{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010059 if (hCryptProv == 0)
60 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020061 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010062 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020063 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010064 }
65
66 while (size > 0)
67 {
Victor Stinnerc48ff732018-11-22 14:43:07 +010068 DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX);
69 if (!CryptGenRandom(hCryptProv, chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010070 {
71 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020072 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010073 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020074 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010075 return -1;
76 }
77 buffer += chunk;
78 size -= chunk;
79 }
80 return 0;
81}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010082
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010083#else /* !MS_WINDOWS */
84
Victor Stinner2f796432017-01-06 11:26:01 +010085#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020086#define PY_GETRANDOM 1
87
Victor Stinnerb27df6f2017-01-06 11:39:15 +010088/* Call getrandom() to get random bytes:
89
Victor Stinner6974cf22016-08-16 18:46:38 +020090 - Return 1 on success
Victor Stinnerb27df6f2017-01-06 11:39:15 +010091 - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
92 or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
93 initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +020094 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinnerb27df6f2017-01-06 11:39:15 +010095 if getrandom() failed with EINTR, raise is non-zero and the Python signal
96 handler raised an exception, or if getrandom() failed with a different
97 error.
98
99 getrandom() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100100static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700101py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +0100102{
Victor Stinnere66987e2016-09-06 16:33:52 -0700103 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200104 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200105 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100106 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700107 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200108 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200109 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100110
Victor Stinner6974cf22016-08-16 18:46:38 +0200111 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100112 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200113 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100114
Victor Stinnere66987e2016-09-06 16:33:52 -0700115 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200116 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100117 while (0 < size) {
Jakub KulĂ­k6f9bc722018-12-31 03:16:40 +0100118#if defined(__sun) && defined(__SVR4)
Victor Stinner9d242712016-04-12 22:28:49 +0200119 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100120 to 1024 bytes. Call it multiple times if more bytes are
121 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200122 n = Py_MIN(size, 1024);
123#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200124 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200125#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200126
Victor Stinner9d242712016-04-12 22:28:49 +0200127 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200128#ifdef HAVE_GETRANDOM
129 if (raise) {
130 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200131 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200132 Py_END_ALLOW_THREADS
133 }
134 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200135 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200136 }
137#else
138 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200139 expose the Linux getrandom() syscall yet. See:
140 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200141 if (raise) {
142 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200143 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200144 Py_END_ALLOW_THREADS
145 }
146 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200147 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200148 }
Gregory P. Smith3015fb82018-11-12 22:01:22 -0800149# ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -0800150 if (n > 0) {
151 __msan_unpoison(dest, n);
152 }
153# endif
Victor Stinnerbae2d622015-10-01 09:47:30 +0200154#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200155
Victor Stinner59f7fb22015-03-18 14:39:33 +0100156 if (n < 0) {
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100157 /* ENOSYS: the syscall is not supported by the kernel.
158 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
159 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200160 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100161 getrandom_works = 0;
162 return 0;
163 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200164
Victor Stinnere66987e2016-09-06 16:33:52 -0700165 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
Min ho Kimc4cacc82019-07-31 08:16:13 +1000166 is not initialized yet. For _PyRandom_Init(), we ignore the
Victor Stinnere66987e2016-09-06 16:33:52 -0700167 error and fall back on reading /dev/urandom which never blocks,
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100168 even if the system urandom is not initialized yet:
169 see the PEP 524. */
Victor Stinnere66987e2016-09-06 16:33:52 -0700170 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200171 return 0;
172 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100173
174 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200175 if (raise) {
176 if (PyErr_CheckSignals()) {
177 return -1;
178 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100179 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200180
181 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100182 continue;
183 }
184
Victor Stinner4bad3b62016-08-16 15:23:58 +0200185 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100186 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200187 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100188 return -1;
189 }
190
Victor Stinnercfb19612016-06-08 10:16:50 +0200191 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100192 size -= n;
193 }
194 return 1;
195}
Victor Stinner2f796432017-01-06 11:26:01 +0100196
197#elif defined(HAVE_GETENTROPY)
198#define PY_GETENTROPY 1
199
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100200/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100201
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100202 - 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. */
Victor Stinner2f796432017-01-06 11:26:01 +0100211static int
212py_getentropy(char *buffer, Py_ssize_t size, int raise)
213{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100214 /* 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
Victor Stinner2f796432017-01-06 11:26:01 +0100222 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100223 /* getentropy() is limited to returning up to 256 bytes. Call it
224 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100225 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) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100238 /* 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
Victor Stinner2f796432017-01-06 11:26:01 +0100257 if (raise) {
258 PyErr_SetFromErrno(PyExc_OSError);
259 }
260 return -1;
261 }
262
263 buffer += len;
264 size -= len;
265 }
266 return 1;
267}
Jakub KulĂ­k6f9bc722018-12-31 03:16:40 +0100268#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100269
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 Stinnera49a2072017-01-06 11:17:52 +0100277/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200278
Victor Stinnera49a2072017-01-06 11:17:52 +0100279 - Return 0 on success
280 - Raise an exception (if raise is non-zero) and return -1 on error
281
282 Possible causes of errors:
283
284 - 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
290
291 read() is retried if it failed with EINTR: interrupted by a signal.
292
293 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.
296
297 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.
300
301 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. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200304static int
Victor Stinnera49a2072017-01-06 11:17:52 +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;
Victor Stinner6974cf22016-08-16 18:46:38 +0200309
310 if (raise) {
311 struct _Py_stat_struct st;
Nir Soffer4484f9d2018-03-12 01:39:22 +0200312 int fstat_result;
Victor Stinner6974cf22016-08-16 18:46:38 +0200313
Antoine Pitroue472aea2014-04-26 14:33:03 +0200314 if (urandom_cache.fd >= 0) {
Nir Soffer4484f9d2018-03-12 01:39:22 +0200315 Py_BEGIN_ALLOW_THREADS
316 fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
317 Py_END_ALLOW_THREADS
318
Victor Stinner6974cf22016-08-16 18:46:38 +0200319 /* Does the fd point to the same thing as before? (issue #21207) */
Nir Soffer4484f9d2018-03-12 01:39:22 +0200320 if (fstat_result
Victor Stinner6974cf22016-08-16 18:46:38 +0200321 || st.st_dev != urandom_cache.st_dev
322 || st.st_ino != urandom_cache.st_ino) {
323 /* Something changed: forget the cached fd (but don't close it,
324 since it probably points to something important for some
325 third-party code). */
326 urandom_cache.fd = -1;
327 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200328 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200329 if (urandom_cache.fd >= 0)
330 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200331 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200332 fd = _Py_open("/dev/urandom", O_RDONLY);
333 if (fd < 0) {
334 if (errno == ENOENT || errno == ENXIO ||
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100335 errno == ENODEV || errno == EACCES) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200336 PyErr_SetString(PyExc_NotImplementedError,
337 "/dev/urandom (or equivalent) not found");
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100338 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200339 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200340 return -1;
341 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200342 if (urandom_cache.fd >= 0) {
343 /* urandom_fd was initialized by another thread while we were
344 not holding the GIL, keep it. */
345 close(fd);
346 fd = urandom_cache.fd;
347 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200348 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200349 if (_Py_fstat(fd, &st)) {
350 close(fd);
351 return -1;
352 }
353 else {
354 urandom_cache.fd = fd;
355 urandom_cache.st_dev = st.st_dev;
356 urandom_cache.st_ino = st.st_ino;
357 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200358 }
359 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100360
Victor Stinner6974cf22016-08-16 18:46:38 +0200361 do {
362 n = _Py_read(fd, buffer, (size_t)size);
363 if (n == -1)
364 return -1;
365 if (n == 0) {
366 PyErr_Format(PyExc_RuntimeError,
367 "Failed to read %zi bytes from /dev/urandom",
368 size);
369 return -1;
370 }
371
372 buffer += n;
373 size -= n;
374 } while (0 < size);
375 }
376 else {
377 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
378 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100379 return -1;
380 }
381
Victor Stinner6974cf22016-08-16 18:46:38 +0200382 while (0 < size)
383 {
384 do {
385 n = read(fd, buffer, (size_t)size);
386 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100387
Victor Stinner6974cf22016-08-16 18:46:38 +0200388 if (n <= 0) {
389 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200390 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200391 return -1;
392 }
393
394 buffer += n;
395 size -= n;
396 }
397 close(fd);
398 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100399 return 0;
400}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200401
402static void
403dev_urandom_close(void)
404{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200405 if (urandom_cache.fd >= 0) {
406 close(urandom_cache.fd);
407 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200408 }
409}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100410#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200411
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100412
413/* Fill buffer with pseudo-random bytes generated by a linear congruent
414 generator (LCG):
415
416 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
417
418 Use bits 23..16 of x(n) to generate a byte. */
419static void
420lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
421{
422 size_t index;
423 unsigned int x;
424
425 x = x0;
426 for (index=0; index < size; index++) {
427 x *= 214013;
428 x += 2531011;
429 /* modulo 2 ^ (8 * sizeof(int)) */
430 buffer[index] = (x >> 16) & 0xff;
431 }
432}
433
Victor Stinnera49a2072017-01-06 11:17:52 +0100434/* Read random bytes:
435
436 - Return 0 on success
437 - Raise an exception (if raise is non-zero) and return -1 on error
438
439 Used sources of entropy ordered by preference, preferred source first:
440
441 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100442 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100443 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100444 - /dev/urandom device
445
446 Read from the /dev/urandom device if getrandom() or getentropy() function
447 is not available or does not work.
448
Victor Stinner2f796432017-01-06 11:26:01 +0100449 Prefer getrandom() over getentropy() because getrandom() supports blocking
450 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
451 startup to initialize its hash secret, but os.urandom() must block until the
452 system urandom is initialized (at least on Linux 3.17 and newer).
453
Victor Stinnera49a2072017-01-06 11:17:52 +0100454 Prefer getrandom() and getentropy() over reading directly /dev/urandom
455 because these functions don't need file descriptors and so avoid ENFILE or
456 EMFILE errors (too many open files): see the issue #18756.
457
458 Only the getrandom() function supports non-blocking mode.
459
460 Only use RNG running in the kernel. They are more secure because it is
461 harder to get the internal state of a RNG running in the kernel land than a
462 RNG running in the user land. The kernel has a direct access to the hardware
463 and has access to hardware RNG, they are used as entropy sources.
464
465 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
466 its RNG on fork(), two child processes (with the same pid) generate the same
467 random numbers: see issue #18747. Kernel RNGs don't have this issue,
468 they have access to good quality entropy sources.
469
470 If raise is zero:
471
472 - Don't raise an exception on error
473 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
474 a function fails with EINTR: retry directly the interrupted function
475 - Don't release the GIL to call functions.
476*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200477static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700478pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200479{
Victor Stinnera49a2072017-01-06 11:17:52 +0100480#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
481 int res;
482#endif
483
Victor Stinner4bad3b62016-08-16 15:23:58 +0200484 if (size < 0) {
485 if (raise) {
486 PyErr_Format(PyExc_ValueError,
487 "negative argument not allowed");
488 }
489 return -1;
490 }
491
492 if (size == 0) {
493 return 0;
494 }
495
496#ifdef MS_WINDOWS
497 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200498#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100499
500#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Victor Stinner2f796432017-01-06 11:26:01 +0100501#ifdef PY_GETRANDOM
Victor Stinnera49a2072017-01-06 11:17:52 +0100502 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100503#else
504 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100505#endif
506 if (res < 0) {
507 return -1;
508 }
509 if (res == 1) {
510 return 0;
511 }
512 /* getrandom() or getentropy() function is not available: failed with
513 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
514#endif
515
516 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200517#endif
518}
519
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200520/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200521 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200522 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100523
Victor Stinnere66987e2016-09-06 16:33:52 -0700524 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
525 block until the system urandom entropy pool is initialized (128 bits are
526 collected by the kernel).
527
528 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100529int
530_PyOS_URandom(void *buffer, Py_ssize_t size)
531{
Victor Stinnere66987e2016-09-06 16:33:52 -0700532 return pyurandom(buffer, size, 1, 1);
533}
534
535/* Fill buffer with size pseudo-random bytes from the operating system random
536 number generator (RNG). It is not suitable for cryptographic purpose.
537
538 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
539 urandom is not initialized yet, the function returns "weak" entropy read
540 from /dev/urandom.
541
542 Return 0 on success. Raise an exception and return -1 on error. */
543int
544_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
545{
546 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100547}
548
Victor Stinner358e5e12017-12-15 00:51:22 +0100549
Victor Stinner331a6a52019-05-27 16:39:22 +0200550PyStatus
551_Py_HashRandomization_Init(const PyConfig *config)
Eric Snow6b4be192017-05-22 21:36:03 -0700552{
553 void *secret = &_Py_HashSecret;
554 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100555
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800556 if (_Py_HashSecret_Initialized) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200557 return _PyStatus_OK();
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800558 }
Benjamin Peterson69e97272012-02-21 11:08:50 -0500559 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100560
Victor Stinner358e5e12017-12-15 00:51:22 +0100561 if (config->use_hash_seed) {
562 if (config->hash_seed == 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100563 /* disable the randomized hash */
564 memset(secret, 0, secret_size);
565 }
566 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700567 /* use the specified hash seed */
Victor Stinner358e5e12017-12-15 00:51:22 +0100568 lcg_urandom(config->hash_seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100569 }
570 }
571 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700572 /* use a random hash seed */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200573 int res;
574
575 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700576 and so exceptions cannot be used (use raise=0).
577
578 _PyRandom_Init() must not block Python initialization: call
579 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
580 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200581 if (res < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200582 return _PyStatus_ERR("failed to get random numbers "
Victor Stinnerdb719752019-05-01 05:35:33 +0200583 "to initialize Python");
Victor Stinner4bad3b62016-08-16 15:23:58 +0200584 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100585 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200586 return _PyStatus_OK();
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100587}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200588
Eric Snow6b4be192017-05-22 21:36:03 -0700589
590void
591_Py_HashRandomization_Fini(void)
Antoine Pitrou4879a962013-08-31 00:26:02 +0200592{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200593#ifdef MS_WINDOWS
594 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100595 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200596 hCryptProv = 0;
597 }
598#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200599 dev_urandom_close();
600#endif
601}