]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added support for getentropy() and reworked getrandom support
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 30 Oct 2014 10:15:20 +0000 (11:15 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 30 Oct 2014 10:17:07 +0000 (11:17 +0100)
NEWS
configure.ac
lib/nettle/rnd-common.c

diff --git a/NEWS b/NEWS
index 25f2552429b63ccd9fe7900483651c1c4b8e9863..1b4a41fd847aa879c5dcfcad2fca9d45706ab13d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,9 +5,9 @@ See the end for copying conditions.
 
 * 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.
 
index 9c32d23fb86fad8b4a0bdc8c8c18e59e2398330a..badd4d02db4225c2944b37b762130261bfad3933 100644 (file)
@@ -146,15 +146,25 @@ AM_CONDITIONAL(HAVE_GCC, test "$GCC" = "yes")
 
 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
@@ -861,7 +871,7 @@ AC_MSG_NOTICE([External hardware support:
   /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
 ])
index dbcea19776bf90b995384b32a4a0e1d1f3cba4c7..88aa7677d15d545e4c58a4d21f17dd1b13c8e508 100644 (file)
 #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 */
@@ -132,9 +134,14 @@ void _rnd_system_entropy_deinit(void)
 
 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
@@ -142,7 +149,33 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
                                         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;
 
@@ -167,12 +200,10 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
 
                done += res;
        }
-#endif
 
        return 0;
 }
 
-#ifndef HAVE_LINUX_GETRANDOM
 static
 int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
 {
@@ -197,15 +228,9 @@ 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);
@@ -232,18 +257,16 @@ fallback:
        _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 */