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