12763cd
From 4c7b644910e21e690e5f51d5596a9fe46d9c7b7a Mon Sep 17 00:00:00 2001
595af1f
From: Evan Hunt <each@isc.org>
595af1f
Date: Thu, 28 Sep 2017 10:09:22 -0700
e0ab89b
Subject: [PATCH] completed and corrected the crypto-random change
595af1f
595af1f
4724.	[func]		By default, BIND now uses the random number
595af1f
			functions provided by the crypto library (i.e.,
595af1f
			OpenSSL or a PKCS#11 provider) as a source of
595af1f
			randomness rather than /dev/random.  This is
595af1f
			suitable for virtual machine environments
595af1f
			which have limited entropy pools and lack
595af1f
			hardware random number generators.
595af1f
595af1f
			This can be overridden by specifying another
595af1f
			entropy source via the "random-device" option
595af1f
			in named.conf, or via the -r command line option;
595af1f
			however, for functions requiring full cryptographic
595af1f
			strength, such as DNSSEC key generation, this
595af1f
			cannot be overridden. In particular, the -r
595af1f
			command line option no longer has any effect on
595af1f
			dnssec-keygen.
595af1f
595af1f
			This can be disabled by building with
595af1f
			"configure --disable-crypto-rand".
595af1f
			[RT #31459] [RT #46047]
595af1f
---
1e41691
 bin/confgen/keygen.c                     | 12 +++---
1e41691
 bin/dnssec/dnssec-keygen.docbook         | 24 +++++++----
1e41691
 bin/dnssec/dnssectool.c                  | 12 +++---
595af1f
 bin/named/client.c                       |  3 +-
1e41691
 bin/named/config.c                       |  4 +-
1e41691
 bin/named/controlconf.c                  | 19 +++++---
1e41691
 bin/named/include/named/server.h         |  2 +
595af1f
 bin/named/interfacemgr.c                 |  1 +
595af1f
 bin/named/query.c                        |  1 +
564c143
 bin/named/server.c                       | 52 ++++++++++++++--------
1e41691
 bin/nsupdate/nsupdate.c                  |  4 +-
1e41691
 bin/tests/system/pipelined/pipequeries.c |  4 +-
1e41691
 bin/tests/system/tkey/keycreate.c        |  4 +-
564c143
 bin/tests/system/tkey/keydelete.c        |  5 +--
1e41691
 doc/arm/Bv9ARM-book.xml                  | 55 +++++++++++++++++-------
12763cd
 doc/arm/notes-rh-changes.xml             | 43 ++++++++++++++++++
12763cd
 doc/arm/notes.xml                        |  1 +
1e41691
 lib/dns/dst_api.c                        |  4 +-
1e41691
 lib/dns/include/dst/dst.h                | 14 +++++-
595af1f
 lib/dns/openssl_link.c                   |  3 +-
1e41691
 lib/isc/include/isc/entropy.h            | 50 +++++++++++++++------
1e41691
 lib/isc/include/isc/random.h             | 28 +++++++-----
595af1f
 lib/isccfg/namedconf.c                   |  2 +-
12763cd
 23 files changed, 241 insertions(+), 106 deletions(-)
12763cd
 create mode 100644 doc/arm/notes-rh-changes.xml
595af1f
595af1f
diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c
ad7b3b8
index 295e16f..0f79aa8 100644
595af1f
--- a/bin/confgen/keygen.c
595af1f
+++ b/bin/confgen/keygen.c
595af1f
@@ -161,17 +161,15 @@ generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg,
595af1f
 
595af1f
 	DO("create entropy context", isc_entropy_create(mctx, &ectx));
595af1f
 
595af1f
-	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
595af1f
-		randomfile = NULL;
595af1f
-		open_keyboard = ISC_ENTROPY_KEYBOARDYES;
595af1f
-	}
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
595af1f
+	if (randomfile == NULL) {
ad7b3b8
 		isc_entropy_usehook(ectx, true);
595af1f
 	}
595af1f
 #endif
595af1f
+	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
595af1f
+		randomfile = NULL;
595af1f
+		open_keyboard = ISC_ENTROPY_KEYBOARDYES;
595af1f
+	}
595af1f
 	DO("start entropy source", isc_entropy_usebestsource(ectx,
595af1f
 							     &entropy_source,
595af1f
 							     randomfile,
595af1f
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook
564c143
index 0ae6b41..4562430 100644
595af1f
--- a/bin/dnssec/dnssec-keygen.docbook
595af1f
+++ b/bin/dnssec/dnssec-keygen.docbook
564c143
@@ -348,15 +348,23 @@
595af1f
 	<term>-r <replaceable class="parameter">randomdev</replaceable></term>
595af1f
 	<listitem>
595af1f
 	  <para>
595af1f
-	    Specifies the source of randomness.  If the operating
595af1f
-	    system does not provide a <filename>/dev/random</filename>
595af1f
-	    or equivalent device, the default source of randomness
595af1f
-	    is keyboard input.  <filename>randomdev</filename>
595af1f
-	    specifies
595af1f
+	    Specifies a source of randomness.  Normally, when generating
595af1f
+	    DNSSEC keys, this option has no effect; the random number
595af1f
+	    generation function provided by the cryptographic library will
595af1f
+	    be used.
595af1f
+	  </para>
595af1f
+	  <para>
595af1f
+	    If that behavior is disabled at compile time, however,
595af1f
+	    the specified file will be used as entropy source
595af1f
+	    for key generation.  <filename>randomdev</filename> is
595af1f
 	    the name of a character device or file containing random
595af1f
-	    data to be used instead of the default.  The special value
595af1f
-	    <filename>keyboard</filename> indicates that keyboard
595af1f
-	    input should be used.
595af1f
+	    data to be used.  The special value <filename>keyboard</filename>
595af1f
+	    indicates that keyboard input should be used.
595af1f
+	  </para>
595af1f
+	  <para>
595af1f
+	    The default is <filename>/dev/random</filename> if the
595af1f
+	    operating system provides it or an equivalent device;
595af1f
+	    if not, the default source of randomness is keyboard input.
595af1f
 	  </para>
595af1f
 	</listitem>
595af1f
       </varlistentry>
595af1f
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c
ad7b3b8
index 31a99e7..38c83ed 100644
595af1f
--- a/bin/dnssec/dnssectool.c
595af1f
+++ b/bin/dnssec/dnssectool.c
ad7b3b8
@@ -241,18 +241,16 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
595af1f
 		ISC_LIST_INIT(sources);
595af1f
 	}
595af1f
 
595af1f
+#ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
+	if (randomfile == NULL) {
ad7b3b8
+		isc_entropy_usehook(*ectx, true);
595af1f
+	}
595af1f
+#endif
595af1f
 	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
595af1f
 		usekeyboard = ISC_ENTROPY_KEYBOARDYES;
595af1f
 		randomfile = NULL;
595af1f
 	}
