1 #include "Python.h" 2 #ifdef MS_WINDOWS 3 # include <windows.h> 4 /* All sample MSDN wincrypt programs include the header below. It is at least 5 * required with Min GW. */ 6 # include <wincrypt.h> 7 #else 8 # include <fcntl.h> 9 # ifdef HAVE_SYS_STAT_H 10 # include <sys/stat.h> 11 # endif 12 # ifdef HAVE_LINUX_RANDOM_H 13 # include <linux/random.h> 14 # endif 15 # if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY)) 16 # include <sys/random.h> 17 # endif 18 # if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) 19 # include <sys/syscall.h> 20 # endif 21 #endif 22 23 #ifdef Py_DEBUG 24 int _Py_HashSecret_Initialized = 0; 25 #else 26 static int _Py_HashSecret_Initialized = 0; 27 #endif 28 29 #ifdef MS_WINDOWS 30 static HCRYPTPROV hCryptProv = 0; 31 32 static int 33 win32_urandom_init(int raise) 34 { 35 /* Acquire context */ 36 if (!CryptAcquireContext(&hCryptProv, NULL, NULL, 37 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 38 goto error; 39 40 return 0; 41 42 error: 43 if (raise) { 44 PyErr_SetFromWindowsErr(0); 45 } 46 return -1; 47 } 48 49 /* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen 50 API. Return 0 on success, or raise an exception and return -1 on error. */ 51 static int 52 win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) 53 { 54 Py_ssize_t chunk; 55 56 if (hCryptProv == 0) 57 { 58 if (win32_urandom_init(raise) == -1) { 59 return -1; 60 } 61 } 62 63 while (size > 0) 64 { 65 chunk = size > INT_MAX ? INT_MAX : size; 66 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer)) 67 { 68 /* CryptGenRandom() failed */ 69 if (raise) { 70 PyErr_SetFromWindowsErr(0); 71 } 72 return -1; 73 } 74 buffer += chunk; 75 size -= chunk; 76 } 77 return 0; 78 } 79 80 #else /* !MS_WINDOWS */ 81 82 #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) 83 #define PY_GETRANDOM 1 84 85 /* Call getrandom() to get random bytes: 86 87 - Return 1 on success 88 - 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. 91 - Raise an exception (if raise is non-zero) and return -1 on error: 92 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. */ 97 static int 98 py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) 99 { 100 /* Is getrandom() supported by the running kernel? Set to 0 if getrandom() 101 failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris 102 11.3 or newer */ 103 static int getrandom_works = 1; 104 int flags; 105 char *dest; 106 long n; 107 108 if (!getrandom_works) { 109 return 0; 110 } 111 112 flags = blocking ? 0 : GRND_NONBLOCK; 113 dest = buffer; 114 while (0 < size) { 115 #ifdef sun 116 /* Issue #26735: On Solaris, getrandom() is limited to returning up 117 to 1024 bytes. Call it multiple times if more bytes are 118 requested. */ 119 n = Py_MIN(size, 1024); 120 #else 121 n = Py_MIN(size, LONG_MAX); 122 #endif 123 124 errno = 0; 125 #ifdef HAVE_GETRANDOM 126 if (raise) { 127 Py_BEGIN_ALLOW_THREADS 128 n = getrandom(dest, n, flags); 129 Py_END_ALLOW_THREADS 130 } 131 else { 132 n = getrandom(dest, n, flags); 133 } 134 #else 135 /* On Linux, use the syscall() function because the GNU libc doesn't 136 expose the Linux getrandom() syscall yet. See: 137 https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */ 138 if (raise) { 139 Py_BEGIN_ALLOW_THREADS 140 n = syscall(SYS_getrandom, dest, n, flags); 141 Py_END_ALLOW_THREADS 142 } 143 else { 144 n = syscall(SYS_getrandom, dest, n, flags); 145 } 146 #endif 147 148 if (n < 0) { 149 /* 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. */ 152 if (errno == ENOSYS || errno == EPERM) { 153 getrandom_works = 0; 154 return 0; 155 } 156 157 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom 158 is not initialiazed yet. For _PyRandom_Init(), we ignore the 159 error and fall back on reading /dev/urandom which never blocks, 160 even if the system urandom is not initialized yet: 161 see the PEP 524. */ 162 if (errno == EAGAIN && !raise && !blocking) { 163 return 0; 164 } 165 166 if (errno == EINTR) { 167 if (raise) { 168 if (PyErr_CheckSignals()) { 169 return -1; 170 } 171 } 172 173 /* retry getrandom() if it was interrupted by a signal */ 174 continue; 175 } 176 177 if (raise) { 178 PyErr_SetFromErrno(PyExc_OSError); 179 } 180 return -1; 181 } 182 183 dest += n; 184 size -= n; 185 } 186 return 1; 187 } 188 189 #elif defined(HAVE_GETENTROPY) 190 #define PY_GETENTROPY 1 191 192 /* Fill buffer with size pseudo-random bytes generated by getentropy(): 193 194 - 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. */ 203 static int 204 py_getentropy(char *buffer, Py_ssize_t size, int raise) 205 { 206 /* 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 214 while (size > 0) { 215 /* getentropy() is limited to returning up to 256 bytes. Call it 216 multiple times if more bytes are requested. */ 217 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) { 230 /* 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 249 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) */ 261 262 263 static struct { 264 int fd; 265 dev_t st_dev; 266 ino_t st_ino; 267 } urandom_cache = { -1 }; 268 269 /* Read random bytes from the /dev/urandom device: 270 271 - 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. */ 296 static int 297 dev_urandom(char *buffer, Py_ssize_t size, int raise) 298 { 299 int fd; 300 Py_ssize_t n; 301 302 if (raise) { 303 struct _Py_stat_struct st; 304 305 if (urandom_cache.fd >= 0) { 306 /* Does the fd point to the same thing as before? (issue #21207) */ 307 if (_Py_fstat_noraise(urandom_cache.fd, &st) 308 || st.st_dev != urandom_cache.st_dev 309 || st.st_ino != urandom_cache.st_ino) { 310 /* Something changed: forget the cached fd (but don't close it, 311 since it probably points to something important for some 312 third-party code). */ 313 urandom_cache.fd = -1; 314 } 315 } 316 if (urandom_cache.fd >= 0) 317 fd = urandom_cache.fd; 318 else { 319 fd = _Py_open("/dev/urandom", O_RDONLY); 320 if (fd < 0) { 321 if (errno == ENOENT || errno == ENXIO || 322 errno == ENODEV || errno == EACCES) { 323 PyErr_SetString(PyExc_NotImplementedError, 324 "/dev/urandom (or equivalent) not found"); 325 } 326 /* otherwise, keep the OSError exception raised by _Py_open() */ 327 return -1; 328 } 329 if (urandom_cache.fd >= 0) { 330 /* urandom_fd was initialized by another thread while we were 331 not holding the GIL, keep it. */ 332 close(fd); 333 fd = urandom_cache.fd; 334 } 335 else { 336 if (_Py_fstat(fd, &st)) { 337 close(fd); 338 return -1; 339 } 340 else { 341 urandom_cache.fd = fd; 342 urandom_cache.st_dev = st.st_dev; 343 urandom_cache.st_ino = st.st_ino; 344 } 345 } 346 } 347 348 do { 349 n = _Py_read(fd, buffer, (size_t)size); 350 if (n == -1) 351 return -1; 352 if (n == 0) { 353 PyErr_Format(PyExc_RuntimeError, 354 "Failed to read %zi bytes from /dev/urandom", 355 size); 356 return -1; 357 } 358 359 buffer += n; 360 size -= n; 361 } while (0 < size); 362 } 363 else { 364 fd = _Py_open_noraise("/dev/urandom", O_RDONLY); 365 if (fd < 0) { 366 return -1; 367 } 368 369 while (0 < size) 370 { 371 do { 372 n = read(fd, buffer, (size_t)size); 373 } while (n < 0 && errno == EINTR); 374 375 if (n <= 0) { 376 /* stop on error or if read(size) returned 0 */ 377 close(fd); 378 return -1; 379 } 380 381 buffer += n; 382 size -= n; 383 } 384 close(fd); 385 } 386 return 0; 387 } 388 389 static void 390 dev_urandom_close(void) 391 { 392 if (urandom_cache.fd >= 0) { 393 close(urandom_cache.fd); 394 urandom_cache.fd = -1; 395 } 396 } 397 #endif /* !MS_WINDOWS */ 398 399 400 /* Fill buffer with pseudo-random bytes generated by a linear congruent 401 generator (LCG): 402 403 x(n+1) = (x(n) * 214013 + 2531011) % 2^32 404 405 Use bits 23..16 of x(n) to generate a byte. */ 406 static void 407 lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) 408 { 409 size_t index; 410 unsigned int x; 411 412 x = x0; 413 for (index=0; index < size; index++) { 414 x *= 214013; 415 x += 2531011; 416 /* modulo 2 ^ (8 * sizeof(int)) */ 417 buffer[index] = (x >> 16) & 0xff; 418 } 419 } 420 421 /* Read random bytes: 422 423 - Return 0 on success 424 - Raise an exception (if raise is non-zero) and return -1 on error 425 426 Used sources of entropy ordered by preference, preferred source first: 427 428 - CryptGenRandom() on Windows 429 - getrandom() function (ex: Linux and Solaris): call py_getrandom() 430 - getentropy() function (ex: OpenBSD): call py_getentropy() 431 - /dev/urandom device 432 433 Read from the /dev/urandom device if getrandom() or getentropy() function 434 is not available or does not work. 435 436 Prefer getrandom() over getentropy() because getrandom() supports blocking 437 and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at 438 startup to initialize its hash secret, but os.urandom() must block until the 439 system urandom is initialized (at least on Linux 3.17 and newer). 440 441 Prefer getrandom() and getentropy() over reading directly /dev/urandom 442 because these functions don't need file descriptors and so avoid ENFILE or 443 EMFILE errors (too many open files): see the issue #18756. 444 445 Only the getrandom() function supports non-blocking mode. 446 447 Only use RNG running in the kernel. They are more secure because it is 448 harder to get the internal state of a RNG running in the kernel land than a 449 RNG running in the user land. The kernel has a direct access to the hardware 450 and has access to hardware RNG, they are used as entropy sources. 451 452 Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed 453 its RNG on fork(), two child processes (with the same pid) generate the same 454 random numbers: see issue #18747. Kernel RNGs don't have this issue, 455 they have access to good quality entropy sources. 456 457 If raise is zero: 458 459 - Don't raise an exception on error 460 - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if 461 a function fails with EINTR: retry directly the interrupted function 462 - Don't release the GIL to call functions. 463 */ 464 static int 465 pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise) 466 { 467 #if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) 468 int res; 469 #endif 470 471 if (size < 0) { 472 if (raise) { 473 PyErr_Format(PyExc_ValueError, 474 "negative argument not allowed"); 475 } 476 return -1; 477 } 478 479 if (size == 0) { 480 return 0; 481 } 482 483 #ifdef MS_WINDOWS 484 return win32_urandom((unsigned char *)buffer, size, raise); 485 #else 486 487 #if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) 488 #ifdef PY_GETRANDOM 489 res = py_getrandom(buffer, size, blocking, raise); 490 #else 491 res = py_getentropy(buffer, size, raise); 492 #endif 493 if (res < 0) { 494 return -1; 495 } 496 if (res == 1) { 497 return 0; 498 } 499 /* getrandom() or getentropy() function is not available: failed with 500 ENOSYS or EPERM. Fall back on reading from /dev/urandom. */ 501 #endif 502 503 return dev_urandom(buffer, size, raise); 504 #endif 505 } 506 507 /* Fill buffer with size pseudo-random bytes from the operating system random 508 number generator (RNG). It is suitable for most cryptographic purposes 509 except long living private keys for asymmetric encryption. 510 511 On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode: 512 block until the system urandom entropy pool is initialized (128 bits are 513 collected by the kernel). 514 515 Return 0 on success. Raise an exception and return -1 on error. */ 516 int 517 _PyOS_URandom(void *buffer, Py_ssize_t size) 518 { 519 return pyurandom(buffer, size, 1, 1); 520 } 521 522 /* Fill buffer with size pseudo-random bytes from the operating system random 523 number generator (RNG). It is not suitable for cryptographic purpose. 524 525 On Linux 3.17 and newer (when getrandom() syscall is used), if the system 526 urandom is not initialized yet, the function returns "weak" entropy read 527 from /dev/urandom. 528 529 Return 0 on success. Raise an exception and return -1 on error. */ 530 int 531 _PyOS_URandomNonblock(void *buffer, Py_ssize_t size) 532 { 533 return pyurandom(buffer, size, 0, 1); 534 } 535 536 void 537 _PyRandom_Init(void) 538 { 539 char *env; 540 unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc; 541 Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); 542 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); 543 544 if (_Py_HashSecret_Initialized) 545 return; 546 _Py_HashSecret_Initialized = 1; 547 548 /* 549 Hash randomization is enabled. Generate a per-process secret, 550 using PYTHONHASHSEED if provided. 551 */ 552 553 env = Py_GETENV("PYTHONHASHSEED"); 554 if (env && *env != '\0' && strcmp(env, "random") != 0) { 555 char *endptr = env; 556 unsigned long seed; 557 seed = strtoul(env, &endptr, 10); 558 if (*endptr != '\0' 559 || seed > 4294967295UL 560 || (errno == ERANGE && seed == ULONG_MAX)) 561 { 562 Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer " 563 "in range [0; 4294967295]"); 564 } 565 if (seed == 0) { 566 /* disable the randomized hash */ 567 memset(secret, 0, secret_size); 568 } 569 else { 570 lcg_urandom(seed, secret, secret_size); 571 } 572 } 573 else { 574 int res; 575 576 /* _PyRandom_Init() is called very early in the Python initialization 577 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); 582 if (res < 0) { 583 Py_FatalError("failed to get random numbers to initialize Python"); 584 } 585 } 586 } 587 588 void 589 _PyRandom_Fini(void) 590 { 591 #ifdef MS_WINDOWS 592 if (hCryptProv) { 593 CryptReleaseContext(hCryptProv, 0); 594 hCryptProv = 0; 595 } 596 #else 597 dev_urandom_close(); 598 #endif 599 } 600