eb7207
From af3b530773231f8cff6548e36962ad1f25e38c5d 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 +
27025e
 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 +-
27025e
 bin/tests/system/tkey/keydelete.c        |  5 +--
e55890
 doc/arm/Bv9ARM-book.xml                  | 55 +++++++++++++++++-------
b9f8ff
 doc/arm/notes-rh-changes.xml             | 42 ++++++++++++++++++
27025e
 doc/arm/notes.xml                        |  1 +
27025e
 lib/dns/dst_api.c                        |  4 +-
e55890
 lib/dns/include/dst/dst.h                | 14 +++++-
e55890
 lib/dns/openssl_link.c                   |  3 +-
b9f8ff
 lib/isc/include/isc/entropy.h            | 48 +++++++++++++++------
eb7207
 lib/isc/include/isc/random.h             | 26 +++++++----
e55890
 lib/isccfg/namedconf.c                   |  2 +-
eb7207
 23 files changed, 240 insertions(+), 102 deletions(-)
27025e
 create mode 100644 doc/arm/notes-rh-changes.xml
e55890
e55890
diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c
eb7207
index bd269e7..1ac775f 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) {
27025e
 		isc_entropy_usehook(ectx, 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
eb7207
index bd19e1d..2c09b30 100644
e55890
--- a/bin/dnssec/dnssec-keygen.docbook
e55890
+++ b/bin/dnssec/dnssec-keygen.docbook
b9f8ff
@@ -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
eb7207
index 2a0f9c6..6fcd411 100644
e55890
--- a/bin/dnssec/dnssectool.c
e55890
+++ b/bin/dnssec/dnssectool.c
27025e
@@ -241,18 +241,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) {
27025e
+		isc_entropy_usehook(*ectx, 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;
27025e
-		isc_entropy_usehook(*ectx, 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
eb7207
index 4a50ad9..4d140e8 100644
e55890
--- a/bin/named/client.c
e55890
+++ b/bin/named/client.c
eb7207
@@ -1768,7 +1768,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
eb7207
index 9b343fa..5e663c6 100644
e55890
--- a/bin/named/config.c
e55890
+++ b/bin/named/config.c
27025e
@@ -98,7 +98,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
eb7207
index 9fdf49b..42128dc 100644
e55890
--- a/bin/named/controlconf.c
e55890
+++ b/bin/named/controlconf.c
eb7207
@@ -327,9 +327,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;
27025e
 	uint32_t algorithm;
eb7207
@@ -340,16 +341,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;
27025e
 	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;
eb7207
@@ -462,8 +464,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) {
27025e
+			uint16_t r1 = isc_rng_random(server->rngctx);
27025e
+			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
eb7207
index 4fd0194..0ba2627 100644
e55890
--- a/bin/named/include/named/server.h
e55890
+++ b/bin/named/include/named/server.h
27025e
@@ -20,6 +20,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>
eb7207
@@ -135,6 +136,7 @@ struct ns_server {
e55890
 	char *			lockfile;
e55890
 
27025e
 	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
eb7207
index 93aac31..e12fad9 100644
e55890
--- a/bin/named/interfacemgr.c
e55890
+++ b/bin/named/interfacemgr.c
27025e
@@ -17,6 +17,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
eb7207
index 58b5914..edf42d2 100644
e55890
--- a/bin/named/query.c
e55890
+++ b/bin/named/query.c
eb7207
@@ -20,6 +20,7 @@
e55890
 #include <isc/mem.h>
eb7207
 #include <isc/platform.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
eb7207
index b2ae57c..cca7fe8 100644
e55890
--- a/bin/named/server.c
e55890
+++ b/bin/named/server.c
eb7207
@@ -8279,21 +8279,32 @@ 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
+		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) {
27025e
+#ifdef ISC_PLATFORM_CRYPTORANDOM
27025e
+			isc_entropy_usehook(ns_g_entropy, true);
27025e
+#else
e55890
+			if ((obj != NULL) && !cfg_obj_isvoid(obj))
e55890
+				level = ISC_LOG_INFO;
27025e
 			isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
27025e
-				      NS_LOGMODULE_SERVER, ISC_LOG_INFO,
e55890
+				      NS_LOGMODULE_SERVER, level,
27025e
 				      "no source of entropy found");
e55890
+			if ((obj == NULL) || cfg_obj_isvoid(obj)) {
e55890
+				CHECK(ISC_R_FAILURE);
e55890
+			}
e55890
+#endif
27025e
 		} else {
27025e
-			const char *randomdev = cfg_obj_asstring(obj);
27025e
-#ifdef ISC_PLATFORM_CRYPTORANDOM
27025e
-			if (strcmp(randomdev, ISC_PLATFORM_CRYPTORANDOM) == 0)
27025e
-				isc_entropy_usehook(ns_g_entropy, true);
27025e
-#else
27025e
-			int level = ISC_LOG_ERROR;
27025e
 			result = isc_entropy_createfilesource(ns_g_entropy,
27025e
-							      randomdev);
27025e
+			                                      randomdev);
e55890
 #ifdef PATH_RANDOMDEV
e55890
 			if (ns_g_fallbackentropy != NULL) {
e55890
 				level = ISC_LOG_INFO;
eb7207
@@ -8304,8 +8315,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
 			}
eb7207
@@ -8325,7 +8336,6 @@ load_configuration(const char *filename, ns_server_t *server,
e55890
 				}
e55890
 				isc_entropy_detach(&ns_g_fallbackentropy);
e55890
 			}
e55890
-#endif
e55890
 #endif
e55890
 		}
27025e
 
eb7207
@@ -9097,6 +9107,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
27025e
 	server->in_roothints = NULL;
27025e
 	server->blackholeacl = NULL;
27025e
 	server->keepresporder = NULL;
27025e
+	server->rngctx = NULL;
27025e
 
27025e
 	/* Must be first. */
27025e
 	CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy,
eb7207
@@ -9123,6 +9134,9 @@ 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");
27025e
+	server->rngctx = NULL;
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
eb7207
@@ -9329,7 +9343,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
 
eb7207
@@ -13366,10 +13381,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];
27025e
-		uint32_t rnd32[64];
27025e
+		uint16_t rnd16[128];
e55890
 	} rnd;
