ยปCore Development>Code coverage>Python/random.c

Python code coverage for Python/random.c

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