+* [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().
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(
#include <ntp_types.h>
+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);
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 \
--- /dev/null
+/*
+ * 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 <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdio.h>
+
+#include <l_stdlib.h>
+#include <ntp_random.h>
+
+#ifdef USE_OPENSSL_CRYPTO_RAND
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+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
+}
--- /dev/null
+# 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
+
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
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);
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;