Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
instead of reading /dev/urandom, to get pseudo-random bytes.
This commit is contained in:
parent
3c6fe4da88
commit
4d6a3d6c01
|
@ -27,6 +27,7 @@ import codecs
|
|||
import decimal
|
||||
import fractions
|
||||
import pickle
|
||||
import sysconfig
|
||||
try:
|
||||
import threading
|
||||
except ImportError:
|
||||
|
@ -1103,6 +1104,12 @@ class URandomTests(unittest.TestCase):
|
|||
data2 = self.get_urandom_subprocess(16)
|
||||
self.assertNotEqual(data1, data2)
|
||||
|
||||
|
||||
HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
|
||||
|
||||
@unittest.skipIf(HAVE_GETENTROPY,
|
||||
"getentropy() does not use a file descriptor")
|
||||
class URandomFDTests(unittest.TestCase):
|
||||
@unittest.skipUnless(resource, "test requires the resource module")
|
||||
def test_urandom_failure(self):
|
||||
# Check urandom() failing when it is not able to open /dev/random.
|
||||
|
|
|
@ -196,6 +196,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
|
||||
instead of reading /dev/urandom, to get pseudo-random bytes.
|
||||
|
||||
- Issue #19104: pprint now produces evaluable output for wrapped strings.
|
||||
|
||||
- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter.
|
||||
|
|
|
@ -36,7 +36,7 @@ error:
|
|||
}
|
||||
|
||||
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
|
||||
API. Return 0 on success, or -1 on error. */
|
||||
API. Return 0 on success, or raise an exception and return -1 on error. */
|
||||
static int
|
||||
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
||||
{
|
||||
|
@ -66,10 +66,35 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
#elif HAVE_GETENTROPY
|
||||
/* Fill buffer with size pseudo-random bytes generated by getentropy().
|
||||
Return 0 on success, or raise an exception and return -1 on error.
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
If fatal is nonzero, call Py_FatalError() instead of raising an exception
|
||||
on error. */
|
||||
static int
|
||||
py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
|
||||
{
|
||||
while (size > 0) {
|
||||
Py_ssize_t len = Py_MIN(size, 256);
|
||||
int res = getentropy(buffer, len);
|
||||
if (res < 0) {
|
||||
if (fatal) {
|
||||
Py_FatalError("getentropy() failed");
|
||||
}
|
||||
else {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buffer += len;
|
||||
size -= len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static struct {
|
||||
int fd;
|
||||
dev_t st_dev;
|
||||
|
@ -201,7 +226,7 @@ dev_urandom_close(void)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
#endif /* HAVE_GETENTROPY */
|
||||
|
||||
/* Fill buffer with pseudo-random bytes generated by a linear congruent
|
||||
generator (LCG):
|
||||
|
@ -242,6 +267,8 @@ _PyOS_URandom(void *buffer, Py_ssize_t size)
|
|||
|
||||
#ifdef MS_WINDOWS
|
||||
return win32_urandom((unsigned char *)buffer, size, 1);
|
||||
#elif HAVE_GETENTROPY
|
||||
return py_getentropy(buffer, size, 0);
|
||||
#else
|
||||
return dev_urandom_python((char*)buffer, size);
|
||||
#endif
|
||||
|
@ -287,6 +314,8 @@ _PyRandom_Init(void)
|
|||
else {
|
||||
#ifdef MS_WINDOWS
|
||||
(void)win32_urandom(secret, secret_size, 0);
|
||||
#elif HAVE_GETENTROPY
|
||||
(void)py_getentropy(secret, secret_size, 1);
|
||||
#else
|
||||
dev_urandom_noraise(secret, secret_size);
|
||||
#endif
|
||||
|
@ -301,6 +330,8 @@ _PyRandom_Fini(void)
|
|||
CryptReleaseContext(hCryptProv, 0);
|
||||
hCryptProv = 0;
|
||||
}
|
||||
#elif HAVE_GETENTROPY
|
||||
/* nothing to clean */
|
||||
#else
|
||||
dev_urandom_close();
|
||||
#endif
|
||||
|
|
|
@ -10697,7 +10697,7 @@ fi
|
|||
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
||||
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
||||
futimens futimes gai_strerror \
|
||||
futimens futimes gai_strerror getentropy \
|
||||
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||
if_nameindex \
|
||||
|
|
|
@ -3004,7 +3004,7 @@ fi
|
|||
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
||||
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
||||
futimens futimes gai_strerror \
|
||||
futimens futimes gai_strerror getentropy \
|
||||
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||
if_nameindex \
|
||||
|
|
|
@ -332,6 +332,9 @@
|
|||
/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
|
||||
#undef HAVE_GETC_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the `getentropy' function. */
|
||||
#undef HAVE_GETENTROPY
|
||||
|
||||
/* Define to 1 if you have the `getgrouplist' function. */
|
||||
#undef HAVE_GETGROUPLIST
|
||||
|
||||
|
|
Loading…
Reference in New Issue