Blame SOURCES/bind-9.11-rt46047.patch

e55890
From dc861636b6bcb4a028b2392347a57a61bb5ece6e Mon Sep 17 00:00:00 2001
e55890
From: Evan Hunt <each@isc.org>
e55890
Date: Thu, 28 Sep 2017 10:09:22 -0700
e55890
Subject: [PATCH] completed and corrected the crypto-random change
e55890
e55890
4724.	[func]		By default, BIND now uses the random number
e55890
			functions provided by the crypto library (i.e.,
e55890
			OpenSSL or a PKCS#11 provider) as a source of
e55890
			randomness rather than /dev/random.  This is
e55890
			suitable for virtual machine environments
e55890
			which have limited entropy pools and lack
e55890
			hardware random number generators.
e55890
e55890
			This can be overridden by specifying another
e55890
			entropy source via the "random-device" option
e55890
			in named.conf, or via the -r command line option;
e55890
			however, for functions requiring full cryptographic
e55890
			strength, such as DNSSEC key generation, this
e55890
			cannot be overridden. In particular, the -r
e55890
			command line option no longer has any effect on
e55890
			dnssec-keygen.
e55890
e55890
			This can be disabled by building with
e55890
			"configure --disable-crypto-rand".
e55890
			[RT #31459] [RT #46047]
e55890
---
e55890
 bin/confgen/keygen.c                     | 12 +++---
e55890
 bin/dnssec/dnssec-keygen.docbook         | 24 +++++++----
e55890
 bin/dnssec/dnssectool.c                  | 12 +++---
e55890
 bin/named/client.c                       |  3 +-
e55890
 bin/named/config.c                       |  4 +-
e55890
 bin/named/controlconf.c                  | 19 +++++---
e55890
 bin/named/include/named/server.h         |  2 +
e55890
 bin/named/interfacemgr.c                 |  1 +
e55890
 bin/named/query.c                        |  1 +
e55890
 bin/named/server.c                       | 52 +++++++++++++---------
e55890
 bin/nsupdate/nsupdate.c                  |  4 +-
e55890
 bin/tests/system/pipelined/pipequeries.c |  4 +-
e55890
 bin/tests/system/tkey/keycreate.c        |  4 +-
e55890
 bin/tests/system/tkey/keydelete.c        |  4 +-
e55890
 doc/arm/Bv9ARM-book.xml                  | 55 +++++++++++++++++-------
e55890
 doc/arm/notes.xml                        | 23 +++++++++-
e55890
 lib/dns/dst_api.c                        |  7 ++-
e55890
 lib/dns/include/dst/dst.h                | 14 +++++-
e55890
 lib/dns/openssl_link.c                   |  3 +-
e55890
 lib/isc/include/isc/entropy.h            | 50 +++++++++++++++------
e55890
 lib/isc/include/isc/random.h             | 28 +++++++-----
e55890
 lib/isccfg/namedconf.c                   |  2 +-
e55890
 22 files changed, 218 insertions(+), 110 deletions(-)
e55890
e55890
diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c
e55890
index fa439cc..a7ad417 100644
e55890
--- a/bin/confgen/keygen.c
e55890
+++ b/bin/confgen/keygen.c
e55890
@@ -161,17 +161,15 @@ generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg,
e55890
 
e55890
 	DO("create entropy context", isc_entropy_create(mctx, &ectx));
e55890
 
e55890
-	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
e55890
-		randomfile = NULL;
e55890
-		open_keyboard = ISC_ENTROPY_KEYBOARDYES;
e55890
-	}
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
+	if (randomfile == NULL) {
e55890
 		isc_entropy_usehook(ectx, ISC_TRUE);
e55890
 	}
e55890
 #endif
e55890
+	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
e55890
+		randomfile = NULL;
e55890
+		open_keyboard = ISC_ENTROPY_KEYBOARDYES;
e55890
+	}
e55890
 	DO("start entropy source", isc_entropy_usebestsource(ectx,
e55890
 							     &entropy_source,
e55890
 							     randomfile,
e55890
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook
e55890
index 96dfef6..1c84b06 100644
e55890
--- a/bin/dnssec/dnssec-keygen.docbook
e55890
+++ b/bin/dnssec/dnssec-keygen.docbook
e55890
@@ -349,15 +349,23 @@
e55890
 	<term>-r <replaceable class="parameter">randomdev</replaceable></term>
e55890
 	<listitem>
e55890
 	  <para>
e55890
-	    Specifies the source of randomness.  If the operating
e55890
-	    system does not provide a <filename>/dev/random</filename>
e55890
-	    or equivalent device, the default source of randomness
e55890
-	    is keyboard input.  <filename>randomdev</filename>
e55890
-	    specifies
e55890
+	    Specifies a source of randomness.  Normally, when generating
e55890
+	    DNSSEC keys, this option has no effect; the random number
e55890
+	    generation function provided by the cryptographic library will
e55890
+	    be used.
e55890
+	  </para>
e55890
+	  <para>
e55890
+	    If that behavior is disabled at compile time, however,
e55890
+	    the specified file will be used as entropy source
e55890
+	    for key generation.  <filename>randomdev</filename> is
e55890
 	    the name of a character device or file containing random
e55890
-	    data to be used instead of the default.  The special value
e55890
-	    <filename>keyboard</filename> indicates that keyboard
e55890
-	    input should be used.
e55890
+	    data to be used.  The special value <filename>keyboard</filename>
e55890
+	    indicates that keyboard input should be used.
e55890
+	  </para>
e55890
+	  <para>
e55890
+	    The default is <filename>/dev/random</filename> if the
e55890
+	    operating system provides it or an equivalent device;
e55890
+	    if not, the default source of randomness is keyboard input.
e55890
 	  </para>
e55890
 	</listitem>
e55890
       </varlistentry>
e55890
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c
e55890
index 4ea9eaf..5dd9475 100644
e55890
--- a/bin/dnssec/dnssectool.c
e55890
+++ b/bin/dnssec/dnssectool.c
e55890
@@ -239,18 +239,16 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
e55890
 		ISC_LIST_INIT(sources);
e55890
 	}
e55890
 
e55890
+#ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
+	if (randomfile == NULL) {
e55890
+		isc_entropy_usehook(*ectx, ISC_TRUE);
e55890
+	}
e55890
+#endif
e55890
 	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
e55890
 		usekeyboard = ISC_ENTROPY_KEYBOARDYES;
e55890
 		randomfile = NULL;
e55890
 	}
