blob: dd752b86094d4ba0b6bd96d196ff35a5b77b2cc4 [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{
Georg Brandl2daf6ae2012-02-20 19:54:16 +010058 if (hCryptProv == 0)
59 {
Victor Stinner4bad3b62016-08-16 15:23:58 +020060 if (win32_urandom_init(raise) == -1) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010061 return -1;
Victor Stinner4bad3b62016-08-16 15:23:58 +020062 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010063 }
64
65 while (size > 0)
66 {
Victor Stinnerc48ff732018-11-22 14:43:07 +010067 DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX);
68 if (!CryptGenRandom(hCryptProv, chunk, buffer))
Georg Brandl2daf6ae2012-02-20 19:54:16 +010069 {
70 /* CryptGenRandom() failed */
Victor Stinner4bad3b62016-08-16 15:23:58 +020071 if (raise) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +010072 PyErr_SetFromWindowsErr(0);
Victor Stinner4bad3b62016-08-16 15:23:58 +020073 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +010074 return -1;
75 }
76 buffer += chunk;
77 size -= chunk;
78 }
79 return 0;
80}
Georg Brandl2daf6ae2012-02-20 19:54:16 +010081
Victor Stinnerdcdb60e2017-01-06 11:16:20 +010082#else /* !MS_WINDOWS */
83
Victor Stinner2f796432017-01-06 11:26:01 +010084#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Victor Stinnerbae2d622015-10-01 09:47:30 +020085#define PY_GETRANDOM 1
86
Victor Stinnerb27df6f2017-01-06 11:39:15 +010087/* Call getrandom() to get random bytes:
88
Victor Stinner6974cf22016-08-16 18:46:38 +020089 - Return 1 on success
Victor Stinnerb27df6f2017-01-06 11:39:15 +010090 - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
91 or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
92 initialized yet) and raise=0.
Victor Stinner6974cf22016-08-16 18:46:38 +020093 - Raise an exception (if raise is non-zero) and return -1 on error:
Victor Stinnerb27df6f2017-01-06 11:39:15 +010094 if getrandom() failed with EINTR, raise is non-zero and the Python signal
95 handler raised an exception, or if getrandom() failed with a different
96 error.
97
98 getrandom() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner59f7fb22015-03-18 14:39:33 +010099static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700100py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner59f7fb22015-03-18 14:39:33 +0100101{
Victor Stinnere66987e2016-09-06 16:33:52 -0700102 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
Victor Stinner6d8bc462016-09-20 22:46:02 +0200103 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
Victor Stinneraf597322016-09-20 22:26:18 +0200104 11.3 or newer */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100105 static int getrandom_works = 1;
Victor Stinnere66987e2016-09-06 16:33:52 -0700106 int flags;
Victor Stinnercfb19612016-06-08 10:16:50 +0200107 char *dest;
Victor Stinnerec721f32016-06-16 23:53:47 +0200108 long n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100109
Victor Stinner6974cf22016-08-16 18:46:38 +0200110 if (!getrandom_works) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100111 return 0;
Victor Stinner6974cf22016-08-16 18:46:38 +0200112 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100113
Victor Stinnere66987e2016-09-06 16:33:52 -0700114 flags = blocking ? 0 : GRND_NONBLOCK;
Victor Stinnercfb19612016-06-08 10:16:50 +0200115 dest = buffer;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100116 while (0 < size) {
Jakub KulĂ­k6f9bc722018-12-31 03:16:40 +0100117#if defined(__sun) && defined(__SVR4)
Victor Stinner9d242712016-04-12 22:28:49 +0200118 /* Issue #26735: On Solaris, getrandom() is limited to returning up
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100119 to 1024 bytes. Call it multiple times if more bytes are
120 requested. */
Victor Stinner9d242712016-04-12 22:28:49 +0200121 n = Py_MIN(size, 1024);
122#else
Victor Stinnerec721f32016-06-16 23:53:47 +0200123 n = Py_MIN(size, LONG_MAX);
Victor Stinner9d242712016-04-12 22:28:49 +0200124#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200125
Victor Stinner9d242712016-04-12 22:28:49 +0200126 errno = 0;
Victor Stinnerbae2d622015-10-01 09:47:30 +0200127#ifdef HAVE_GETRANDOM
128 if (raise) {
129 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200130 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200131 Py_END_ALLOW_THREADS
132 }
133 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200134 n = getrandom(dest, n, flags);
Victor Stinnerbae2d622015-10-01 09:47:30 +0200135 }
136#else
137 /* On Linux, use the syscall() function because the GNU libc doesn't
Victor Stinner6974cf22016-08-16 18:46:38 +0200138 expose the Linux getrandom() syscall yet. See:
139 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
Victor Stinner79b74ae2015-03-30 11:16:40 +0200140 if (raise) {
141 Py_BEGIN_ALLOW_THREADS
Victor Stinnercfb19612016-06-08 10:16:50 +0200142 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200143 Py_END_ALLOW_THREADS
144 }
145 else {
Victor Stinnercfb19612016-06-08 10:16:50 +0200146 n = syscall(SYS_getrandom, dest, n, flags);
Victor Stinner79b74ae2015-03-30 11:16:40 +0200147 }
Gregory P. Smith3015fb82018-11-12 22:01:22 -0800148# ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -0800149 if (n > 0) {
150 __msan_unpoison(dest, n);
151 }
152# endif
Victor Stinnerbae2d622015-10-01 09:47:30 +0200153#endif
Victor Stinner79b74ae2015-03-30 11:16:40 +0200154
Victor Stinner59f7fb22015-03-18 14:39:33 +0100155 if (n < 0) {
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100156 /* ENOSYS: the syscall is not supported by the kernel.
157 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
158 or something else. */
Victor Stinner6d8bc462016-09-20 22:46:02 +0200159 if (errno == ENOSYS || errno == EPERM) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100160 getrandom_works = 0;
161 return 0;
162 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200163
Victor Stinnere66987e2016-09-06 16:33:52 -0700164 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100165 is not initialiazed yet. For _PyRandom_Init(), we ignore the
Victor Stinnere66987e2016-09-06 16:33:52 -0700166 error and fall back on reading /dev/urandom which never blocks,
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100167 even if the system urandom is not initialized yet:
168 see the PEP 524. */
Victor Stinnere66987e2016-09-06 16:33:52 -0700169 if (errno == EAGAIN && !raise && !blocking) {
Victor Stinnerdddf4842016-06-07 11:21:42 +0200170 return 0;
171 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100172
173 if (errno == EINTR) {
Victor Stinnercecdd962016-08-16 15:19:09 +0200174 if (raise) {
175 if (PyErr_CheckSignals()) {
176 return -1;
177 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100178 }
Victor Stinnercecdd962016-08-16 15:19:09 +0200179
180 /* retry getrandom() if it was interrupted by a signal */
Victor Stinner59f7fb22015-03-18 14:39:33 +0100181 continue;
182 }
183
Victor Stinner4bad3b62016-08-16 15:23:58 +0200184 if (raise) {
Victor Stinner59f7fb22015-03-18 14:39:33 +0100185 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200186 }
Victor Stinner59f7fb22015-03-18 14:39:33 +0100187 return -1;
188 }
189
Victor Stinnercfb19612016-06-08 10:16:50 +0200190 dest += n;
Victor Stinner59f7fb22015-03-18 14:39:33 +0100191 size -= n;
192 }
193 return 1;
194}
Victor Stinner2f796432017-01-06 11:26:01 +0100195
196#elif defined(HAVE_GETENTROPY)
197#define PY_GETENTROPY 1
198
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100199/* Fill buffer with size pseudo-random bytes generated by getentropy():
Victor Stinner2f796432017-01-06 11:26:01 +0100200
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100201 - Return 1 on success
202 - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
203 EPERM).
204 - Raise an exception (if raise is non-zero) and return -1 on error:
205 if getentropy() failed with EINTR, raise is non-zero and the Python signal
206 handler raised an exception, or if getentropy() failed with a different
207 error.
208
209 getentropy() is retried if it failed with EINTR: interrupted by a signal. */
Victor Stinner2f796432017-01-06 11:26:01 +0100210static int
211py_getentropy(char *buffer, Py_ssize_t size, int raise)
212{
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100213 /* Is getentropy() supported by the running kernel? Set to 0 if
214 getentropy() failed with ENOSYS or EPERM. */
215 static int getentropy_works = 1;
216
217 if (!getentropy_works) {
218 return 0;
219 }
220
Victor Stinner2f796432017-01-06 11:26:01 +0100221 while (size > 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100222 /* getentropy() is limited to returning up to 256 bytes. Call it
223 multiple times if more bytes are requested. */
Victor Stinner2f796432017-01-06 11:26:01 +0100224 Py_ssize_t len = Py_MIN(size, 256);
225 int res;
226
227 if (raise) {
228 Py_BEGIN_ALLOW_THREADS
229 res = getentropy(buffer, len);
230 Py_END_ALLOW_THREADS
231 }
232 else {
233 res = getentropy(buffer, len);
234 }
235
236 if (res < 0) {
Victor Stinnerde2f1ea2017-01-06 11:33:18 +0100237 /* ENOSYS: the syscall is not supported by the running kernel.
238 EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
239 or something else. */
240 if (errno == ENOSYS || errno == EPERM) {
241 getentropy_works = 0;
242 return 0;
243 }
244
245 if (errno == EINTR) {
246 if (raise) {
247 if (PyErr_CheckSignals()) {
248 return -1;
249 }
250 }
251
252 /* retry getentropy() if it was interrupted by a signal */
253 continue;
254 }
255
Victor Stinner2f796432017-01-06 11:26:01 +0100256 if (raise) {
257 PyErr_SetFromErrno(PyExc_OSError);
258 }
259 return -1;
260 }
261
262 buffer += len;
263 size -= len;
264 }
265 return 1;
266}
Jakub KulĂ­k6f9bc722018-12-31 03:16:40 +0100267#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100268
Victor Stinner59f7fb22015-03-18 14:39:33 +0100269
Antoine Pitroue472aea2014-04-26 14:33:03 +0200270static struct {
271 int fd;
272 dev_t st_dev;
273 ino_t st_ino;
274} urandom_cache = { -1 };
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100275
Victor Stinnera49a2072017-01-06 11:17:52 +0100276/* Read random bytes from the /dev/urandom device:
Victor Stinner6974cf22016-08-16 18:46:38 +0200277
Victor Stinnera49a2072017-01-06 11:17:52 +0100278 - Return 0 on success
279 - Raise an exception (if raise is non-zero) and return -1 on error
280
281 Possible causes of errors:
282
283 - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
284 was not found. For example, it was removed manually or not exposed in a
285 chroot or container.
286 - open() failed with a different error
287 - fstat() failed
288 - read() failed or returned 0
289
290 read() is retried if it failed with EINTR: interrupted by a signal.
291
292 The file descriptor of the device is kept open between calls to avoid using
293 many file descriptors when run in parallel from multiple threads:
294 see the issue #18756.
295
296 st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
297 check if the file descriptor was replaced by a different file (which is
298 likely a bug in the application): see the issue #21207.
299
300 If the file descriptor was closed or replaced, open a new file descriptor
301 but don't close the old file descriptor: it probably points to something
302 important for some third-party code. */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200303static int
Victor Stinnera49a2072017-01-06 11:17:52 +0100304dev_urandom(char *buffer, Py_ssize_t size, int raise)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100305{
306 int fd;
307 Py_ssize_t n;
Victor Stinner6974cf22016-08-16 18:46:38 +0200308
309 if (raise) {
310 struct _Py_stat_struct st;
Nir Soffer4484f9d2018-03-12 01:39:22 +0200311 int fstat_result;
Victor Stinner6974cf22016-08-16 18:46:38 +0200312
Antoine Pitroue472aea2014-04-26 14:33:03 +0200313 if (urandom_cache.fd >= 0) {
Nir Soffer4484f9d2018-03-12 01:39:22 +0200314 Py_BEGIN_ALLOW_THREADS
315 fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
316 Py_END_ALLOW_THREADS
317
Victor Stinner6974cf22016-08-16 18:46:38 +0200318 /* Does the fd point to the same thing as before? (issue #21207) */
Nir Soffer4484f9d2018-03-12 01:39:22 +0200319 if (fstat_result
Victor Stinner6974cf22016-08-16 18:46:38 +0200320 || st.st_dev != urandom_cache.st_dev
321 || st.st_ino != urandom_cache.st_ino) {
322 /* Something changed: forget the cached fd (but don't close it,
323 since it probably points to something important for some
324 third-party code). */
325 urandom_cache.fd = -1;
326 }
Antoine Pitrou4879a962013-08-31 00:26:02 +0200327 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200328 if (urandom_cache.fd >= 0)
329 fd = urandom_cache.fd;
Antoine Pitroue472aea2014-04-26 14:33:03 +0200330 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200331 fd = _Py_open("/dev/urandom", O_RDONLY);
332 if (fd < 0) {
333 if (errno == ENOENT || errno == ENXIO ||
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100334 errno == ENODEV || errno == EACCES) {
Victor Stinner6974cf22016-08-16 18:46:38 +0200335 PyErr_SetString(PyExc_NotImplementedError,
336 "/dev/urandom (or equivalent) not found");
Victor Stinnerb27df6f2017-01-06 11:39:15 +0100337 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200338 /* otherwise, keep the OSError exception raised by _Py_open() */
Antoine Pitroue472aea2014-04-26 14:33:03 +0200339 return -1;
340 }
Victor Stinner6974cf22016-08-16 18:46:38 +0200341 if (urandom_cache.fd >= 0) {
342 /* urandom_fd was initialized by another thread while we were
343 not holding the GIL, keep it. */
344 close(fd);
345 fd = urandom_cache.fd;
346 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200347 else {
Victor Stinner6974cf22016-08-16 18:46:38 +0200348 if (_Py_fstat(fd, &st)) {
349 close(fd);
350 return -1;
351 }
352 else {
353 urandom_cache.fd = fd;
354 urandom_cache.st_dev = st.st_dev;
355 urandom_cache.st_ino = st.st_ino;
356 }
Antoine Pitroue472aea2014-04-26 14:33:03 +0200357 }
358 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100359
Victor Stinner6974cf22016-08-16 18:46:38 +0200360 do {
361 n = _Py_read(fd, buffer, (size_t)size);
362 if (n == -1)
363 return -1;
364 if (n == 0) {
365 PyErr_Format(PyExc_RuntimeError,
366 "Failed to read %zi bytes from /dev/urandom",
367 size);
368 return -1;
369 }
370
371 buffer += n;
372 size -= n;
373 } while (0 < size);
374 }
375 else {
376 fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
377 if (fd < 0) {
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100378 return -1;
379 }
380
Victor Stinner6974cf22016-08-16 18:46:38 +0200381 while (0 < size)
382 {
383 do {
384 n = read(fd, buffer, (size_t)size);
385 } while (n < 0 && errno == EINTR);
Victor Stinnerc9382eb2015-03-19 23:36:33 +0100386
Victor Stinner6974cf22016-08-16 18:46:38 +0200387 if (n <= 0) {
388 /* stop on error or if read(size) returned 0 */
Victor Stinner3ee933f2016-08-16 18:27:44 +0200389 close(fd);
Victor Stinner6974cf22016-08-16 18:46:38 +0200390 return -1;
391 }
392
393 buffer += n;
394 size -= n;
395 }
396 close(fd);
397 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100398 return 0;
399}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200400
401static void
402dev_urandom_close(void)
403{
Antoine Pitroue472aea2014-04-26 14:33:03 +0200404 if (urandom_cache.fd >= 0) {
405 close(urandom_cache.fd);
406 urandom_cache.fd = -1;
Antoine Pitrou4879a962013-08-31 00:26:02 +0200407 }
408}
Victor Stinnerdcdb60e2017-01-06 11:16:20 +0100409#endif /* !MS_WINDOWS */
Antoine Pitrou4879a962013-08-31 00:26:02 +0200410
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100411
412/* Fill buffer with pseudo-random bytes generated by a linear congruent
413 generator (LCG):
414
415 x(n+1) = (x(n) * 214013 + 2531011) % 2^32
416
417 Use bits 23..16 of x(n) to generate a byte. */
418static void
419lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
420{
421 size_t index;
422 unsigned int x;
423
424 x = x0;
425 for (index=0; index < size; index++) {
426 x *= 214013;
427 x += 2531011;
428 /* modulo 2 ^ (8 * sizeof(int)) */
429 buffer[index] = (x >> 16) & 0xff;
430 }
431}
432
Victor Stinnera49a2072017-01-06 11:17:52 +0100433/* Read random bytes:
434
435 - Return 0 on success
436 - Raise an exception (if raise is non-zero) and return -1 on error
437
438 Used sources of entropy ordered by preference, preferred source first:
439
440 - CryptGenRandom() on Windows
Victor Stinnera49a2072017-01-06 11:17:52 +0100441 - getrandom() function (ex: Linux and Solaris): call py_getrandom()
Victor Stinner2f796432017-01-06 11:26:01 +0100442 - getentropy() function (ex: OpenBSD): call py_getentropy()
Victor Stinnera49a2072017-01-06 11:17:52 +0100443 - /dev/urandom device
444
445 Read from the /dev/urandom device if getrandom() or getentropy() function
446 is not available or does not work.
447
Victor Stinner2f796432017-01-06 11:26:01 +0100448 Prefer getrandom() over getentropy() because getrandom() supports blocking
449 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
450 startup to initialize its hash secret, but os.urandom() must block until the
451 system urandom is initialized (at least on Linux 3.17 and newer).
452
Victor Stinnera49a2072017-01-06 11:17:52 +0100453 Prefer getrandom() and getentropy() over reading directly /dev/urandom
454 because these functions don't need file descriptors and so avoid ENFILE or
455 EMFILE errors (too many open files): see the issue #18756.
456
457 Only the getrandom() function supports non-blocking mode.
458
459 Only use RNG running in the kernel. They are more secure because it is
460 harder to get the internal state of a RNG running in the kernel land than a
461 RNG running in the user land. The kernel has a direct access to the hardware
462 and has access to hardware RNG, they are used as entropy sources.
463
464 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
465 its RNG on fork(), two child processes (with the same pid) generate the same
466 random numbers: see issue #18747. Kernel RNGs don't have this issue,
467 they have access to good quality entropy sources.
468
469 If raise is zero:
470
471 - Don't raise an exception on error
472 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
473 a function fails with EINTR: retry directly the interrupted function
474 - Don't release the GIL to call functions.
475*/
Victor Stinner4bad3b62016-08-16 15:23:58 +0200476static int
Victor Stinnere66987e2016-09-06 16:33:52 -0700477pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
Victor Stinner4bad3b62016-08-16 15:23:58 +0200478{
Victor Stinnera49a2072017-01-06 11:17:52 +0100479#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
480 int res;
481#endif
482
Victor Stinner4bad3b62016-08-16 15:23:58 +0200483 if (size < 0) {
484 if (raise) {
485 PyErr_Format(PyExc_ValueError,
486 "negative argument not allowed");
487 }
488 return -1;
489 }
490
491 if (size == 0) {
492 return 0;
493 }
494
495#ifdef MS_WINDOWS
496 return win32_urandom((unsigned char *)buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200497#else
Victor Stinnera49a2072017-01-06 11:17:52 +0100498
499#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
Victor Stinner2f796432017-01-06 11:26:01 +0100500#ifdef PY_GETRANDOM
Victor Stinnera49a2072017-01-06 11:17:52 +0100501 res = py_getrandom(buffer, size, blocking, raise);
Victor Stinner2f796432017-01-06 11:26:01 +0100502#else
503 res = py_getentropy(buffer, size, raise);
Victor Stinnera49a2072017-01-06 11:17:52 +0100504#endif
505 if (res < 0) {
506 return -1;
507 }
508 if (res == 1) {
509 return 0;
510 }
511 /* getrandom() or getentropy() function is not available: failed with
512 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
513#endif
514
515 return dev_urandom(buffer, size, raise);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200516#endif
517}
518
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200519/* Fill buffer with size pseudo-random bytes from the operating system random
Serhiy Storchaka56a6d852014-12-01 18:28:43 +0200520 number generator (RNG). It is suitable for most cryptographic purposes
Georg Brandlc6a2c9b2013-10-06 18:43:19 +0200521 except long living private keys for asymmetric encryption.
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100522
Victor Stinnere66987e2016-09-06 16:33:52 -0700523 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
524 block until the system urandom entropy pool is initialized (128 bits are
525 collected by the kernel).
526
527 Return 0 on success. Raise an exception and return -1 on error. */
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100528int
529_PyOS_URandom(void *buffer, Py_ssize_t size)
530{
Victor Stinnere66987e2016-09-06 16:33:52 -0700531 return pyurandom(buffer, size, 1, 1);
532}
533
534/* Fill buffer with size pseudo-random bytes from the operating system random
535 number generator (RNG). It is not suitable for cryptographic purpose.
536
537 On Linux 3.17 and newer (when getrandom() syscall is used), if the system
538 urandom is not initialized yet, the function returns "weak" entropy read
539 from /dev/urandom.
540
541 Return 0 on success. Raise an exception and return -1 on error. */
542int
543_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
544{
545 return pyurandom(buffer, size, 0, 1);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100546}
547
Victor Stinner358e5e12017-12-15 00:51:22 +0100548
549_PyInitError
550_Py_HashRandomization_Init(const _PyCoreConfig *config)
Eric Snow6b4be192017-05-22 21:36:03 -0700551{
552 void *secret = &_Py_HashSecret;
553 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100554
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800555 if (_Py_HashSecret_Initialized) {
556 return _Py_INIT_OK();
557 }
Benjamin Peterson69e97272012-02-21 11:08:50 -0500558 _Py_HashSecret_Initialized = 1;
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100559
Victor Stinner358e5e12017-12-15 00:51:22 +0100560 if (config->use_hash_seed) {
561 if (config->hash_seed == 0) {
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100562 /* disable the randomized hash */
563 memset(secret, 0, secret_size);
564 }
565 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700566 /* use the specified hash seed */
Victor Stinner358e5e12017-12-15 00:51:22 +0100567 lcg_urandom(config->hash_seed, secret, secret_size);
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100568 }
569 }
570 else {
Eric Snow6b4be192017-05-22 21:36:03 -0700571 /* use a random hash seed */
Victor Stinner4bad3b62016-08-16 15:23:58 +0200572 int res;
573
574 /* _PyRandom_Init() is called very early in the Python initialization
Victor Stinnere66987e2016-09-06 16:33:52 -0700575 and so exceptions cannot be used (use raise=0).
576
577 _PyRandom_Init() must not block Python initialization: call
578 pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
579 res = pyurandom(secret, secret_size, 0, 0);
Victor Stinner4bad3b62016-08-16 15:23:58 +0200580 if (res < 0) {
Victor Stinnerdb719752019-05-01 05:35:33 +0200581 return _Py_INIT_ERR("failed to get random numbers "
582 "to initialize Python");
Victor Stinner4bad3b62016-08-16 15:23:58 +0200583 }
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100584 }
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800585 return _Py_INIT_OK();
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100586}
Antoine Pitrou4879a962013-08-31 00:26:02 +0200587
Eric Snow6b4be192017-05-22 21:36:03 -0700588
589void
590_Py_HashRandomization_Fini(void)
Antoine Pitrou4879a962013-08-31 00:26:02 +0200591{
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200592#ifdef MS_WINDOWS
593 if (hCryptProv) {
Tim Goldenb8ac3e12014-05-06 13:29:45 +0100594 CryptReleaseContext(hCryptProv, 0);
Victor Stinnerd50c3f32014-05-02 22:06:44 +0200595 hCryptProv = 0;
596 }
597#else
Antoine Pitrou4879a962013-08-31 00:26:02 +0200598 dev_urandom_close();
599#endif
600}