From: Harlan Stenn Date: Sun, 14 Dec 2014 16:12:13 +0000 (+0000) Subject: [Sec 2666] Use cryptographic random numbers for md5 key generation X-Git-Tag: NTP_4_2_8~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85b5573fcb2bf2a9f10ea68f2d552d82914b38da;p=thirdparty%2Fntp.git [Sec 2666] Use cryptographic random numbers for md5 key generation bk: 548db6ddlELn4rnqUZ4kKGOjvtXwbQ --- diff --git a/ChangeLog b/ChangeLog index d9473edea..f3765a5ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* [Sec 2666] Use cryptographic random numbers for md5 key generation. * [Sec 2667] buffer overflow in crypto_recv(). * [Sec 2668] buffer overflow in ctl_putdata(). * [Sec 2669] buffer overflow in configure(). diff --git a/configure.ac b/configure.ac index 82c6795d1..a7d344a21 100644 --- a/configure.ac +++ b/configure.ac @@ -3021,6 +3021,8 @@ AC_MSG_RESULT([$ans]) NTP_OPENSSL +NTP_CRYPTO_RAND + # if we are using OpenSSL (--with-crypto), by default Autokey is enabled AC_MSG_CHECKING([if we want to include NTP Autokey protocol support]) AC_ARG_ENABLE( diff --git a/include/ntp_random.h b/include/ntp_random.h index 3f898312d..fa77f6553 100644 --- a/include/ntp_random.h +++ b/include/ntp_random.h @@ -1,6 +1,9 @@ #include +void ntp_crypto_srandom(void); +int ntp_crypto_random_buf(void *buf, size_t nbytes); + long ntp_random (void); void ntp_srandom (unsigned long); void ntp_srandomdev (void); diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 515fa9a72..c12658f5a 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -78,16 +78,17 @@ libntp_a_SRCS = \ msyslog.c \ netof.c \ ntp_calendar.c \ + ntp_crypto_rnd.c \ ntp_intres.c \ ntp_libopts.c \ ntp_lineedit.c \ + ntp_random.c \ ntp_rfc2553.c \ ntp_worker.c \ numtoa.c \ numtohost.c \ octtoint.c \ prettydate.c \ - ntp_random.c \ recvbuff.c \ refnumtoa.c \ snprintf.c \ diff --git a/libntp/ntp_crypto_rnd.c b/libntp/ntp_crypto_rnd.c new file mode 100644 index 000000000..62a808db3 --- /dev/null +++ b/libntp/ntp_crypto_rnd.c @@ -0,0 +1,96 @@ +/* + * Crypto-quality random number functions + * + * Author: Harlan Stenn, 2014 + * + * This file is Copyright (c) 2014 by Network Time Foundation. + * BSD terms apply: see the file COPYRIGHT in the distribution root for details. + */ + +#include "config.h" +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include + +#include +#include + +#ifdef USE_OPENSSL_CRYPTO_RAND +#include +#include + +int crypto_rand_init = 0; +#endif + +/* + * As of late 2014, here's how we plan to provide cryptographic-quality + * random numbers: + * + * - If we are building with OpenSSL, use RAND_poll() and RAND_bytes(). + * - Otherwise, use arc4random(). + * + * Use of arc4random() can be forced using configure --disable-openssl-random + * + * We can count on arc4random existing, thru the OS or thru libevent. + * The quality of arc4random depends on the implementor. + * + * RAND_poll() doesn't show up until XXX. If it's not present, we + * need to either provide our own or use arc4random(). + */ + +/* + * ntp_crypto_srandom: + * + * Initialize the random number generator, if needed by the underlying + * crypto random number generation mechanism. + */ + +void +ntp_crypto_srandom( + void + ) +{ +#ifdef USE_OPENSSL_CRYPTO_RAND + if (!crypto_rand_init) { + RAND_poll(); + crypto_rand_init = 1; + } +#else + /* No initialization needed for arc4random() */ +#endif +} + + +/* + * ntp_crypto_random_buf: + * + * Returns 0 on success, -1 on error. + */ +int +ntp_crypto_random_buf( + void *buf, + size_t nbytes + ) +{ +#ifdef USE_OPENSSL_CRYPTO_RAND + int rc; + + rc = RAND_bytes(buf, nbytes); + if (1 != rc) { + unsigned long err; + char *err_str; + + err = ERR_get_error(); + err_str = ERR_error_string(err, NULL); + /* XXX: Log the error */ + + return -1; + } + return 0; +#else + arc4random_buf(buf, nbytes); + return 0; +#endif +} diff --git a/sntp/m4/ntp_crypto_rand.m4 b/sntp/m4/ntp_crypto_rand.m4 new file mode 100644 index 000000000..25383a726 --- /dev/null +++ b/sntp/m4/ntp_crypto_rand.m4 @@ -0,0 +1,53 @@ +# SYNOPSIS -*- Autoconf -*- +# +# NTP_CRYPTO_RAND +# +# DESCRIPTION +# +# AUTHOR +# +# Harlan Stenn +# +# LICENSE +# +# This file is Copyright (c) 2014 Network Time Foundation +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice, +# author attribution and this notice are preserved. This file is offered +# as-is, without any warranty. + +AC_DEFUN([NTP_CRYPTO_RAND], [ + +dnl check for --disable-openssl-random +dnl if that's not specified: +dnl - Look for RAND_poll and RAND_bytes +dnl - if they exist, define USE_OPENSSL_CRYPTO_RAND + +AC_MSG_CHECKING([if we want to use OpenSSL's crypto random (if available)]) +AC_ARG_ENABLE( + [openssl-random], + [AS_HELP_STRING( + [--enable-openssl-random], + [Use OpenSSL's crypto random number functions, if available (default is yes)] + )], + [ntp_use_openssl_random=$enableval], + [ntp_use_openssl_random=yes] +) +AC_MSG_RESULT([$ntp_use_openssl_random]) + +# The following might need extra libraries +NTPO_SAVED_LIBS="$LIBS" +LIBS="$NTPO_SAVED_LIBS $LDADD_NTP" +AC_MSG_NOTICE([LIBS is <$LIBS>]) +AC_CHECK_FUNCS([RAND_bytes RAND_poll]) +LIBS="$NTPO_SAVED_LIBS" +case "$ntp_use_openssl_random$ac_cv_func_RAND_bytes$ac_cv_func_RAND_poll" in + yesyesyes) + AC_DEFINE([USE_OPENSSL_CRYPTO_RAND], [1], [Use OpenSSL's crypto random functions]) + ;; + *) ntp_use_openssl_random=no ;; +esac + +]) dnl NTP_CRYPTO_RAND + diff --git a/util/ntp-keygen.c b/util/ntp-keygen.c index d55a3572c..e1b450e3c 100644 --- a/util/ntp-keygen.c +++ b/util/ntp-keygen.c @@ -336,6 +336,8 @@ main( ssl_check_version(); #endif /* OPENSSL */ + ntp_crypto_srandom(); + /* * Process options, initialize host name and timestamp. * gethostname() won't null-terminate if hostname is exactly the @@ -348,7 +350,6 @@ main( passwd1 = hostbuf; passwd2 = NULL; GETTIMEOFDAY(&tv, NULL); - ntp_srandom((u_long)(tv.tv_sec + tv.tv_usec)); epoch = tv.tv_sec; fstamp = (u_int)(epoch + JAN_1970); @@ -828,7 +829,14 @@ gen_md5( int temp; while (1) { - temp = ntp_random() & 0xff; + int rc; + + rc = ntp_crypto_random_buf(&temp, 1); + if (-1 == rc) { + fprintf(stderr, "ntp_crypto_random_buf() failed.\n"); + exit (-1); + } + temp &= 0xff; if (temp == '#') continue;