e55890
 	unsigned char text[512 + 1];
e55890
 	isc_region_t r;
eb7207
@@ -13379,9 +13394,10 @@ generate_salt(unsigned char *salt, size_t saltlen) {
e55890
 	if (saltlen > 256U)
e55890
 		return (ISC_R_RANGE);
e55890
 
27025e
-	n = (int) (saltlen + sizeof(uint32_t) - 1) / sizeof(uint32_t);
e55890
-	for (i = 0; i < n; i++)
e55890
-		isc_random_get(&rnd.rnd32[i]);
27025e
+	n = (saltlen + sizeof(uint16_t) - 1) / sizeof(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
eb7207
index 7f15cbc..458aa76 100644
e55890
--- a/bin/nsupdate/nsupdate.c
e55890
+++ b/bin/nsupdate/nsupdate.c
eb7207
@@ -289,9 +289,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) {
27025e
 		isc_entropy_usehook(*ectx, true);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c
eb7207
index 95b65bf..7a81d4e 100644
e55890
--- a/bin/tests/system/pipelined/pipequeries.c
e55890
+++ b/bin/tests/system/pipelined/pipequeries.c
27025e
@@ -280,9 +280,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) {
27025e
 		isc_entropy_usehook(ectx, true);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
eb7207
index 3236968..4fa77b6 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) {
27025e
 		isc_entropy_usehook(ectx, true);
e55890
 	}
e55890
 #endif
e55890
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
eb7207
index 43fb6b0..105e151 100644
e55890
--- a/bin/tests/system/tkey/keydelete.c
e55890
+++ b/bin/tests/system/tkey/keydelete.c
27025e
@@ -171,6 +171,7 @@ main(int argc, char **argv) {
27025e
 		randomfile = argv[2];
27025e
 		argv += 2;
27025e
 		argc -= 2;
27025e
+		POST(argc);
27025e
 	}
27025e
 	keyname = argv[1];
27025e
 
27025e
@@ -182,9 +183,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) {
27025e
 		isc_entropy_usehook(ectx, true);
e55890
 	}
e55890
 #endif
e55890
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
eb7207
index ca98726..1f9df2c 100644
e55890
--- a/doc/arm/Bv9ARM-book.xml
e55890
+++ b/doc/arm/Bv9ARM-book.xml
eb7207
@@ -5034,22 +5034,45 @@ badresp:1,adberr:0,findfail:0,valfail:0]
e55890
 	    <term><command>random-device</command></term>
e55890
 	    <listitem>
e55890
 	      <para>