e55890
 
e55890
-#ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
-		isc_entropy_usehook(*ectx, ISC_TRUE);
e55890
-	}
e55890
-#endif
e55890
 	result = isc_entropy_usebestsource(*ectx, &source, randomfile,
e55890
 					   usekeyboard);
e55890
 
e55890
diff --git a/bin/named/client.c b/bin/named/client.c
e55890
index b7d8a98..56d475c 100644
e55890
--- a/bin/named/client.c
e55890
+++ b/bin/named/client.c
e55890
@@ -1605,7 +1605,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
e55890
 
e55890
 		isc_buffer_init(&buf, cookie, sizeof(cookie));
e55890
 		isc_stdtime_get(&now;;
e55890
-		isc_random_get(&nonce);
e55890
+		nonce = ((isc_rng_random(ns_g_server->rngctx) << 16) |
e55890
+			 isc_rng_random(ns_g_server->rngctx));
e55890
 
e55890
 		compute_cookie(client, now, nonce, ns_g_server->secret, &buf;;
e55890
 
e55890
diff --git a/bin/named/config.c b/bin/named/config.c
e55890
index c50f759..c1e72ef 100644
e55890
--- a/bin/named/config.c
e55890
+++ b/bin/named/config.c
e55890
@@ -92,7 +92,9 @@ options {\n\
e55890
 #	pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
e55890
 	port 53;\n\
e55890
 	prefetch 2 9;\n"
e55890
-#ifdef PATH_RANDOMDEV
e55890
+#if defined(ISC_PLATFORM_CRYPTORANDOM)
e55890
+"	random-device none;\n"
e55890
+#elif defined(PATH_RANDOMDEV)
e55890
 "	random-device \"" PATH_RANDOMDEV "\";\n"
e55890
 #endif
e55890
 "	recursing-file \"named.recursing\";\n\
e55890
diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c
e55890
index 237e8dc..b905475 100644
e55890
--- a/bin/named/controlconf.c
e55890
+++ b/bin/named/controlconf.c
e55890
@@ -322,9 +322,10 @@ log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
e55890
 
e55890
 static void
e55890
 control_recvmessage(isc_task_t *task, isc_event_t *event) {
e55890
-	controlconnection_t *conn;
e55890
-	controllistener_t *listener;
e55890
-	controlkey_t *key;
e55890
+	controlconnection_t *conn = NULL;
e55890
+	controllistener_t *listener = NULL;
e55890
+	ns_server_t *server = NULL;
e55890
+	controlkey_t *key = NULL;
e55890
 	isccc_sexpr_t *request = NULL;
e55890
 	isccc_sexpr_t *response = NULL;
e55890
 	isc_uint32_t algorithm;
e55890
@@ -335,16 +336,17 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
e55890
 	isc_buffer_t *text;
e55890
 	isc_result_t result;
e55890
 	isc_result_t eresult;
e55890
-	isccc_sexpr_t *_ctrl;
e55890
+	isccc_sexpr_t *_ctrl = NULL;
e55890
 	isccc_time_t sent;
e55890
 	isccc_time_t exp;
e55890
 	isc_uint32_t nonce;
e55890
-	isccc_sexpr_t *data;
e55890
+	isccc_sexpr_t *data = NULL;
e55890
 
e55890
 	REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG);
e55890
 
e55890
 	conn = event->ev_arg;
e55890
 	listener = conn->listener;
e55890
+	server = listener->controls->server;
e55890
 	algorithm = DST_ALG_UNKNOWN;
e55890
 	secret.rstart = NULL;
e55890
 	text = NULL;
e55890
@@ -455,8 +457,11 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
e55890
 	 * Establish nonce.
e55890
 	 */
e55890
 	if (conn->nonce == 0) {
e55890
-		while (conn->nonce == 0)
e55890
-			isc_random_get(&conn->nonce);
e55890
+		while (conn->nonce == 0) {
e55890
+			isc_uint16_t r1 = isc_rng_random(server->rngctx);
e55890
+			isc_uint16_t r2 = isc_rng_random(server->rngctx);
e55890
+			conn->nonce = (r1 << 16) | r2;
e55890
+		}
e55890
 		eresult = ISC_R_SUCCESS;
e55890
 	} else
e55890
 		eresult = ns_control_docommand(request, listener->readonly, &text);
e55890
diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
e55890
index d8179a6..e03d24d 100644
e55890
--- a/bin/named/include/named/server.h
e55890
+++ b/bin/named/include/named/server.h
e55890
@@ -17,6 +17,7 @@
e55890
 #include <isc/log.h>
e55890
 #include <isc/magic.h>
e55890
 #include <isc/quota.h>
e55890
+#include <isc/random.h>
e55890
 #include <isc/sockaddr.h>
e55890
 #include <isc/types.h>
e55890
 #include <isc/xml.h>
e55890
@@ -131,6 +132,7 @@ struct ns_server {
e55890
 	char *			lockfile;
e55890
 
e55890
 	isc_uint16_t		transfer_tcp_message_size;
e55890
+	isc_rng_t *		rngctx;
e55890
 };
e55890
 
e55890
 struct ns_altsecret {
e55890
diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
e55890
index d8c7188..50f924e 100644
e55890
--- a/bin/named/interfacemgr.c
e55890
+++ b/bin/named/interfacemgr.c
e55890
@@ -15,6 +15,7 @@
e55890
 
e55890
 #include <isc/interfaceiter.h>
e55890
 #include <isc/os.h>
e55890
+#include <isc/random.h>
e55890
 #include <isc/string.h>
e55890
 #include <isc/task.h>
e55890
 #include <isc/util.h>
e55890
diff --git a/bin/named/query.c b/bin/named/query.c
e55890
index accbf3b..d89622d 100644
e55890
--- a/bin/named/query.c
e55890
+++ b/bin/named/query.c
e55890
@@ -18,6 +18,7 @@
e55890
 #include <isc/hex.h>
e55890
 #include <isc/mem.h>
e55890
 #include <isc/print.h>
e55890
+#include <isc/random.h>
e55890
 #include <isc/rwlock.h>
e55890
 #include <isc/serial.h>
e55890
 #include <isc/stats.h>
e55890
diff --git a/bin/named/server.c b/bin/named/server.c
e55890
index ca789e5..db02709 100644
e55890
--- a/bin/named/server.c
e55890
+++ b/bin/named/server.c
e55890
@@ -8076,21 +8076,30 @@ load_configuration(const char *filename, ns_server_t *server,
e55890
 	 * Open the source of entropy.
e55890
 	 */
e55890
 	if (first_time) {
e55890
+		const char *randomdev = NULL;
e55890
+		int level = ISC_LOG_ERROR;
e55890
 		obj = NULL;
e55890
 		result = ns_config_get(maps, "random-device", &obj);
e55890
-		if (result != ISC_R_SUCCESS) {
e55890
-			isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
e55890
-				      NS_LOGMODULE_SERVER, ISC_LOG_INFO,
e55890
-				      "no source of entropy found");
e55890
-		} else {
e55890
-			const char *randomdev = cfg_obj_asstring(obj);
e55890
+		if (result == ISC_R_SUCCESS) {
e55890
+			if (!cfg_obj_isvoid(obj)) {
e55890
+				level = ISC_LOG_INFO;
e55890
+				randomdev = cfg_obj_asstring(obj);
e55890
+			}
e55890
+		}
e55890
+		if (randomdev == NULL) {
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-			if (strcmp(randomdev, ISC_PLATFORM_CRYPTORANDOM) == 0)
e55890
-				isc_entropy_usehook(ns_g_entropy, ISC_TRUE);
e55890
+			isc_entropy_usehook(ns_g_entropy, ISC_TRUE);
e55890
 #else
e55890
-			int level = ISC_LOG_ERROR;
e55890
-			result = isc_entropy_createfilesource(ns_g_entropy,
e55890
-							      randomdev);
e55890
+			if ((obj != NULL) && !cfg_obj_isvoid(obj))
e55890
+				level = ISC_LOG_INFO;
e55890
+			isc_log_write(named_g_lctx, NS_LOGCATEGORY_GENERAL,
e55890
+				      NS_LOGMODULE_SERVER, level,
e55890
+				      "no source of entropy found");
e55890
+			if ((obj == NULL) || cfg_obj_isvoid(obj)) {
e55890
+				CHECK(ISC_R_FAILURE);
e55890
+			}
e55890
+#endif
e55890
+		} else {
e55890
 #ifdef PATH_RANDOMDEV
e55890
 			if (ns_g_fallbackentropy != NULL) {
e55890
 				level = ISC_LOG_INFO;
e55890
@@ -8101,8 +8110,8 @@ load_configuration(const char *filename, ns_server_t *server,
e55890
 					      NS_LOGCATEGORY_GENERAL,
e55890
 					      NS_LOGMODULE_SERVER,
e55890
 					      level,
e55890
-					      "could not open entropy source "
e55890
-					      "%s: %s",
e55890
+					      "could not open "
e55890
+					      "entropy source %s: %s",
e55890
 					      randomdev,
e55890
 					      isc_result_totext(result));
e55890
 			}
e55890
@@ -8122,7 +8131,6 @@ load_configuration(const char *filename, ns_server_t *server,
e55890
 				}
e55890
 				isc_entropy_detach(&ns_g_fallbackentropy);
e55890
 			}
e55890
-#endif
e55890
 #endif
e55890
 		}
e55890
 	}
e55890
@@ -8911,6 +8919,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
e55890
 	CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy,
e55890
 				      &server->tkeyctx),
e55890
 		   "creating TKEY context");
e55890
+	CHECKFATAL(isc_rng_create(ns_g_mctx, ns_g_entropy, &server->rngctx),
e55890
+	           "creating random numbers context");
e55890
 
e55890
 	/*
e55890
 	 * Setup the server task, which is responsible for coordinating
e55890
@@ -9117,7 +9127,8 @@ ns_server_destroy(ns_server_t **serverp) {
e55890
 
e55890
 	if (server->zonemgr != NULL)
e55890
 		dns_zonemgr_detach(&server->zonemgr);
e55890
-
e55890
+	if (server->rngctx != NULL)
e55890
+		isc_rng_detach(&server->rngctx);
e55890
 	if (server->tkeyctx != NULL)
e55890
 		dns_tkeyctx_destroy(&server->tkeyctx);
e55890
 
e55890
@@ -13018,10 +13029,10 @@ newzone_cfgctx_destroy(void **cfgp) {
e55890
 
e55890
 static isc_result_t
e55890
 generate_salt(unsigned char *salt, size_t saltlen) {
e55890
-	int i, n;
e55890
+	size_t i, n;
e55890
 	union {
e55890
 		unsigned char rnd[256];
e55890
-		isc_uint32_t rnd32[64];
e55890
+		isc_uint16_t rnd16[128];
e55890
 	} rnd;
e55890
 	unsigned char text[512 + 1];
e55890
 	isc_region_t r;
e55890
@@ -13031,9 +13042,10 @@ generate_salt(unsigned char *salt, size_t saltlen) {
e55890
 	if (saltlen > 256U)
e55890
 		return (ISC_R_RANGE);
e55890
 
e55890
-	n = (int) (saltlen + sizeof(isc_uint32_t) - 1) / sizeof(isc_uint32_t);
e55890
-	for (i = 0; i < n; i++)
e55890
-		isc_random_get(&rnd.rnd32[i]);
e55890
+	n = (saltlen + sizeof(isc_uint16_t) - 1) / sizeof(isc_uint16_t);
e55890
+	for (i = 0; i < n; i++) {
e55890
+		rnd.rnd16[i] = isc_rng_random(ns_g_server->rngctx);
e55890
+	}
e55890
 
e55890
 	memmove(salt, rnd.rnd, saltlen);
e55890
 
e55890
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
e55890
index 46c7acf..a0d0278 100644
e55890
--- a/bin/nsupdate/nsupdate.c
e55890
+++ b/bin/nsupdate/nsupdate.c
e55890
@@ -281,9 +281,7 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
e55890
 	}
e55890
 
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
+	if (randomfile == NULL) {
e55890
 		isc_entropy_usehook(*ectx, ISC_TRUE);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c
e55890
index 810d99e..d7d10e2 100644
e55890
--- a/bin/tests/system/pipelined/pipequeries.c
e55890
+++ b/bin/tests/system/pipelined/pipequeries.c
e55890
@@ -279,9 +279,7 @@ main(int argc, char *argv[]) {
e55890
 	ectx = NULL;
e55890
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
+	if (randomfile == NULL) {
e55890
 		isc_entropy_usehook(ectx, ISC_TRUE);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
e55890
index 4f2f5b4..0894db7 100644
e55890
--- a/bin/tests/system/tkey/keycreate.c
e55890
+++ b/bin/tests/system/tkey/keycreate.c
e55890
@@ -255,9 +255,7 @@ main(int argc, char *argv[]) {
e55890
 	ectx = NULL;
e55890
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
+	if (randomfile == NULL) {
e55890
 		isc_entropy_usehook(ectx, ISC_TRUE);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
e55890
index 0975bbe..5b8a470 100644
e55890
--- a/bin/tests/system/tkey/keydelete.c
e55890
+++ b/bin/tests/system/tkey/keydelete.c
e55890
@@ -182,9 +182,7 @@ main(int argc, char **argv) {
e55890
 	ectx = NULL;
e55890
 	RUNCHECK(isc_entropy_create(mctx, &ectx));
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (randomfile != NULL &&
e55890
-	    strcmp(randomfile, ISC_PLATFORM_CRYPTORANDOM) == 0) {
e55890
-		randomfile = NULL;
e55890
+	if (randomfile == NULL) {
e55890
 		isc_entropy_usehook(ectx, ISC_TRUE);
e55890
 	}
e55890
 #endif
e55890
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
e55890
index a5d9e2e..2a96f71 100644
e55890
--- a/doc/arm/Bv9ARM-book.xml
e55890
+++ b/doc/arm/Bv9ARM-book.xml
e55890
@@ -5070,22 +5070,45 @@ badresp:1,adberr:0,findfail:0,valfail:0]
e55890
 	    <term><command>random-device</command></term>
e55890
 	    <listitem>
e55890
 	      <para>
e55890
-		The source of entropy to be used by the server.  Entropy is
e55890
-		primarily needed
e55890
-		for DNSSEC operations, such as TKEY transactions and dynamic
e55890
-		update of signed
e55890
-		zones.  This options specifies the device (or file) from which
e55890
-		to read
e55890
-		entropy.  If this is a file, operations requiring entropy will
e55890
-		fail when the
e55890
-		file has been exhausted.  If not specified, the default value
e55890
-		is
e55890
-		<filename>/dev/random</filename>
e55890
-		(or equivalent) when present, and none otherwise.  The
e55890
-		<command>random-device</command> option takes
e55890
-		effect during
e55890
-		the initial configuration load at server startup time and
e55890
-		is ignored on subsequent reloads.
e55890
+		Specifies a source of entropy to be used by the server.
e55890
+		This is a device or file from which to read entropy.
e55890
+		If it is a file, operations requiring entropy
e55890
+		will fail when the file has been exhausted.
e55890
+	      </para>
e55890
+	      <para>
e55890
+		Entropy is needed for cryptographic operations such as
e55890
+		TKEY transactions, dynamic update of signed zones, and
e55890
+		generation of TSIG session keys. It is also used for
e55890
+		seeding and stirring the pseudo-random number generator,
e55890
+		which is used for less critical functions requiring
e55890
+		randomness such as generation of DNS message transaction
e55890
+		ID's.
e55890
+	      </para>
e55890
+	      <para>
e55890
+		If <command>random-device</command> is not specified, or
e55890
+		if it is set to <literal>none</literal>, entropy will be
e55890
+		read from the random number generation function supplied
e55890
+		by the cryptographic library with which BIND was linked
e55890
+		(i.e.  OpenSSL or a PKCS#11 provider).
e55890
+	      </para>
e55890
+	      <para>
e55890
+		The <command>random-device</command> option takes
e55890
+		effect during the initial configuration load at server
e55890
+		startup time and is ignored on subsequent reloads.
e55890
+	      </para>
e55890
+	      <para>
e55890
+		If BIND is built with
e55890
+		<command>configure --disable-crypto-rand</command>, then
e55890
+		entropy is <emphasis>not</emphasis> sourced from the
e55890
+		cryptographic library. In this case, if
e55890
+		<command>random-device</command> is not specified, the
e55890
+		default value is the system random device,
e55890
+		<filename>/dev/random</filename> or the equivalent.
e55890
+		This default can be overridden with
e55890
+		<command>configure --with-randomdev</command>.
e55890
+		If no system random device exists, then no entropy source
e55890
+		will be configured, and <command>named</command> will only
e55890
+		be able to use pseudo-random numbers.
e55890
 	      </para>
e55890
 	    </listitem>
e55890
 	  </varlistentry>
e55890
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
e55890
index d3fdb5e..fbc78a0 100644
e55890
--- a/doc/arm/notes.xml
e55890
+++ b/doc/arm/notes.xml
e55890
@@ -115,7 +115,28 @@
e55890
     <itemizedlist>
e55890
       <listitem>
e55890
 	<para>
e55890
-	  None.
e55890
+	  By default, BIND now uses the random number generation functions
e55890
+	  in the cryptographic library (i.e., OpenSSL or a PKCS#11
e55890
+	  provider) as a source of high-quality randomness rather than
e55890
+	  <filename>/dev/random</filename>.  This is suitable for virtual
e55890
+	  machine environments, which may have limited entropy pools and
e55890
+	  lack hardware random number generators.
e55890
+	</para>
e55890
+	<para>
e55890
+	  This can be overridden by specifying another entropy source via
e55890
+	  the <command>random-device</command> option in
e55890
+	  <filename>named.conf</filename>, or via the <command>-r</command>
e55890
+	  command line option.  However, for functions requiring full
e55890
+	  cryptographic strength, such as DNSSEC key generation, this
e55890
+	  <emphasis>cannot</emphasis> be overridden. In particular, the
e55890
+	  <command>-r</command> command line option no longer has any
e55890
+	  effect on <command>dnssec-keygen</command>.
e55890
+	</para>
e55890
+	<para>
e55890
+	  This can be disabled by building with
e55890
+	  <command>configure --disable-crypto-rand</command>, in which
e55890
+	  case <filename>/dev/random</filename> will be the default
e55890
+	  entropy source.  [RT #31459] [RT #46047]
e55890
 	</para>
e55890
       </listitem>
e55890
     </itemizedlist>
e55890
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
e55890
index 803e7b3..29a4fef 100644
e55890
--- a/lib/dns/dst_api.c
e55890
+++ b/lib/dns/dst_api.c
e55890
@@ -276,8 +276,9 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx,
e55890
 #endif
e55890
 #if defined(OPENSSL) || defined(PKCS11CRYPTO)
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
-	if (dst_entropy_pool != NULL)
e55890
+	if (dst_entropy_pool != NULL) {
e55890
 		isc_entropy_sethook(dst_random_getdata);
e55890
+	}
e55890
 #endif
e55890
 #endif /* defined(OPENSSL) || defined(PKCS11CRYPTO) */
e55890
 	dst_initialized = ISC_TRUE;
e55890
@@ -2015,10 +2016,12 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
e55890
 	else
e55890
 		flags |= ISC_ENTROPY_BLOCKING;
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
+	/* get entropy directly from crypto provider */
e55890
 	return (dst_random_getdata(buf, len, NULL, flags));
e55890
 #else
e55890
+	/* get entropy from entropy source or hook function */
e55890
 	return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
e55890
-#endif
e55890
+#endif /* ISC_PLATFORM_CRYPTORANDOM */
e55890
 #endif /* PKCS11CRYPTO */
e55890
 }
e55890
 
e55890
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
e55890
index d9b6ab6..e8c1a3c 100644
e55890
--- a/lib/dns/include/dst/dst.h
e55890
+++ b/lib/dns/include/dst/dst.h
e55890
@@ -161,8 +161,18 @@ isc_result_t
e55890
 dst_random_getdata(void *data, unsigned int length,
e55890
 		   unsigned int *returned, unsigned int flags);
e55890
 /*%<
e55890
- * \brief Return data from the crypto random generator.
e55890
- * Specialization of isc_entropy_getdata().
e55890
+ * Gets random data from the random generator provided by the
e55890
+ * crypto library, if BIND was built with --enable-crypto-rand.
e55890
+ *
e55890
+ * See isc_entropy_getdata() for parameter usage. Normally when
e55890
+ * this function is available, it will be set up as a hook in the
e55890
+ * entropy context, so that isc_entropy_getdata() is a front-end to
e55890
+ * this function.
e55890
+ *
e55890
+ * Returns:
e55890
+ * \li	ISC_R_SUCCESS on success
e55890
+ * \li	ISC_R_NOTIMPLEMENTED if BIND is built with --disable-crypto-rand
e55890
+ * \li	DST_R_OPENSSLFAILURE, DST_R_CRYPTOFAILURE, or other codes on error
e55890
  */
e55890
 
e55890
 isc_boolean_t
e55890
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
e55890
index c1e1bde..91e87d0 100644
e55890
--- a/lib/dns/openssl_link.c
e55890
+++ b/lib/dns/openssl_link.c
e55890
@@ -482,7 +482,8 @@ dst__openssl_getengine(const char *engine) {
e55890
 
e55890
 isc_result_t
e55890
 dst_random_getdata(void *data, unsigned int length,
e55890
-		   unsigned int *returned, unsigned int flags) {
e55890
+		   unsigned int *returned, unsigned int flags)
e55890
+{
e55890
 #ifdef ISC_PLATFORM_CRYPTORANDOM
e55890
 #ifndef DONT_REQUIRE_DST_LIB_INIT
e55890
 	INSIST(dst__memory_pool != NULL);
e55890
diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h
e55890
index d9deb8a..2d37363 100644
e55890
--- a/lib/isc/include/isc/entropy.h
e55890
+++ b/lib/isc/include/isc/entropy.h
e55890
@@ -9,8 +9,6 @@
e55890
  * information regarding copyright ownership.
e55890
  */
e55890
 
e55890
-/* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */
e55890
-
e55890
 #ifndef ISC_ENTROPY_H
e55890
 #define ISC_ENTROPY_H 1
e55890
 
e55890
@@ -190,9 +188,8 @@ isc_entropy_createcallbacksource(isc_entropy_t *ent,
e55890
 /*!<
e55890
  * \brief Create an entropy source that is polled via a callback.
e55890
  *
e55890
- * This would
e55890
- * be used when keyboard input is used, or a GUI input method.  It can
e55890
- * also be used to hook in any external entropy source.
e55890
+ * This would be used when keyboard input is used, or a GUI input method.
e55890
+ * It can also be used to hook in any external entropy source.
e55890
  *
e55890
  * Samples are added via isc_entropy_addcallbacksample(), below.
e55890
  * _addcallbacksample() is the only function which may be called from
e55890
@@ -233,15 +230,32 @@ isc_result_t
e55890
 isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
e55890
 		    unsigned int *returned, unsigned int flags);
e55890
 /*!<
e55890
- * \brief Extract data from the entropy pool.  This may load the pool from various
e55890
- * sources.
e55890
+ * \brief Get random data from entropy pool 'ent'.
e55890
+ *
e55890
+ * If a hook has been set up using isc_entropy_sethook() and
e55890
+ * isc_entropy_usehook(), then the hook function will be called to get
e55890
+ * random data.
e55890
+ *
e55890
+ * Otherwise, randomness is extracted from the entropy pool set up in BIND.
e55890
+ * This may cause the pool to be loaded from various sources. Ths is done
e55890
+ * by stirring the pool and returning a part of hash as randomness.
e55890
+ * (Note that no secrets are given away here since parts of the hash are
e55890
+ * XORed together before returning.)
e55890
+ *
e55890
+ * 'flags' may contain ISC_ENTROPY_GOODONLY, ISC_ENTROPY_PARTIAL, or
e55890
+ * ISC_ENTROPY_BLOCKING. These will be honored if the hook function is
e55890
+ * not in use. If it is, the flags will be passed to the hook function
e55890
+ * but it may ignore them.
e55890
  *
e55890
- * Do this by stiring the pool and returning a part of hash as randomness.
e55890
- * Note that no secrets are given away here since parts of the hash are
e55890
- * xored together before returned.
e55890
+ * Up to 'length' bytes of randomness are retrieved and copied into 'data'.
e55890
+ * (If 'returned' is not NULL, and the number of bytes copied is less than
e55890
+ * 'length' - which may happen if ISC_ENTROPY_PARTIAL was used - then the
e55890
+ * number of bytes copied will be stored in *returned.)
e55890
  *
e55890
- * Honor the request from the caller to only return good data, any data,
e55890
- * etc.
e55890
+ * Returns:
e55890
+ * \li	ISC_R_SUCCESS on success
e55890
+ * \li	ISC_R_NOENTROPY if entropy pool is empty
e55890
+ * \li	other error codes are possible when a hook is in use
e55890
  */
e55890
 
e55890
 void
e55890
@@ -306,13 +320,21 @@ isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
e55890
 void
e55890
 isc_entropy_usehook(isc_entropy_t *ectx, isc_boolean_t onoff);
e55890
 /*!<
e55890
- * \brief Mark/unmark the given entropy structure as being hooked.
e55890
+ * \brief Configure entropy context 'ectx' to use the hook function
e55890
+ *
e55890
+ * Sets the entropy context to call the hook function for random number
e55890
+ * generation, if such a function has been configured via
e55890
+ * isc_entropy_sethook(), whenever isc_entropy_getdata() is called.
e55890
  */
e55890
 
e55890
 void
e55890
 isc_entropy_sethook(isc_entropy_getdata_t myhook);
e55890
 /*!<
e55890
- * \brief Set the getdata hook (e.g., for a crypto random generator).
e55890
+ * \brief Set the hook function.
e55890
+ *
e55890
+ * The hook function is a global value: only one hook function
e55890
+ * can be set in the system. Individual entropy contexts may be
e55890
+ * configured to use it, or not, by calling isc_entropy_usehook().
e55890
  */
e55890
 
e55890
 ISC_LANG_ENDDECLS
e55890
diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h
e55890
index ba53ebf..b575728 100644
e55890
--- a/lib/isc/include/isc/random.h
e55890
+++ b/lib/isc/include/isc/random.h
e55890
@@ -9,8 +9,6 @@
e55890
  * information regarding copyright ownership.
e55890
  */
e55890
 
e55890
-/* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */
e55890
-
e55890
 #ifndef ISC_RANDOM_H
e55890
 #define ISC_RANDOM_H 1
e55890
 
e55890
@@ -21,13 +19,23 @@
e55890
 #include <isc/mutex.h>
e55890
 
e55890
 /*! \file isc/random.h
e55890
- * \brief Implements a random state pool which will let the caller return a
e55890
- * series of possibly non-reproducible random values.
e55890
+ * \brief Implements pseudo random number generators.
e55890
+ *
e55890
+ * Two pseudo-random number generators are implemented, in isc_random_*
e55890
+ * and isc_rng_*. Neither one is very strong; they should not be used
e55890
+ * in cryptography functions.
e55890
+ *
e55890
+ * isc_random_* is based on arc4random if it is available on the system.
e55890
+ * Otherwise it is based on the posix srand() and rand() functions.
e55890
+ * It is useful for jittering values a bit here and there, such as
e55890
+ * timeouts, etc, but should not be relied upon to generate
e55890
+ * unpredictable sequences (for example, when choosing transaction IDs).
e55890
  *
e55890
- * Note that the
e55890
- * strength of these numbers is not all that high, and should not be
e55890
- * used in cryptography functions.  It is useful for jittering values
e55890
- * a bit here and there, such as timeouts, etc.
e55890
+ * isc_rng_* is based on ChaCha20, and is seeded and stirred from the
e55890
+ * system entropy source. It is stronger than isc_random_* and can
e55890
+ * be used for generating unpredictable sequences. It is still not as
e55890
+ * good as using system entropy directly (see entropy.h) and should not
e55890
+ * be used for cryptographic functions such as key generation.
e55890
  */
e55890
 
e55890
 ISC_LANG_BEGINDECLS
e55890
@@ -115,8 +123,8 @@ isc_rng_random(isc_rng_t *rngctx);
e55890
 isc_uint16_t
e55890
 isc_rng_uniformrandom(isc_rng_t *rngctx, isc_uint16_t upper_bound);
e55890
 /*%<
e55890
- * Returns a uniformly distributed pseudo random 16-bit unsigned
e55890
- * integer.
e55890
+ * Returns a uniformly distributed pseudo-random 16-bit unsigned integer
e55890
+ * less than 'upper_bound'.
e55890
  */
e55890
 
e55890
 ISC_LANG_ENDDECLS
e55890
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
e55890
index 8d496ff..dd08187 100644
e55890
--- a/lib/isccfg/namedconf.c
e55890
+++ b/lib/isccfg/namedconf.c
e55890
@@ -1106,7 +1106,7 @@ options_clauses[] = {
e55890
 	{ "pid-file", &cfg_type_qstringornone, 0 },
e55890
 	{ "port", &cfg_type_uint32, 0 },
e55890
 	{ "querylog", &cfg_type_boolean, 0 },
e55890
-	{ "random-device", &cfg_type_qstring, 0 },
e55890
+	{ "random-device", &cfg_type_qstringornone, 0 },
e55890
 	{ "recursing-file", &cfg_type_qstring, 0 },
e55890
 	{ "recursive-clients", &cfg_type_uint32, 0 },
e55890
 	{ "reserved-sockets", &cfg_type_uint32, 0 },
e55890
-- 
e55890
2.20.1
e55890