]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] completed and corrected the crypto-random change
authorEvan Hunt <each@isc.org>
Thu, 28 Sep 2017 17:09:22 +0000 (10:09 -0700)
committerEvan Hunt <each@isc.org>
Thu, 28 Sep 2017 17:09:22 +0000 (10:09 -0700)
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]

24 files changed:
CHANGES
bin/confgen/keygen.c
bin/dnssec/dnssec-keygen.docbook
bin/dnssec/dnssectool.c
bin/named/config.c
bin/named/controlconf.c
bin/named/server.c
bin/nsupdate/nsupdate.c
bin/tests/system/pipelined/pipequeries.c
bin/tests/system/tkey/keycreate.c
bin/tests/system/tkey/keydelete.c
doc/arm/Bv9ARM-book.xml
doc/arm/notes.xml
lib/dns/dst_api.c
lib/dns/include/dst/dst.h
lib/dns/openssl_link.c
lib/isc/include/isc/entropy.h
lib/isc/include/isc/random.h
lib/isccfg/namedconf.c
lib/ns/client.c
lib/ns/include/ns/server.h
lib/ns/interfacemgr.c
lib/ns/query.c
lib/ns/server.c

diff --git a/CHANGES b/CHANGES
index 72b2a6109879ec7422ece9b1b9660c5532cb267b..df1bc116b41e984162520768d07ccf412ff95458 100644 (file)
--- a/CHANGES
+++ b/CHANGES
                        location to be reported is "update_completed".
                        [RT #46014]
 
-4724.  [func]          When the random device (i.e. the "random-device"
-                       option in named.conf, or the -r command line option
-                       in various tools) is set to "openssl", the OpenSSL
-                       RAND routine is used as the source of entropy/
-                       randomness. This is suitable for a virtual
-                       machine environment without a hardware random
-                       number generator. This behavior can be overridden
-                       by using "configure --disable-crypto-rand" or
-                       native PKCS#11. [RT #31459]
+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]
 
 4723.  [bug]           Statistics counter DNSTAPdropped was misidentified
                        as DNSSECdropped. [RT #46002]
index 40df5ceab76c2410497114bf8ba5a364f175475c..7eb85979da42838c0e7bc93a75308aee2d122831 100644 (file)
@@ -151,17 +151,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,
index 12b49a53946bb90400619e0b9f3589d8e7a53668..afa83b5908b93d617e5ca1c21b65d058eb3f2b94 100644 (file)
        <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>
index 908a2bcd383bcda0b3536c2a7d679bc6da63ab27..891765e55690c2475c8cfde0c83c77bfe15c818e 100644 (file)
@@ -234,18 +234,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);
 