eb7207
-		This specifies a 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
eb7207
-		zones.  This option specifies the device (or file) from which
e55890
-		to read
eb7207
-		entropy.  If it is a file, operations requiring entropy will
e55890
-		fail when the
eb7207
-		file has been exhausted.  If <command>random-device</command> is 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>
27025e
diff --git a/doc/arm/notes-rh-changes.xml b/doc/arm/notes-rh-changes.xml
27025e
new file mode 100644
b9f8ff
index 0000000..89a4961
27025e
--- /dev/null
27025e
+++ b/doc/arm/notes-rh-changes.xml
b9f8ff
@@ -0,0 +1,42 @@
27025e
+
27025e
+ - Copyright (C) Internet Systems Consortium, Inc. ("ISC")
27025e
+ -
27025e
+ - This Source Code Form is subject to the terms of the Mozilla Public
27025e
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
27025e
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
27025e
+ -
27025e
+ - See the COPYRIGHT file distributed with this work for additional
27025e
+ - information regarding copyright ownership.
27025e
+-->
27025e
+
27025e
+<section xml:id="relnotes_rh_changes"><info><title>Red Hat Specific Changes</title></info>
27025e
+  <itemizedlist>
27025e
+     <listitem>
27025e
+      <para>
27025e
+        By default, BIND now uses the random number generation functions
27025e
+        in the cryptographic library (i.e., OpenSSL or a PKCS#11
27025e
+        provider) as a source of high-quality randomness rather than
27025e
+        <filename>/dev/random</filename>.  This is suitable for virtual
27025e
+        machine environments, which may have limited entropy pools and
27025e
+        lack hardware random number generators.
27025e
+      </para>
27025e
+      <para>
27025e
+        This can be overridden by specifying another entropy source via
27025e
+        the <command>random-device</command> option in
27025e
+        <filename>named.conf</filename>, or via the <command>-r</command>
27025e
+        command line option.  However, for functions requiring full
27025e
+        cryptographic strength, such as DNSSEC key generation, this
27025e
+        <emphasis>cannot</emphasis> be overridden. In particular, the
27025e
+        <command>-r</command> command line option no longer has any
27025e
+        effect on <command>dnssec-keygen</command>.
27025e
+      </para>
27025e
+      <para>
27025e
+        This can be disabled by building with
27025e
+        <command>configure --disable-crypto-rand</command>, in which
27025e
+        case <filename>/dev/random</filename> will be the default
27025e
+        entropy source.  [RT #31459] [RT #46047]
27025e
+      </para>
27025e
+    </listitem>
27025e
+  </itemizedlist>
27025e
+</section>
27025e
+
e55890
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
eb7207
index a5e42c0..f8cb1f9 100644
e55890
--- a/doc/arm/notes.xml
e55890
+++ b/doc/arm/notes.xml
eb7207
@@ -47,6 +47,7 @@
27025e
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-9.11.1.xml"/>
27025e
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-9.11.0.xml"/>
27025e
 
27025e
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-rh-changes.xml"/>
27025e
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-eol.xml"/>
27025e
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="notes-thankyou.xml"/>
27025e
 </section>
e55890
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
eb7207
index aa54afc..2156384 100644
e55890
--- a/lib/dns/dst_api.c
e55890
+++ b/lib/dns/dst_api.c
27025e
@@ -2017,10 +2017,12 @@ dst__entropy_getdata(void *buf, unsigned int len, bool 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
eb7207
index 3aba028..180c841 100644
e55890
--- a/lib/dns/include/dst/dst.h
e55890
+++ b/lib/dns/include/dst/dst.h
27025e
@@ -163,8 +163,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
 
27025e
 bool
e55890
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
eb7207
index 3f4f822..cfdc757 100644
e55890
--- a/lib/dns/openssl_link.c
e55890
+++ b/lib/dns/openssl_link.c
27025e
@@ -484,7 +484,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
eb7207
index f32c9dc..bed276b 100644
e55890
--- a/lib/isc/include/isc/entropy.h
e55890
+++ b/lib/isc/include/isc/entropy.h
b9f8ff
@@ -189,9 +189,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
b9f8ff
@@ -232,15 +231,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'.
b9f8ff
  *
b9f8ff
- * Do this by stirring the pool and returning a part of hash as randomness.
b9f8ff
- * Note that no secrets are given away here since parts of the hash are
b9f8ff
- * xored together before returned.
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.
b9f8ff
  *
b9f8ff
- * Honor the request from the caller to only return good data, any data,
b9f8ff
- * etc.
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.
b9f8ff
+ *
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.)
b9f8ff
+ *
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
b9f8ff
@@ -305,13 +321,21 @@ isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
e55890
 void
27025e
 isc_entropy_usehook(isc_entropy_t *ectx, bool 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
eb7207
index f38e80d..3cb1c56 100644
e55890
--- a/lib/isc/include/isc/random.h
e55890
+++ b/lib/isc/include/isc/random.h
eb7207
@@ -19,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.
eb7207
  *
eb7207
- * Note that the
eb7207
- * strength of these numbers is not all that high, and should not be
eb7207
- * used in cryptography functions.  It is useful for jittering values
eb7207
- * a bit here and there, such as timeouts, etc.
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).
eb7207
+  *
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
eb7207
@@ -113,8 +123,8 @@ isc_rng_random(isc_rng_t *rngctx);
27025e
 uint16_t
27025e
 isc_rng_uniformrandom(isc_rng_t *rngctx, 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
eb7207
index e74c93b..212194e 100644
e55890
--- a/lib/isccfg/namedconf.c
e55890
+++ b/lib/isccfg/namedconf.c
27025e
@@ -1109,7 +1109,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
-- 
eb7207
2.26.2
e55890