From: Nikos Mavrogiannopoulos Date: Thu, 30 Oct 2014 10:15:20 +0000 (+0100) Subject: Added support for getentropy() and reworked getrandom support X-Git-Tag: gnutls_3_4_0~722 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2b64138a70a031b8b6a122ea48ed460da94e45bb;p=thirdparty%2Fgnutls.git Added support for getentropy() and reworked getrandom support --- diff --git a/NEWS b/NEWS index 25f2552429..1b4a41fd84 100644 --- 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. diff --git a/configure.ac b/configure.ac index 9c32d23fb8..badd4d02db 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ],[ - 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 ],[ + 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 ]) diff --git a/lib/nettle/rnd-common.c b/lib/nettle/rnd-common.c index dbcea19776..88aa7677d1 100644 --- a/lib/nettle/rnd-common.c +++ b/lib/nettle/rnd-common.c @@ -37,8 +37,10 @@ #include #include -#ifdef HAVE_LINUX_GETRANDOM +#if defined(HAVE_LINUX_GETRANDOM) # include +#elif defined(HAVE_GETENTROPY) +# include #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 */