]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Sec 2666] Use cryptographic random numbers for md5 key generation
authorHarlan Stenn <stenn@ntp.org>
Sun, 14 Dec 2014 16:12:13 +0000 (16:12 +0000)
committerHarlan Stenn <stenn@ntp.org>
Sun, 14 Dec 2014 16:12:13 +0000 (16:12 +0000)
bk: 548db6ddlELn4rnqUZ4kKGOjvtXwbQ

ChangeLog
configure.ac
include/ntp_random.h
libntp/Makefile.am
libntp/ntp_crypto_rnd.c [new file with mode: 0644]
sntp/m4/ntp_crypto_rand.m4 [new file with mode: 0644]
util/ntp-keygen.c

index d9473edea00a644f17881b6eccae45b8aba702f0..f3765a5ffd0d51db0e57224b36ed3393c5fab0fa 100644 (file)
--- 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().
index 82c6795d1993f2a61576d9e3afcfaeccea2f87d4..a7d344a2156872cb0a1dd73e0998337886919ae5 100644 (file)
@@ -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(
index 3f898312d77e820e7f90514347194d737f23de3f..fa77f6553ec657c5dad3ee8dc5f9b42baf26133f 100644 (file)
@@ -1,6 +1,9 @@
 
 #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);
index 515fa9a72f4598e909ae2a6c124f0535b8139679..c12658f5a18e809aa3441d32c7e286e14c18bc1e 100644 (file)
@@ -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 (file)
index 0000000..62a808d
--- /dev/null
@@ -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 <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
+}
diff --git a/sntp/m4/ntp_crypto_rand.m4 b/sntp/m4/ntp_crypto_rand.m4
new file mode 100644 (file)
index 0000000..25383a7
--- /dev/null
@@ -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
+
index d55a3572cf2ab0b956964876a2a474f05ebe0fd2..e1b450e3cdbe59cff8b9e10cd8b150ab5f178b5d 100644 (file)
@@ -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;