aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-11-04 15:51:37 +0000
committerJonathan Wakely <jwakely@redhat.com>2021-11-09 14:40:33 +0000
commit3439657b02869299685d259c3a77aa38714565b7 (patch)
tree1dab70303e55e7101cdb6bde499de3239cda0cfc /libstdc++-v3
parent8d2d0a6c4391e462555db6d33b2cc00f3da0932f (diff)
downloadgcc-3439657b02869299685d259c3a77aa38714565b7.zip
gcc-3439657b02869299685d259c3a77aa38714565b7.tar.gz
gcc-3439657b02869299685d259c3a77aa38714565b7.tar.bz2
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.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/acinclude.m446
-rw-r--r--libstdc++-v3/config.h.in6
-rwxr-xr-xlibstdc++-v3/configure103
-rw-r--r--libstdc++-v3/configure.ac4
-rw-r--r--libstdc++-v3/src/c++11/random.cc69
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc7
7 files changed, 234 insertions, 2 deletions
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 90ecc4a..497af57 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -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])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 228a758..420021f 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -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
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c1aea82..2137103 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -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.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 2d68b36..5b3c92f 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -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
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 4b88818..4a553e0 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -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;
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
index 07713e5..e56afbc 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
@@ -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;
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
index 6f3ebb1..63b7043 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
@@ -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