index 53271d102f760d527e89df7c5ff5ab9e0a208a9a..6e20b908a13864600fd197e89284c45769e2ac78 100644 (file)
@@ -86,7 +86,9 @@ options {\n\
 #      pid-file \"" NAMED_LOCALSTATEDIR "/run/named/named.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\
index ed99ade75b587ad56ed043e3e60dd8a4852997b1..adc05858186d73b5a5359f07225bfb0f33c87f3d 100644 (file)
@@ -320,9 +320,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;
+       named_server_t *server = NULL;
+       controlkey_t *key = NULL;
        isccc_sexpr_t *request = NULL;
        isccc_sexpr_t *response = NULL;
        isc_uint32_t algorithm;
@@ -333,16 +334,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;
@@ -453,8 +455,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->sctx->rngctx);
+                       isc_uint16_t r2 = isc_rng_random(server->sctx->rngctx);
+                       conn->nonce = (r1 << 16) | r2;
+               }
                eresult = ISC_R_SUCCESS;
        } else
                eresult = named_control_docommand(request, listener->readonly,
index fc17c26d7fafc2d9b0082532bdb04e83928858b6..18060deea61c6c664823c1a6818dd270cca97a13 100644 (file)
@@ -8289,34 +8289,47 @@ load_configuration(const char *filename, named_server_t *server,
         * Open the source of entropy.
         */
        if (first_time) {
+               const char *randomdev = NULL;
+               int level = ISC_LOG_ERROR;
                obj = NULL;
                result = named_config_get(maps, "random-device", &obj);
-               if (result != ISC_R_SUCCESS) {
+               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
+                       isc_entropy_usehook(named_g_entropy, ISC_TRUE);
+#else
+                       if ((obj != NULL) && !cfg_obj_isvoid(obj))
+                               level = ISC_LOG_INFO;
                        isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
-                                     NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
+                                     NAMED_LOGMODULE_SERVER, level,
                                      "no source of entropy found");
+                       if ((obj == NULL) || cfg_obj_isvoid(obj)) {
+                               CHECK(ISC_R_FAILURE);
+                       }
+#endif
                } else {
-                       const char *randomdev = cfg_obj_asstring(obj);
-#ifdef ISC_PLATFORM_CRYPTORANDOM
-                       if (strcmp(randomdev, ISC_PLATFORM_CRYPTORANDOM) == 0)
-                               isc_entropy_usehook(named_g_entropy, ISC_TRUE);
-#else
-                       int level = ISC_LOG_ERROR;
                        result = isc_entropy_createfilesource(named_g_entropy,
                                                              randomdev);
 #ifdef PATH_RANDOMDEV
-                       if (named_g_fallbackentropy != NULL)
+                       if (named_g_fallbackentropy != NULL) {
                                level = ISC_LOG_INFO;
+                       }
 #endif
-                       if (result != ISC_R_SUCCESS)
+                       if (result != ISC_R_SUCCESS) {
                                isc_log_write(named_g_lctx,
                                              NAMED_LOGCATEGORY_GENERAL,
                                              NAMED_LOGMODULE_SERVER,
                                              level,
-                                             "could not open entropy source "
-                                             "%s: %s",
+                                             "could not open "
+                                             "entropy source %s: %s",
                                              randomdev,
                                              isc_result_totext(result));
+                       }
 #ifdef PATH_RANDOMDEV
                        if (named_g_fallbackentropy != NULL) {
                                if (result != ISC_R_SUCCESS) {
@@ -8334,7 +8347,6 @@ load_configuration(const char *filename, named_server_t *server,
                                }
                                isc_entropy_detach(&named_g_fallbackentropy);
                        }
-#endif
 #endif
                }
        }
@@ -13298,10 +13310,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;
@@ -13311,9 +13323,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(named_g_server->sctx->rngctx);
+       }
 
        memmove(salt, rnd.rnd, saltlen);
 
index 883ec5d0edec68a77b7e384470cd05ab59dd3d0b..fbe77e0a11c173c57b3f4c2b5aaedddd5da09867 100644 (file)
@@ -273,9 +273,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
index 61a4c90d3b99e49c7d9bebb6166e3f502fa658fc..38887ea8a23b5f5e904bede48b3d5926a6a5b047 100644 (file)
@@ -248,9 +248,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
index ee10e0ab750d63b70ce1cc1f34538bbd1331ad94..fcd6c45d460284c7cfeeb11c533b6876aeec7d6a 100644 (file)
@@ -250,9 +250,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
index a7f014e836e3986798acff139dfa26b266bc04a8..f2cd99f58e3be8466d390008ccabac0ece1eb3ee 100644 (file)
@@ -180,9 +180,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
index 4ef7013b9d56216d04713cb40470316203f79f78..516ec62ef57c642238352cfabd6c0c41b3ea98c8 100644 (file)
@@ -5274,22 +5274,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>
index 105e5b1270658201f20c39862e33dd62bd91b637..5bad7a766d4605ce27d6247c85ce6a59868d6219 100644 (file)
       </listitem>
       <listitem>
        <para>
-         When <command>named</command> is linked with OpenSSL, the
-         OpenSSL RAND routine can be used as the source of entropy/
-         randomness by specifying
-         <command>random-device openssl;</command> in
-         <filename>named.conf</filename>. It can also be used in tools
-         such as <command>dnssec-keygen</command>,
-         <command>tsig-keygen</command>,
-         and <command>nsupdate</command> by specifying
-         <command>-r openssl</command> on the command line.
-         This is suitable for a virtual machine environment without
-         a hardware random number generator.
-         This behavior can be overridden by using
-         <command>configure --disable-crypto-rand</command> or
-         building with native PKCS#11. [RT #31459]
+         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>
index 920843e370369a08f8fbe76a4df3a05577bf3191..107215ff5183f6cb255fe25b70a704d49660b5fd 100644 (file)
@@ -269,8 +269,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;
@@ -2007,10 +2008,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 */
 }
 
