From: Evan Hunt Date: Thu, 28 Sep 2017 17:09:22 +0000 (-0700) Subject: [master] completed and corrected the crypto-random change X-Git-Tag: v9.12.0b1~124 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=24172bd2eeba91441ab1c65d2717b0692309244a;p=thirdparty%2Fbind9.git [master] 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] --- diff --git a/CHANGES b/CHANGES index 72b2a610987..df1bc116b41 100644 --- a/CHANGES +++ b/CHANGES @@ -63,15 +63,26 @@ 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] diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c index 40df5ceab76..7eb85979da4 100644 --- a/bin/confgen/keygen.c +++ b/bin/confgen/keygen.c @@ -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, diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook index 12b49a53946..afa83b5908b 100644 --- a/bin/dnssec/dnssec-keygen.docbook +++ b/bin/dnssec/dnssec-keygen.docbook @@ -347,15 +347,23 @@ -r randomdev - Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - 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. + + + If that behavior is disabled at compile time, however, + the specified file will be used as entropy source + for key generation. randomdev is the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. + data to be used. The special value keyboard + indicates that keyboard input should be used. + + + The default is /dev/random if the + operating system provides it or an equivalent device; + if not, the default source of randomness is keyboard input. diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 908a2bcd383..891765e5569 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -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); diff --git a/bin/named/config.c b/bin/named/config.c index 53271d102f7..6e20b908a13 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -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\ diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index ed99ade75b5..adc05858186 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -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, diff --git a/bin/named/server.c b/bin/named/server.c index fc17c26d7fa..18060deea61 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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); diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 883ec5d0ede..fbe77e0a11c 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -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 diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index 61a4c90d3b9..38887ea8a23 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -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 diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index ee10e0ab750..fcd6c45d460 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -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 diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index a7f014e836e..f2cd99f58e3 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -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 diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 4ef7013b9d5..516ec62ef57 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5274,22 +5274,45 @@ badresp:1,adberr:0,findfail:0,valfail:0] random-device - 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 - /dev/random - (or equivalent) when present, and none otherwise. The - random-device 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. + + + 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. + + + If random-device is not specified, or + if it is set to none, 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). + + + The random-device option takes + effect during the initial configuration load at server + startup time and is ignored on subsequent reloads. + + + If BIND is built with + configure --disable-crypto-rand, then + entropy is not sourced from the + cryptographic library. In this case, if + random-device is not specified, the + default value is the system random device, + /dev/random or the equivalent. + This default can be overridden with + configure --with-randomdev. + If no system random device exists, then no entropy source + will be configured, and named will only + be able to use pseudo-random numbers. diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 105e5b12706..5bad7a766d4 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -362,20 +362,28 @@ - When named is linked with OpenSSL, the - OpenSSL RAND routine can be used as the source of entropy/ - randomness by specifying - random-device openssl; in - named.conf. It can also be used in tools - such as dnssec-keygen, - tsig-keygen, - and nsupdate by specifying - -r openssl 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 - configure --disable-crypto-rand 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 + /dev/random. This is suitable for virtual + machine environments, which may 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, in which + case /dev/random will be the default + entropy source. [RT #31459] [RT #46047] diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 920843e3703..107215ff518 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -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 */ } diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index cacf6ca15eb..a2d4ee68f45 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -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 diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index 9f44f25c3dc..e649141dadd 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -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); diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h index a97fe5f4ce2..0793c566aeb 100644 --- a/lib/isc/include/isc/entropy.h +++ b/lib/isc/include/isc/entropy.h @@ -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 diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h index 29aa00baf87..55b488ca2e4 100644 --- a/lib/isc/include/isc/random.h +++ b/lib/isc/include/isc/random.h @@ -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 @@ -18,13 +16,23 @@ #include /*! \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 diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 15a14116480..8522860981e 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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 }, diff --git a/lib/ns/client.c b/lib/ns/client.c index 82bd216468a..d914b595aee 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -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); diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h index 0ae3263129c..32493d89ef6 100644 --- a/lib/ns/include/ns/server.h +++ b/lib/ns/include/ns/server.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index be819a7d6ee..3c0e427dad5 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/lib/ns/query.c b/lib/ns/query.c index e1ec7b6b4b0..eee578556e2 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/ns/server.c b/lib/ns/server.c index 4a149ac160b..2c5dc36251c 100644 --- a/lib/ns/server.c +++ b/lib/ns/server.c @@ -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);