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