index cacf6ca15eb3c42b74271aaedc84cd3f19a313c2..a2d4ee68f45455a55f3e89c575eab3fdba3c44b0 100644 (file)
@@ -158,8 +158,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
index 9f44f25c3dc23c8ffc3321fbdff200b002d6483e..e649141dadd50e2b17ae431c1c4d4b7f184d8803 100644 (file)
@@ -485,7 +485,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);
index a97fe5f4ce2d9a48f4647f176d63fe38b6310805..0793c566aeb1959c3b8f8631572f85a904e8a116 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */
-
 #ifndef ISC_ENTROPY_H
 #define ISC_ENTROPY_H 1
 
@@ -187,9 +185,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
@@ -230,15 +227,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
@@ -303,13 +317,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
index 29aa00baf873fc0d5e910f492c3570b5d46791a0..55b488ca2e43e9044de7937c877cf7ab8bd54c7d 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */
-
 #ifndef ISC_RANDOM_H
 #define ISC_RANDOM_H 1
 
 #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
@@ -112,8 +120,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
index 15a141164803bd209c7f6e69cfd8880dfc95154c..8522860981ed9dd0b57c93b2350e2034cbb78999 100644 (file)
@@ -1104,7 +1104,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 },
index 82bd216468a41310918837dd3e3c9d33ebde6fe7..d914b595aeee514b40af14f38cbd0138c0e18197 100644 (file)
@@ -1638,7 +1638,9 @@ 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(client->sctx->rngctx) << 16) |
+                        isc_rng_random(client->sctx->rngctx));
 
                compute_cookie(client, now, nonce, client->sctx->secret, &buf);
 
index 0ae3263129c966277fbbb1b1d1cea796f5c57d95..32493d89ef6f9d1b4a995b9ef743131f7238e6e1 100644 (file)
@@ -15,6 +15,7 @@
 #include <isc/fuzz.h>
 #include <isc/magic.h>
 #include <isc/quota.h>
+#include <isc/random.h>
 #include <isc/sockaddr.h>
 #include <isc/types.h>
 
@@ -91,6 +92,7 @@ struct ns_server {
        isc_uint16_t            transfer_tcp_message_size;
        isc_boolean_t           interface_auto;
        dns_tkeyctx_t *         tkeyctx;
+       isc_rng_t *             rngctx;
 
        /*% Server id for NSID */
        char *                  server_id;
index be819a7d6ee49196a4e199c2035d9e8d1e87aa2c..3c0e427dad5fda21776b8932ec6e777f544b7752 100644 (file)
@@ -12,6 +12,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>
index e1ec7b6b4b09fc6341bc2af65a23fb04fe936941..eee578556e2e08251ade88741709f0d257048cfd 100644 (file)
@@ -15,6 +15,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>
index 4a149ac160b293d072edd8342bee1493f0a385ed..2c5dc36251cf944c2248fcbbd9dc8687a97b28f1 100644 (file)
@@ -53,6 +53,7 @@ ns_server_create(isc_mem_t *mctx, isc_entropy_t *entropy,
        CHECKFATAL(isc_quota_init(&sctx->recursionquota, 100));
 
        CHECKFATAL(dns_tkeyctx_create(mctx, entropy, &sctx->tkeyctx));
+       CHECKFATAL(isc_rng_create(mctx, entropy, &sctx->rngctx));
 
        CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats));
 
@@ -154,6 +155,8 @@ ns_server_detach(ns_server_t **sctxp) {
                        dns_acl_detach(&sctx->blackholeacl);
                if (sctx->keepresporder != NULL)
                        dns_acl_detach(&sctx->keepresporder);
+               if (sctx->rngctx != NULL)
+                       isc_rng_detach(&sctx->rngctx);
                if (sctx->tkeyctx != NULL)
                        dns_tkeyctx_destroy(&sctx->tkeyctx);