595af1f
 
595af1f
-#ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
ad7b3b8
-		isc_entropy_usehook(*ectx, true);
595af1f
-	}
595af1f
-#endif
595af1f
 	result = isc_entropy_usebestsource(*ectx, &source, randomfile,
595af1f
 					   usekeyboard);
595af1f
 
595af1f
diff --git a/bin/named/client.c b/bin/named/client.c
12763cd
index 2169954..c6c59f7 100644
595af1f
--- a/bin/named/client.c
595af1f
+++ b/bin/named/client.c
12763cd
@@ -1754,7 +1754,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
595af1f
 
595af1f
 		isc_buffer_init(&buf, cookie, sizeof(cookie));
595af1f
 		isc_stdtime_get(&now;;
595af1f
-		isc_random_get(&nonce);
595af1f
+		nonce = ((isc_rng_random(ns_g_server->rngctx) << 16) |
595af1f
+			 isc_rng_random(ns_g_server->rngctx));
595af1f
 
595af1f
 		compute_cookie(client, now, nonce, ns_g_server->secret, &buf;;
595af1f
 
595af1f
diff --git a/bin/named/config.c b/bin/named/config.c
12763cd
index de64ca5..833c1dc 100644
595af1f
--- a/bin/named/config.c
595af1f
+++ b/bin/named/config.c
12763cd
@@ -98,7 +98,9 @@ options {\n\
595af1f
 #	pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
595af1f
 	port 53;\n\
595af1f
 	prefetch 2 9;\n"
595af1f
-#ifdef PATH_RANDOMDEV
595af1f
+#if defined(ISC_PLATFORM_CRYPTORANDOM)
595af1f
+"	random-device none;\n"
595af1f
+#elif defined(PATH_RANDOMDEV)
595af1f
 "	random-device \"" PATH_RANDOMDEV "\";\n"
595af1f
 #endif
595af1f
 "	recursing-file \"named.recursing\";\n\
595af1f
diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c
ad7b3b8
index d955c2f..40621f2 100644
595af1f
--- a/bin/named/controlconf.c
595af1f
+++ b/bin/named/controlconf.c
ad7b3b8
@@ -325,9 +325,10 @@ log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
595af1f
 
595af1f
 static void
595af1f
 control_recvmessage(isc_task_t *task, isc_event_t *event) {
595af1f
-	controlconnection_t *conn;
595af1f
-	controllistener_t *listener;
595af1f
-	controlkey_t *key;
595af1f
+	controlconnection_t *conn = NULL;
595af1f
+	controllistener_t *listener = NULL;
595af1f
+	ns_server_t *server = NULL;
595af1f
+	controlkey_t *key = NULL;
595af1f
 	isccc_sexpr_t *request = NULL;
595af1f
 	isccc_sexpr_t *response = NULL;
ad7b3b8
 	uint32_t algorithm;
ad7b3b8
@@ -338,16 +339,17 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
595af1f
 	isc_buffer_t *text;
595af1f
 	isc_result_t result;
595af1f
 	isc_result_t eresult;
595af1f
-	isccc_sexpr_t *_ctrl;
595af1f
+	isccc_sexpr_t *_ctrl = NULL;
595af1f
 	isccc_time_t sent;
595af1f
 	isccc_time_t exp;
ad7b3b8
 	uint32_t nonce;
595af1f
-	isccc_sexpr_t *data;
595af1f
+	isccc_sexpr_t *data = NULL;
595af1f
 
595af1f
 	REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG);
595af1f
 
595af1f
 	conn = event->ev_arg;
595af1f
 	listener = conn->listener;
595af1f
+	server = listener->controls->server;
595af1f
 	algorithm = DST_ALG_UNKNOWN;
595af1f
 	secret.rstart = NULL;
595af1f
 	text = NULL;
ad7b3b8
@@ -458,8 +460,11 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
595af1f
 	 * Establish nonce.
595af1f
 	 */
595af1f
 	if (conn->nonce == 0) {
595af1f
-		while (conn->nonce == 0)
595af1f
-			isc_random_get(&conn->nonce);
595af1f
+		while (conn->nonce == 0) {
ad7b3b8
+			uint16_t r1 = isc_rng_random(server->rngctx);
ad7b3b8
+			uint16_t r2 = isc_rng_random(server->rngctx);
595af1f
+			conn->nonce = (r1 << 16) | r2;
595af1f
+		}
595af1f
 		eresult = ISC_R_SUCCESS;
595af1f
 	} else
595af1f
 		eresult = ns_control_docommand(request, listener->readonly, &text);
595af1f
diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
ad7b3b8
index f5ed2b7..b2c1d05 100644
595af1f
--- a/bin/named/include/named/server.h
595af1f
+++ b/bin/named/include/named/server.h
ad7b3b8
@@ -20,6 +20,7 @@
595af1f
 #include <isc/log.h>
595af1f
 #include <isc/magic.h>
595af1f
 #include <isc/quota.h>
595af1f
+#include <isc/random.h>
595af1f
 #include <isc/sockaddr.h>
595af1f
 #include <isc/types.h>
595af1f
 #include <isc/xml.h>
ad7b3b8
@@ -134,6 +135,7 @@ struct ns_server {
595af1f
 	char *			lockfile;
595af1f
 
ad7b3b8
 	uint16_t		transfer_tcp_message_size;
595af1f
+	isc_rng_t *		rngctx;
595af1f
 };
595af1f
 
595af1f
 struct ns_altsecret {
595af1f
diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
12763cd
index 9bd1f93..851d3c9 100644
595af1f
--- a/bin/named/interfacemgr.c
595af1f
+++ b/bin/named/interfacemgr.c
ad7b3b8
@@ -17,6 +17,7 @@
595af1f
 
595af1f
 #include <isc/interfaceiter.h>
595af1f
 #include <isc/os.h>
595af1f
+#include <isc/random.h>
595af1f
 #include <isc/string.h>
595af1f
 #include <isc/task.h>
595af1f
 #include <isc/util.h>
595af1f
diff --git a/bin/named/query.c b/bin/named/query.c
12763cd
index 86417c7..55b7b7c 100644
595af1f
--- a/bin/named/query.c
595af1f
+++ b/bin/named/query.c
ad7b3b8
@@ -19,6 +19,7 @@
595af1f
 #include <isc/hex.h>
595af1f
 #include <isc/mem.h>
595af1f
 #include <isc/print.h>
595af1f
+#include <isc/random.h>
595af1f
 #include <isc/rwlock.h>
595af1f
 #include <isc/serial.h>
595af1f
 #include <isc/stats.h>
595af1f
diff --git a/bin/named/server.c b/bin/named/server.c
12763cd
index c782073..bc59cbc 100644
595af1f
--- a/bin/named/server.c
595af1f
+++ b/bin/named/server.c
12763cd
@@ -8204,21 +8204,32 @@ load_configuration(const char *filename, ns_server_t *server,
595af1f
 	 * Open the source of entropy.
595af1f
 	 */
595af1f
 	if (first_time) {
595af1f
+		const char *randomdev = NULL;
595af1f
+		int level = ISC_LOG_ERROR;
595af1f
 		obj = NULL;
595af1f
 		result = ns_config_get(maps, "random-device", &obj);
595af1f
-		if (result != ISC_R_SUCCESS) {
595af1f
+		if (result == ISC_R_SUCCESS) {
595af1f
+			if (!cfg_obj_isvoid(obj)) {
595af1f
+				level = ISC_LOG_INFO;
595af1f
+				randomdev = cfg_obj_asstring(obj);
595af1f
+			}
595af1f
+		}
595af1f
+		if (randomdev == NULL) {
1e41691
+#ifdef ISC_PLATFORM_CRYPTORANDOM
ad7b3b8
+			isc_entropy_usehook(ns_g_entropy, true);
1e41691
+#else
595af1f
+			if ((obj != NULL) && !cfg_obj_isvoid(obj))
595af1f
+				level = ISC_LOG_INFO;
1e41691
 			isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
1e41691
-				      NS_LOGMODULE_SERVER, ISC_LOG_INFO,
595af1f
+				      NS_LOGMODULE_SERVER, level,
1e41691
 				      "no source of entropy found");
595af1f
+			if ((obj == NULL) || cfg_obj_isvoid(obj)) {
595af1f
+				CHECK(ISC_R_FAILURE);
595af1f
+			}
595af1f
+#endif
1e41691
 		} else {
1e41691
-			const char *randomdev = cfg_obj_asstring(obj);
1e41691
-#ifdef ISC_PLATFORM_CRYPTORANDOM
1e41691
-			if (strcmp(randomdev, ISC_PLATFORM_CRYPTORANDOM) == 0)
1e41691
-				isc_entropy_usehook(ns_g_entropy, true);
1e41691
-#else
1e41691
-			int level = ISC_LOG_ERROR;
564c143
 			result = isc_entropy_createfilesource(ns_g_entropy,
1e41691
-							      randomdev);
564c143
+			                                      randomdev);
595af1f
 #ifdef PATH_RANDOMDEV
595af1f
 			if (ns_g_fallbackentropy != NULL) {
595af1f
 				level = ISC_LOG_INFO;
12763cd
@@ -8229,8 +8240,8 @@ load_configuration(const char *filename, ns_server_t *server,
595af1f
 					      NS_LOGCATEGORY_GENERAL,
595af1f
 					      NS_LOGMODULE_SERVER,
595af1f
 					      level,
595af1f
-					      "could not open entropy source "
595af1f
-					      "%s: %s",
595af1f
+					      "could not open "
595af1f
+					      "entropy source %s: %s",
595af1f
 					      randomdev,
595af1f
 					      isc_result_totext(result));
595af1f
 			}
12763cd
@@ -8250,7 +8261,6 @@ load_configuration(const char *filename, ns_server_t *server,
595af1f
 				}
595af1f
 				isc_entropy_detach(&ns_g_fallbackentropy);
595af1f
 			}
595af1f
-#endif
595af1f
 #endif
595af1f
 		}
12763cd
 
12763cd
@@ -9018,6 +9028,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
564c143
 	server->in_roothints = NULL;
564c143
 	server->blackholeacl = NULL;
564c143
 	server->keepresporder = NULL;
564c143
+	server->rngctx = NULL;
564c143
 
564c143
 	/* Must be first. */
564c143
 	CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy,
12763cd
@@ -9044,6 +9055,9 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
595af1f
 	CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy,
595af1f
 				      &server->tkeyctx),
595af1f
 		   "creating TKEY context");
e0ab89b
+	server->rngctx = NULL;
595af1f
+	CHECKFATAL(isc_rng_create(ns_g_mctx, ns_g_entropy, &server->rngctx),
595af1f
+	           "creating random numbers context");
595af1f
 
595af1f
 	/*
595af1f
 	 * Setup the server task, which is responsible for coordinating
12763cd
@@ -9250,7 +9264,8 @@ ns_server_destroy(ns_server_t **serverp) {
595af1f
 
595af1f
 	if (server->zonemgr != NULL)
595af1f
 		dns_zonemgr_detach(&server->zonemgr);
595af1f
-
595af1f
+	if (server->rngctx != NULL)
595af1f
+		isc_rng_detach(&server->rngctx);
595af1f
 	if (server->tkeyctx != NULL)
595af1f
 		dns_tkeyctx_destroy(&server->tkeyctx);
595af1f
 
12763cd
@@ -13221,10 +13236,10 @@ newzone_cfgctx_destroy(void **cfgp) {
595af1f
 
595af1f
 static isc_result_t
595af1f
 generate_salt(unsigned char *salt, size_t saltlen) {
595af1f
-	int i, n;
595af1f
+	size_t i, n;
595af1f
 	union {
595af1f
 		unsigned char rnd[256];
ad7b3b8
-		uint32_t rnd32[64];
ad7b3b8
+		uint16_t rnd16[128];
595af1f
 	} rnd;
595af1f
 	unsigned char text[512 + 1];
595af1f
 	isc_region_t r;
12763cd
@@ -13234,9 +13249,10 @@ generate_salt(unsigned char *salt, size_t saltlen) {
595af1f
 	if (saltlen > 256U)
595af1f
 		return (ISC_R_RANGE);
595af1f
 
ad7b3b8
-	n = (int) (saltlen + sizeof(uint32_t) - 1) / sizeof(uint32_t);
595af1f
-	for (i = 0; i < n; i++)
595af1f
-		isc_random_get(&rnd.rnd32[i]);
ad7b3b8
+	n = (saltlen + sizeof(uint16_t) - 1) / sizeof(uint16_t);
595af1f
+	for (i = 0; i < n; i++) {
595af1f
+		rnd.rnd16[i] = isc_rng_random(ns_g_server->rngctx);
595af1f
+	}
595af1f
 
595af1f
 	memmove(salt, rnd.rnd, saltlen);
595af1f
 
595af1f
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
564c143
index 0286987..0376377 100644
595af1f
--- a/bin/nsupdate/nsupdate.c
595af1f
+++ b/bin/nsupdate/nsupdate.c
ad7b3b8
@@ -283,9 +283,7 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
595af1f
 	}
595af1f
 
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
595af1f
+	if (randomfile == NULL) {
ad7b3b8
 		isc_entropy_usehook(*ectx, true);
595af1f
 	}
595af1f
 #endif
595af1f
diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c
12763cd
index f0a6ff2..55064f6 100644
595af1f
--- a/bin/tests/system/pipelined/pipequeries.c
595af1f
+++ b/bin/tests/system/pipelined/pipequeries.c
12763cd
@@ -280,9 +280,7 @@ main(int argc, char *argv[]) {
595af1f
 	ectx = NULL;
595af1f
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
595af1f
+	if (randomfile == NULL) {
ad7b3b8
 		isc_entropy_usehook(ectx, true);
595af1f
 	}
595af1f
 #endif
595af1f
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
ad7b3b8
index fe8698e..937fcc3 100644
595af1f
--- a/bin/tests/system/tkey/keycreate.c
595af1f
+++ b/bin/tests/system/tkey/keycreate.c
595af1f
@@ -255,9 +255,7 @@ main(int argc, char *argv[]) {
595af1f
 	ectx = NULL;
595af1f
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
595af1f
+	if (randomfile == NULL) {
ad7b3b8
 		isc_entropy_usehook(ectx, true);
595af1f
 	}
595af1f
 #endif
595af1f
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
564c143
index 2146f9b..64b8e74 100644
595af1f
--- a/bin/tests/system/tkey/keydelete.c
595af1f
+++ b/bin/tests/system/tkey/keydelete.c
564c143
@@ -171,6 +171,7 @@ main(int argc, char **argv) {
564c143
 		randomfile = argv[2];
564c143
 		argv += 2;
564c143
 		argc -= 2;
564c143
+		POST(argc);
564c143
 	}
564c143
 	keyname = argv[1];
564c143
 
564c143
@@ -182,9 +183,7 @@ main(int argc, char **argv) {
595af1f
 	ectx = NULL;
595af1f
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
-	if (randomfile != NULL &&
595af1f
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
595af1f
-		randomfile = NULL;
595af1f
+	if (randomfile == NULL) {
ad7b3b8
 		isc_entropy_usehook(ectx, true);
595af1f
 	}
595af1f
 #endif
595af1f
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
12763cd
index 9bf100f..c161e71 100644
595af1f
--- a/doc/arm/Bv9ARM-book.xml
595af1f
+++ b/doc/arm/Bv9ARM-book.xml
12763cd
@@ -5076,22 +5076,45 @@ badresp:1,adberr:0,findfail:0,valfail:0]
595af1f
 	    <term><command>random-device</command></term>
595af1f
 	    <listitem>
595af1f
 	      <para>
595af1f
-		The source of entropy to be used by the server.  Entropy is
595af1f
-		primarily needed
595af1f
-		for DNSSEC operations, such as TKEY transactions and dynamic
595af1f
-		update of signed
595af1f
-		zones.  This options specifies the device (or file) from which
595af1f
-		to read
595af1f
-		entropy.  If this is a file, operations requiring entropy will
595af1f
-		fail when the
595af1f
-		file has been exhausted.  If not specified, the default value
595af1f
-		is
595af1f
-		<filename>/dev/random</filename>
595af1f
-		(or equivalent) when present, and none otherwise.  The
595af1f
-		<command>random-device</command> option takes
595af1f
-		effect during
595af1f
-		the initial configuration load at server startup time and
595af1f
-		is ignored on subsequent reloads.
595af1f
+		Specifies a source of entropy to be used by the server.
595af1f
+		This is a device or file from which to read entropy.
595af1f
+		If it is a file, operations requiring entropy
595af1f
+		will fail when the file has been exhausted.
595af1f
+	      </para>
595af1f
+	      <para>
595af1f
+		Entropy is needed for cryptographic operations such as
595af1f
+		TKEY transactions, dynamic update of signed zones, and
595af1f
+		generation of TSIG session keys. It is also used for
595af1f
+		seeding and stirring the pseudo-random number generator,
595af1f
+		which is used for less critical functions requiring
595af1f
+		randomness such as generation of DNS message transaction
595af1f
+		ID's.
595af1f
+	      </para>
595af1f
+	      <para>
595af1f
+		If <command>random-device</command> is not specified, or
595af1f
+		if it is set to <literal>none</literal>, entropy will be
595af1f
+		read from the random number generation function supplied
595af1f
+		by the cryptographic library with which BIND was linked
595af1f
+		(i.e.  OpenSSL or a PKCS#11 provider).
595af1f
+	      </para>
595af1f
+	      <para>
595af1f
+		The <command>random-device</command> option takes
595af1f
+		effect during the initial configuration load at server
595af1f
+		startup time and is ignored on subsequent reloads.
595af1f
+	      </para>
595af1f
+	      <para>
595af1f
+		If BIND is built with
595af1f
+		<command>configure --disable-crypto-rand</command>, then
595af1f
+		entropy is <emphasis>not</emphasis> sourced from the
595af1f
+		cryptographic library. In this case, if
595af1f
+		<command>random-device</command> is not specified, the
595af1f
+		default value is the system random device,
595af1f
+		<filename>/dev/random</filename> or the equivalent.
595af1f
+		This default can be overridden with
595af1f
+		<command>configure --with-randomdev</command>.
595af1f
+		If no system random device exists, then no entropy source
595af1f
+		will be configured, and <command>named</command> will only
595af1f
+		be able to use pseudo-random numbers.
595af1f
 	      </para>
595af1f
 	    </listitem>
595af1f
 	  </varlistentry>
12763cd
diff --git a/doc/arm/notes-rh-changes.xml b/doc/arm/notes-rh-changes.xml
12763cd
new file mode 100644
12763cd
index 0000000..11c3a7c
12763cd
--- /dev/null
12763cd
+++ b/doc/arm/notes-rh-changes.xml
12763cd
@@ -0,0 +1,43 @@
12763cd
+
12763cd
+
12763cd
+ - Copyright (C) Internet Systems Consortium, Inc. ("ISC")
12763cd
+ -
12763cd
+ - This Source Code Form is subject to the terms of the Mozilla Public
12763cd
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
12763cd
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
12763cd
+ -
12763cd
+ - See the COPYRIGHT file distributed with this work for additional
12763cd
+ - information regarding copyright ownership.
12763cd
+-->
12763cd
+
12763cd
+<section xml:id="relnotes_rh_changes"><info><title>Red Hat Specific Changes</title></info>
12763cd
+  <itemizedlist>
12763cd
+     <listitem>
12763cd
+      <para>
12763cd
+        By default, BIND now uses the random number generation functions
12763cd
+        in the cryptographic library (i.e., OpenSSL or a PKCS#11
12763cd
+        provider) as a source of high-quality randomness rather than
12763cd
+        <filename>/dev/random</filename>.  This is suitable for virtual
12763cd
+        machine environments, which may have limited entropy pools and
12763cd
+        lack hardware random number generators.
12763cd
+      </para>
12763cd
+      <para>
12763cd
+        This can be overridden by specifying another entropy source via
12763cd
+        the <command>random-device</command> option in
12763cd
+        <filename>named.conf</filename>, or via the <command>-r</command>
12763cd
+        command line option.  However, for functions requiring full
12763cd
+        cryptographic strength, such as DNSSEC key generation, this
12763cd
+        <emphasis>cannot</emphasis> be overridden. In particular, the
12763cd
+        <command>-r</command> command line option no longer has any
12763cd
+        effect on <command>dnssec-keygen</command>.
12763cd
+      </para>
12763cd
+      <para>
12763cd
+        This can be disabled by building with
12763cd
+        <command>configure --disable-crypto-rand</command>, in which
12763cd
+        case <filename>/dev/random</filename> will be the default
12763cd
+        entropy source.  [RT #31459] [RT #46047]
12763cd
+      </para>
12763cd
+    </listitem>
12763cd
+  </itemizedlist>
12763cd
+</section>
12763cd
+
595af1f
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
12763cd
index 3a9cfcf..ded2000 100644
595af1f
--- a/doc/arm/notes.xml
595af1f
+++ b/doc/arm/notes.xml
12763cd
@@ -23,6 +23,7 @@
12763cd
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-sec-fixes.xml"/>
12763cd
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-new-features.xml"/>
12763cd
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-bug-fixes.xml"/>
12763cd
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-rh-changes.xml"/>
12763cd
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-eol.xml"/>
12763cd
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-thankyou.xml"/>
12763cd
 </section>
595af1f
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
12763cd
index 1614afa..0f52df9 100644
595af1f
--- a/lib/dns/dst_api.c
595af1f
+++ b/lib/dns/dst_api.c
12763cd
@@ -2017,10 +2017,12 @@ dst__entropy_getdata(void *buf, unsigned int len, bool pseudo) {
595af1f
 	else
595af1f
 		flags |= ISC_ENTROPY_BLOCKING;
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
+	/* get entropy directly from crypto provider */
595af1f
 	return (dst_random_getdata(buf, len, NULL, flags));
595af1f
 #else
595af1f
+	/* get entropy from entropy source or hook function */
595af1f
 	return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
595af1f
-#endif
595af1f
+#endif /* ISC_PLATFORM_CRYPTORANDOM */
595af1f
 #endif /* PKCS11CRYPTO */
595af1f
 }
595af1f
 
595af1f
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
1e41691
index 6813c96..665574d 100644
595af1f
--- a/lib/dns/include/dst/dst.h
595af1f
+++ b/lib/dns/include/dst/dst.h
1e41691
@@ -163,8 +163,18 @@ isc_result_t
595af1f
 dst_random_getdata(void *data, unsigned int length,
595af1f
 		   unsigned int *returned, unsigned int flags);
595af1f
 /*%<
595af1f
- * \brief Return data from the crypto random generator.
595af1f
- * Specialization of isc_entropy_getdata().
595af1f
+ * Gets random data from the random generator provided by the
595af1f
+ * crypto library, if BIND was built with --enable-crypto-rand.
595af1f
+ *
595af1f
+ * See isc_entropy_getdata() for parameter usage. Normally when
595af1f
+ * this function is available, it will be set up as a hook in the
595af1f
+ * entropy context, so that isc_entropy_getdata() is a front-end to
595af1f
+ * this function.
595af1f
+ *
595af1f
+ * Returns:
595af1f
+ * \li	ISC_R_SUCCESS on success
595af1f
+ * \li	ISC_R_NOTIMPLEMENTED if BIND is built with --disable-crypto-rand
595af1f
+ * \li	DST_R_OPENSSLFAILURE, DST_R_CRYPTOFAILURE, or other codes on error
595af1f
  */
595af1f
 
ad7b3b8
 bool
595af1f
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
1e41691
index 6849732..e00a0e4 100644
595af1f
--- a/lib/dns/openssl_link.c
595af1f
+++ b/lib/dns/openssl_link.c
1e41691
@@ -484,7 +484,8 @@ dst__openssl_getengine(const char *engine) {
595af1f
 
595af1f
 isc_result_t
595af1f
 dst_random_getdata(void *data, unsigned int length,
595af1f
-		   unsigned int *returned, unsigned int flags) {
595af1f
+		   unsigned int *returned, unsigned int flags)
595af1f
+{
595af1f
 #ifdef ISC_PLATFORM_CRYPTORANDOM
595af1f
 #ifndef DONT_REQUIRE_DST_LIB_INIT
595af1f
 	INSIST(dst__memory_pool != NULL);
595af1f
diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h
ad7b3b8
index 632166a..c7cb17d 100644
595af1f
--- a/lib/isc/include/isc/entropy.h
595af1f
+++ b/lib/isc/include/isc/entropy.h
595af1f
@@ -9,8 +9,6 @@
595af1f
  * information regarding copyright ownership.
595af1f
  */
595af1f
 
595af1f
-/* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */
595af1f
-
595af1f
 #ifndef ISC_ENTROPY_H
595af1f
 #define ISC_ENTROPY_H 1
595af1f
 
ad7b3b8
@@ -191,9 +189,8 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
595af1f
 /*!<
595af1f
  * \brief Create an entropy source that is polled via a callback.
595af1f
  *
595af1f
- * This would
595af1f
- * be used when keyboard input is used, or a GUI input method.  It can
595af1f
- * also be used to hook in any external entropy source.
595af1f
+ * This would be used when keyboard input is used, or a GUI input method.
595af1f
+ * It can also be used to hook in any external entropy source.
595af1f
  *
595af1f
  * Samples are added via isc_entropy_addcallbacksample(), below.
595af1f
  * _addcallbacksample() is the only function which may be called from
ad7b3b8
@@ -234,15 +231,32 @@ isc_result_t
595af1f
 isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
595af1f
 		    unsigned int *returned, unsigned int flags);
595af1f
 /*!<
595af1f
- * \brief Extract data from the entropy pool.  This may load the pool from various
595af1f
- * sources.
595af1f
+ * \brief Get random data from entropy pool 'ent'.
595af1f
+ *
595af1f
+ * If a hook has been set up using isc_entropy_sethook() and
595af1f
+ * isc_entropy_usehook(), then the hook function will be called to get
595af1f
+ * random data.
595af1f
+ *
595af1f
+ * Otherwise, randomness is extracted from the entropy pool set up in BIND.
595af1f
+ * This may cause the pool to be loaded from various sources. Ths is done
595af1f
+ * by stirring the pool and returning a part of hash as randomness.
595af1f
+ * (Note that no secrets are given away here since parts of the hash are
595af1f
+ * XORed together before returning.)
595af1f
+ *
595af1f
+ * 'flags' may contain ISC_ENTROPY_GOODONLY, ISC_ENTROPY_PARTIAL, or
595af1f
+ * ISC_ENTROPY_BLOCKING. These will be honored if the hook function is
595af1f
+ * not in use. If it is, the flags will be passed to the hook function
595af1f
+ * but it may ignore them.
595af1f
  *
595af1f
- * Do this by stiring the pool and returning a part of hash as randomness.
595af1f
- * Note that no secrets are given away here since parts of the hash are
595af1f
- * xored together before returned.
595af1f
+ * Up to 'length' bytes of randomness are retrieved and copied into 'data'.
595af1f
+ * (If 'returned' is not NULL, and the number of bytes copied is less than
595af1f
+ * 'length' - which may happen if ISC_ENTROPY_PARTIAL was used - then the
595af1f
+ * number of bytes copied will be stored in *returned.)
595af1f
  *
595af1f
- * Honor the request from the caller to only return good data, any data,
595af1f
- * etc.
595af1f
+ * Returns:
595af1f
+ * \li	ISC_R_SUCCESS on success
595af1f
+ * \li	ISC_R_NOENTROPY if entropy pool is empty
595af1f
+ * \li	other error codes are possible when a hook is in use
595af1f
  */
595af1f
 
595af1f
 void
ad7b3b8
@@ -307,13 +321,21 @@ isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
595af1f
 void
ad7b3b8
 isc_entropy_usehook(isc_entropy_t *ectx, bool onoff);
595af1f
 /*!<
595af1f
- * \brief Mark/unmark the given entropy structure as being hooked.
595af1f
+ * \brief Configure entropy context 'ectx' to use the hook function
595af1f
+ *
595af1f
+ * Sets the entropy context to call the hook function for random number
595af1f
+ * generation, if such a function has been configured via
595af1f
+ * isc_entropy_sethook(), whenever isc_entropy_getdata() is called.
595af1f
  */
595af1f
 
595af1f
 void
595af1f
 isc_entropy_sethook(isc_entropy_getdata_t myhook);
595af1f
 /*!<
595af1f
- * \brief Set the getdata hook (e.g., for a crypto random generator).
595af1f
+ * \brief Set the hook function.
595af1f
+ *
595af1f
+ * The hook function is a global value: only one hook function
595af1f
+ * can be set in the system. Individual entropy contexts may be
595af1f
+ * configured to use it, or not, by calling isc_entropy_usehook().
595af1f
  */
595af1f
 
595af1f
 ISC_LANG_ENDDECLS
595af1f
diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h
ad7b3b8
index f8aed34..17c551b 100644
595af1f
--- a/lib/isc/include/isc/random.h
595af1f
+++ b/lib/isc/include/isc/random.h
595af1f
@@ -9,8 +9,6 @@
595af1f
  * information regarding copyright ownership.
595af1f
  */
595af1f
 
595af1f
-/* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */
595af1f
-
595af1f
 #ifndef ISC_RANDOM_H
595af1f
 #define ISC_RANDOM_H 1
595af1f
 
595af1f
@@ -21,13 +19,23 @@
595af1f
 #include <isc/mutex.h>
595af1f
 
595af1f
 /*! \file isc/random.h
595af1f
- * \brief Implements a random state pool which will let the caller return a
595af1f
- * series of possibly non-reproducible random values.
595af1f
+ * \brief Implements pseudo random number generators.
595af1f
+ *
595af1f
+ * Two pseudo-random number generators are implemented, in isc_random_*
595af1f
+ * and isc_rng_*. Neither one is very strong; they should not be used
595af1f
+ * in cryptography functions.
595af1f
+ *
595af1f
+ * isc_random_* is based on arc4random if it is available on the system.
595af1f
+ * Otherwise it is based on the posix srand() and rand() functions.
595af1f
+ * It is useful for jittering values a bit here and there, such as
595af1f
+ * timeouts, etc, but should not be relied upon to generate
595af1f
+ * unpredictable sequences (for example, when choosing transaction IDs).
595af1f
  *
595af1f
- * Note that the
595af1f
- * strength of these numbers is not all that high, and should not be
595af1f
- * used in cryptography functions.  It is useful for jittering values
595af1f
- * a bit here and there, such as timeouts, etc.
595af1f
+ * isc_rng_* is based on ChaCha20, and is seeded and stirred from the
595af1f
+ * system entropy source. It is stronger than isc_random_* and can
595af1f
+ * be used for generating unpredictable sequences. It is still not as
595af1f
+ * good as using system entropy directly (see entropy.h) and should not
595af1f
+ * be used for cryptographic functions such as key generation.
595af1f
  */
595af1f
 
595af1f
 ISC_LANG_BEGINDECLS
595af1f
@@ -115,8 +123,8 @@ isc_rng_random(isc_rng_t *rngctx);
ad7b3b8
 uint16_t
ad7b3b8
 isc_rng_uniformrandom(isc_rng_t *rngctx, uint16_t upper_bound);
595af1f
 /*%<
595af1f
- * Returns a uniformly distributed pseudo random 16-bit unsigned
595af1f
- * integer.
595af1f
+ * Returns a uniformly distributed pseudo-random 16-bit unsigned integer
595af1f
+ * less than 'upper_bound'.
595af1f
  */
595af1f
 
595af1f
 ISC_LANG_ENDDECLS
595af1f
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
12763cd
index 03890a3..7bad989 100644
595af1f
--- a/lib/isccfg/namedconf.c
595af1f
+++ b/lib/isccfg/namedconf.c
ad7b3b8
@@ -1109,7 +1109,7 @@ options_clauses[] = {
595af1f
 	{ "pid-file", &cfg_type_qstringornone, 0 },
595af1f
 	{ "port", &cfg_type_uint32, 0 },
595af1f
 	{ "querylog", &cfg_type_boolean, 0 },
595af1f
-	{ "random-device", &cfg_type_qstring, 0 },
595af1f
+	{ "random-device", &cfg_type_qstringornone, 0 },
595af1f
 	{ "recursing-file", &cfg_type_qstring, 0 },
595af1f
 	{ "recursive-clients", &cfg_type_uint32, 0 },
595af1f
 	{ "reserved-sockets", &cfg_type_uint32, 0 },
595af1f
-- 
1e41691
2.20.1
595af1f