* Version 3.4.0 (unreleased)
-** libgnutls: Use getrandom() when available. That avoids the complexity
-of file descriptor handling and the issues with applications closing
-all open file descriptors.
+** libgnutls: Use getrandom() or getentropy() when available. That
+avoids the complexity of file descriptor handling and the issues with
+applications closing all open file descriptors.
** libgnutls: Use pthread_atfork() to detect fork.
dnl check for getrandom()
enable_getrandom=no
+AC_MSG_CHECKING([for getrandom])
AC_LINK_IFELSE([AC_LANG_PROGRAM([
#include <linux/random.h>],[
- getrandom(NULL, 0, 0);
+ getrandom(0, 0, 0);
])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_LINUX_GETRANDOM], 1, [Enable the Linux getrandom function])
- enable_getrandom=yes],
- [AC_MSG_RESULT(no)
- enable_getrandom=no])
+ enable_getrandom=getrandom],
+ [AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING([for getentropy])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([
+ #include <unistd.h>],[
+ getentropy(0, 0);
+ ])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE([HAVE_GETENTROPY], 1, [Enable the OpenBSD getentropy function])
+ enable_getrandom=getentropy],
+ [AC_MSG_RESULT(no)])
dnl Try the hooks.m4
LIBGNUTLS_HOOKS
/dev/crypto: $enable_cryptodev
Hardware accel: $hw_accel
Padlock accel: $use_padlock
- Linux getrandom: $enable_getrandom
+ getrandom variant: $enable_getrandom
PKCS#11 support: $with_p11_kit
TPM support: $with_tpm
])
#include <rnd-common.h>
#include <hash-pjw-bare.h>
-#ifdef HAVE_LINUX_GETRANDOM
+#if defined(HAVE_LINUX_GETRANDOM)
# include <linux/random.h>
+#elif defined(HAVE_GETENTROPY)
+# include <unistd.h>
#endif
/* gnulib wants to claim strerror even if it cannot provide it. WTF */
int _gnutls_urandom_fd = -1;
-static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
+
+get_entropy_func _rnd_get_system_entropy = NULL;
+
+#if defined(HAVE_LINUX_GETRANDOM) || defined(HAVE_GETENTROPY)
+
+static int _rnd_get_system_entropy_simple(void* _rnd, size_t size)
{
-#ifdef HAVE_LINUX_GETRANDOM
+#if defined(HAVE_LINUX_GETRANDOM)
if (getrandom(_rnd, size, 0) < 0) {
gnutls_assert();
_gnutls_debug_log
strerror(errno));
return GNUTLS_E_RANDOM_DEVICE_ERROR;
}
-#else
+#elif defined(HAVE_GETENTROPY)
+ if (getentropy(_rnd, size) < 0) {
+ gnutls_assert();
+ _gnutls_debug_log
+ ("Failed to use getentropy: %s\n",
+ strerror(errno));
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+#endif
+ return 0;
+}
+
+int _rnd_system_entropy_init(void)
+{
+ _rnd_get_system_entropy = _rnd_get_system_entropy_simple;
+ return 0;
+}
+
+void _rnd_system_entropy_deinit(void)
+{
+ return;
+}
+
+#else /* /dev/urandom - egd approach */
+
+static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
+{
uint8_t* rnd = _rnd;
uint32_t done;
done += res;
}
-#endif
return 0;
}
-#ifndef HAVE_LINUX_GETRANDOM
static
int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
{
return 0;
}
-#endif
-
-get_entropy_func _rnd_get_system_entropy = NULL;
int _rnd_system_entropy_init(void)
{
-#ifdef HAVE_LINUX_GETRANDOM
- return 0;
-#else
int old;
_gnutls_urandom_fd = open("/dev/urandom", O_RDONLY);
_rnd_get_system_entropy = _rnd_get_system_entropy_egd;
return 0;
-#endif
}
void _rnd_system_entropy_deinit(void)
{
-#ifndef HAVE_LINUX_GETRANDOM
if (_gnutls_urandom_fd >= 0) {
close(_gnutls_urandom_fd);
_gnutls_urandom_fd = -1;
}
-#endif
}
+#endif /* GETRANDOM || GETENTROPY */
#endif /* _WIN32 */