libstdc++: Support getentropy and arc4random in std::random_device
This adds additional "getentropy" and "arc4random" tokens to std::random_device. The former is supported on Glibc and OpenBSD (and apparently wasm), and the latter is supported on various BSDs. libstdc++-v3/ChangeLog: * acinclude.m4 (GLIBCXX_CHECK_GETENTROPY, GLIBCXX_CHECK_ARC4RANDOM): Define. * configure.ac (GLIBCXX_CHECK_GETENTROPY, GLIBCXX_CHECK_ARC4RANDOM): Use them. * config.h.in: Regenerate. * configure: Regenerate. * src/c++11/random.cc (random_device): Add getentropy and arc4random as sources. * testsuite/26_numerics/random/random_device/cons/token.cc: Check new tokens. * testsuite/26_numerics/random/random_device/entropy.cc: Likewise.
This commit is contained in:
parent
8d2d0a6c43
commit
3439657b02
@ -4830,6 +4830,52 @@ AC_DEFUN([GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER], [
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Check whether getentropy is present in <unistd.h>.
|
||||
dnl
|
||||
AC_DEFUN([GLIBCXX_CHECK_GETENTROPY], [
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_MSG_CHECKING([for getentropy])
|
||||
AC_CACHE_VAL(glibcxx_cv_getentropy, [
|
||||
AC_TRY_COMPILE(
|
||||
[#include <unistd.h>],
|
||||
[unsigned i;
|
||||
::getentropy(&i, sizeof(i));],
|
||||
[glibcxx_cv_getentropy=yes], [glibcxx_cv_getentropy=no])
|
||||
])
|
||||
|
||||
if test $glibcxx_cv_getentropy = yes; then
|
||||
AC_DEFINE(HAVE_GETENTROPY, 1, [Define if getentropy is available in <unistd.h>.])
|
||||
fi
|
||||
AC_MSG_RESULT($glibcxx_cv_getentropy)
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Check whether arc4random is present in <stdlib.h>.
|
||||
dnl
|
||||
AC_DEFUN([GLIBCXX_CHECK_ARC4RANDOM], [
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_MSG_CHECKING([for arc4random])
|
||||
AC_CACHE_VAL(glibcxx_cv_arc4random, [
|
||||
AC_TRY_COMPILE(
|
||||
[#include <stdlib.h>],
|
||||
[unsigned i = ::arc4random();],
|
||||
[glibcxx_cv_arc4random=yes], [glibcxx_cv_arc4random=no])
|
||||
])
|
||||
|
||||
if test $glibcxx_cv_arc4random = yes; then
|
||||
AC_DEFINE(HAVE_ARC4RANDOM, 1, [Define if arc4random is available in <stdlib.h>.])
|
||||
fi
|
||||
AC_MSG_RESULT($glibcxx_cv_arc4random)
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
|
||||
|
||||
# Macros from the top-level gcc directory.
|
||||
m4_include([../config/gc++filt.m4])
|
||||
m4_include([../config/tls.m4])
|
||||
|
@ -9,6 +9,9 @@
|
||||
/* Define to 1 if you have the `aligned_alloc' function. */
|
||||
#undef HAVE_ALIGNED_ALLOC
|
||||
|
||||
/* Define if arc4random is available in <stdlib.h>. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
@ -132,6 +135,9 @@
|
||||
/* Define to 1 if you have the `frexpl' function. */
|
||||
#undef HAVE_FREXPL
|
||||
|
||||
/* Define if getentropy is available in <unistd.h>. */
|
||||
#undef HAVE_GETENTROPY
|
||||
|
||||
/* Define if _Unwind_GetIPInfo is available. */
|
||||
#undef HAVE_GETIPINFO
|
||||
|
||||
|
103
libstdc++-v3/configure
vendored
103
libstdc++-v3/configure
vendored
@ -75429,6 +75429,109 @@ $as_echo "#define _GLIBCXX_X86_RDSEED 1" >>confdefs.h
|
||||
$as_echo "$ac_cv_x86_rdseed" >&6; }
|
||||
|
||||
|
||||
# Check for other random number APIs
|
||||
|
||||
|
||||
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getentropy" >&5
|
||||
$as_echo_n "checking for getentropy... " >&6; }
|
||||
if ${glibcxx_cv_getentropy+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned i;
|
||||
::getentropy(&i, sizeof(i));
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
glibcxx_cv_getentropy=yes
|
||||
else
|
||||
glibcxx_cv_getentropy=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test $glibcxx_cv_getentropy = yes; then
|
||||
|
||||
$as_echo "#define HAVE_GETENTROPY 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_getentropy" >&5
|
||||
$as_echo "$glibcxx_cv_getentropy" >&6; }
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for arc4random" >&5
|
||||
$as_echo_n "checking for arc4random... " >&6; }
|
||||
if ${glibcxx_cv_arc4random+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <stdlib.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned i = ::arc4random();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
glibcxx_cv_arc4random=yes
|
||||
else
|
||||
glibcxx_cv_arc4random=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test $glibcxx_cv_arc4random = yes; then
|
||||
|
||||
$as_echo "#define HAVE_ARC4RANDOM 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_arc4random" >&5
|
||||
$as_echo "$glibcxx_cv_arc4random" >&6; }
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
# This depends on GLIBCXX_ENABLE_SYMVERS and GLIBCXX_IS_NATIVE.
|
||||
|
||||
# Do checks for resource limit functions.
|
||||
|
@ -468,6 +468,10 @@ GLIBCXX_CHECK_X86_RDRAND
|
||||
# Check if assembler supports rdseed opcode.
|
||||
GLIBCXX_CHECK_X86_RDSEED
|
||||
|
||||
# Check for other random number APIs
|
||||
GLIBCXX_CHECK_GETENTROPY
|
||||
GLIBCXX_CHECK_ARC4RANDOM
|
||||
|
||||
# This depends on GLIBCXX_ENABLE_SYMVERS and GLIBCXX_IS_NATIVE.
|
||||
GLIBCXX_CONFIGURE_TESTSUITE
|
||||
|
||||
|
@ -68,7 +68,12 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined _GLIBCXX_USE_CRT_RAND_S || defined _GLIBCXX_USE_DEV_RANDOM
|
||||
#ifdef _GLIBCXX_HAVE_GETENTROPY
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined _GLIBCXX_USE_CRT_RAND_S || defined _GLIBCXX_USE_DEV_RANDOM \
|
||||
|| _GLIBCXX_HAVE_GETENTROPY
|
||||
// The OS provides a source of randomness we can use.
|
||||
# pragma GCC poison _M_mt
|
||||
#elif defined USE_RDRAND || defined USE_RDSEED || defined USE_DARN
|
||||
@ -166,6 +171,25 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_GETENTROPY
|
||||
unsigned int
|
||||
__libc_getentropy(void*)
|
||||
{
|
||||
unsigned int val;
|
||||
if (::getentropy(&val, sizeof(val)) != 0)
|
||||
std::__throw_runtime_error(__N("random_device: getentropy failed"));
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_ARC4RANDOM
|
||||
unsigned int
|
||||
__libc_arc4random(void*)
|
||||
{
|
||||
return ::arc4random();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LCG
|
||||
// TODO: use this to seed std::mt19937 engine too.
|
||||
unsigned
|
||||
@ -214,7 +238,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
#endif
|
||||
|
||||
enum Which : unsigned {
|
||||
device_file = 1, prng = 2, rand_s = 4,
|
||||
device_file = 1, prng = 2, rand_s = 4, getentropy = 8, arc4random = 16,
|
||||
rdseed = 64, rdrand = 128, darn = 256,
|
||||
any = 0xffff
|
||||
};
|
||||
@ -256,6 +280,16 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
return device_file;
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_ARC4RANDOM
|
||||
if (func == __libc_arc4random)
|
||||
return arc4random;
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_GETENTROPY
|
||||
if (func == __libc_getentropy)
|
||||
return getentropy;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LCG
|
||||
if (func == &__lcg)
|
||||
return prng;
|
||||
@ -311,6 +345,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
else if (token == "rand_s")
|
||||
which = rand_s;
|
||||
#endif // _GLIBCXX_USE_CRT_RAND_S
|
||||
#ifdef _GLIBCXX_HAVE_GETENTROPY
|
||||
else if (token == "getentropy")
|
||||
which = getentropy;
|
||||
#endif // _GLIBCXX_HAVE_GETENTROPY
|
||||
#ifdef _GLIBCXX_HAVE_ARC4RANDOM
|
||||
else if (token == "arc4random")
|
||||
which = arc4random;
|
||||
#endif // _GLIBCXX_HAVE_ARC4RANDOM
|
||||
#ifdef _GLIBCXX_USE_DEV_RANDOM
|
||||
else if (token == "/dev/urandom" || token == "/dev/random")
|
||||
{
|
||||
@ -395,6 +437,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
}
|
||||
#endif // USE_DARN
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_ARC4RANDOM
|
||||
if (which & arc4random)
|
||||
{
|
||||
_M_func = &__libc_arc4random;
|
||||
return;
|
||||
}
|
||||
#endif // _GLIBCXX_HAVE_ARC4RANDOM
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_GETENTROPY
|
||||
if (which & getentropy)
|
||||
{
|
||||
unsigned int i;
|
||||
if (::getentropy(&i, sizeof(i)) == 0) // On linux the syscall can fail.
|
||||
{
|
||||
_M_func = &__libc_getentropy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // _GLIBCXX_HAVE_GETENTROPY
|
||||
|
||||
#ifdef _GLIBCXX_USE_DEV_RANDOM
|
||||
if (which & device_file)
|
||||
{
|
||||
@ -548,6 +610,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
case rdseed:
|
||||
case darn:
|
||||
return (double) max;
|
||||
case arc4random:
|
||||
case getentropy:
|
||||
return (double) max;
|
||||
case rand_s:
|
||||
case prng:
|
||||
return 0.0;
|
||||
|
@ -53,6 +53,7 @@ test03()
|
||||
const std::string tokens[] = {
|
||||
"rdseed", "rdrand", "darn",
|
||||
"rand_s", "/dev/urandom", "/dev/random",
|
||||
"getentropy", "arc4random",
|
||||
"mt19937", "prng"
|
||||
};
|
||||
int count = 0;
|
||||
|
@ -28,6 +28,13 @@ test01()
|
||||
const double entropy = std::random_device(token).entropy();
|
||||
VERIFY( entropy == max );
|
||||
}
|
||||
|
||||
for (auto token : { "getentropy", "arc4random" })
|
||||
if (__gnu_test::random_device_available(token))
|
||||
{
|
||||
const double entropy = std::random_device(token).entropy();
|
||||
VERIFY( entropy == max );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user