diff --git a/CHANGES b/CHANGES index b3f5d4ad8a..035116d089 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5264. [func] New DNS Cookie algorithm - siphash24 - has been added to + BIND 9, and the old HMAC-SHA DNS Cookie algorithms have + been removed. [GL #605] + --- 9.15.2 released --- 5263. [cleanup] Use atomics and isc_refcount_t wherever possible. diff --git a/bin/named/config.c b/bin/named/config.c index cc74012e7f..300a21b161 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -50,7 +50,7 @@ options {\n\ automatic-interface-scan yes;\n\ bindkeys-file \"" NAMED_SYSCONFDIR "/bind.keys\";\n\ # blackhole {none;};\n" -" cookie-algorithm aes;\n" +" cookie-algorithm siphash24;\n" #ifndef WIN32 " coresize default;\n\ datasize default;\n" diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index f8f223eb3c..61d6225e77 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -222,7 +222,7 @@ options { check-srv-cname ( fail | warn | ignore ); check-wildcard boolean; clients-per-query integer; - cookie-algorithm ( aes | sha1 | sha256 ); + cookie-algorithm ( aes | siphash24 ); cookie-secret string; coresize ( default | unlimited | sizeval ); datasize ( default | unlimited | sizeval ); diff --git a/bin/named/server.c b/bin/named/server.c index d1ca372a4a..5691cdc489 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -9129,12 +9130,10 @@ load_configuration(const char *filename, named_server_t *server, obj = NULL; result = named_config_get(maps, "cookie-algorithm", &obj); INSIST(result == ISC_R_SUCCESS); - if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) { + if (strcasecmp(cfg_obj_asstring(obj), "siphash24") == 0) { + server->sctx->cookiealg = ns_cookiealg_siphash24; + } else if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) { server->sctx->cookiealg = ns_cookiealg_aes; - } else if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0) { - server->sctx->cookiealg = ns_cookiealg_sha1; - } else if (strcasecmp(cfg_obj_asstring(obj), "sha256") == 0) { - server->sctx->cookiealg = ns_cookiealg_sha256; } else { INSIST(0); ISC_UNREACHABLE(); @@ -9192,30 +9191,18 @@ load_configuration(const char *filename, named_server_t *server, usedlength = isc_buffer_usedlength(&b); switch (server->sctx->cookiealg) { + case ns_cookiealg_siphash24: + expectedlength = ISC_SIPHASH24_KEY_LENGTH; + if (usedlength != expectedlength) { + CHECKM(ISC_R_RANGE, + "SipHash-2-4 cookie-secret must be 128 bits"); + } + break; case ns_cookiealg_aes: expectedlength = ISC_AES128_KEYLENGTH; if (usedlength != expectedlength) { CHECKM(ISC_R_RANGE, - "AES cookie-secret must be " - "128 bits"); - } - break; - case ns_cookiealg_sha1: - expectedlength = - isc_md_type_get_size(ISC_MD_SHA1); - if (usedlength != expectedlength) { - CHECKM(ISC_R_RANGE, - "SHA1 cookie-secret must be " - "160 bits"); - } - break; - case ns_cookiealg_sha256: - expectedlength = - isc_md_type_get_size(ISC_MD_SHA256); - if (usedlength != expectedlength) { - CHECKM(ISC_R_RANGE, - "SHA256 cookie-secret must be " - "256 bits"); + "AES cookie-secret must be 128 bits"); } break; } diff --git a/bin/tests/system/cookie/good-cookie-sha1.conf b/bin/tests/system/cookie/bad-cookie-badaes.conf similarity index 80% rename from bin/tests/system/cookie/good-cookie-sha1.conf rename to bin/tests/system/cookie/bad-cookie-badaes.conf index 315732bfbf..6c8e42cabd 100644 --- a/bin/tests/system/cookie/good-cookie-sha1.conf +++ b/bin/tests/system/cookie/bad-cookie-badaes.conf @@ -10,6 +10,6 @@ */ options { - cookie-algorithm sha1; - cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits + cookie-algorithm aes; + cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa"; // 136 bits }; diff --git a/bin/tests/system/cookie/bad-cookie-badsha256.conf b/bin/tests/system/cookie/bad-cookie-badsiphash24.conf similarity index 81% rename from bin/tests/system/cookie/bad-cookie-badsha256.conf rename to bin/tests/system/cookie/bad-cookie-badsiphash24.conf index 3442099a68..392cb04473 100644 --- a/bin/tests/system/cookie/bad-cookie-badsha256.conf +++ b/bin/tests/system/cookie/bad-cookie-badsiphash24.conf @@ -10,6 +10,6 @@ */ options { - cookie-algorithm sha256; - cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits + cookie-algorithm siphash24; + cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd"; // 160 bits }; diff --git a/bin/tests/system/cookie/bad-cookie-badsha1.conf b/bin/tests/system/cookie/good-cookie-aes.conf similarity index 80% rename from bin/tests/system/cookie/bad-cookie-badsha1.conf rename to bin/tests/system/cookie/good-cookie-aes.conf index f22dd49e83..efb56a67a4 100644 --- a/bin/tests/system/cookie/bad-cookie-badsha1.conf +++ b/bin/tests/system/cookie/good-cookie-aes.conf @@ -10,6 +10,6 @@ */ options { - cookie-algorithm sha1; - cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272fff"; // 168 bits + cookie-algorithm aes; + cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits }; diff --git a/bin/tests/system/cookie/good-cookie-sha256.conf b/bin/tests/system/cookie/good-cookie-siphash24.conf similarity index 78% rename from bin/tests/system/cookie/good-cookie-sha256.conf rename to bin/tests/system/cookie/good-cookie-siphash24.conf index 2fe68f2e45..2e2f628543 100644 --- a/bin/tests/system/cookie/good-cookie-sha256.conf +++ b/bin/tests/system/cookie/good-cookie-siphash24.conf @@ -10,6 +10,6 @@ */ options { - cookie-algorithm sha256; - cookie-secret "b174e3800b6734f73268f15831c957860a8ee1229cfb9039c1514836f53efbed"; + cookie-algorithm siphash24; + cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits }; diff --git a/bin/tests/system/cookie/ns4/named.conf.in b/bin/tests/system/cookie/ns4/named.conf.in index 79d1cda568..7ed0760f17 100644 --- a/bin/tests/system/cookie/ns4/named.conf.in +++ b/bin/tests/system/cookie/ns4/named.conf.in @@ -28,8 +28,8 @@ options { listen-on-v6 { none; }; recursion yes; dnssec-validation yes; - cookie-algorithm sha1; - cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2"; + cookie-algorithm siphash24; + cookie-secret "569d36a6cc27d6bf55502183302ba352"; require-server-cookie yes; }; diff --git a/bin/tests/system/cookie/ns5/named.conf.in b/bin/tests/system/cookie/ns5/named.conf.in index ae51a9071d..7dd681b7f3 100644 --- a/bin/tests/system/cookie/ns5/named.conf.in +++ b/bin/tests/system/cookie/ns5/named.conf.in @@ -28,9 +28,9 @@ options { listen-on-v6 { none; }; recursion yes; dnssec-validation yes; - cookie-algorithm sha1; - cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2"; - cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; + cookie-algorithm siphash24; + cookie-secret "569d36a6cc27d6bf55502183302ba352"; + cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; require-server-cookie yes; }; diff --git a/bin/tests/system/cookie/ns6/named.conf.in b/bin/tests/system/cookie/ns6/named.conf.in index 368d9a3192..2cfd462d22 100644 --- a/bin/tests/system/cookie/ns6/named.conf.in +++ b/bin/tests/system/cookie/ns6/named.conf.in @@ -28,8 +28,8 @@ options { listen-on-v6 { none; }; recursion yes; dnssec-validation yes; - cookie-algorithm sha1; - cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; + cookie-algorithm siphash24; + cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; require-server-cookie yes; }; diff --git a/bin/tests/system/cookie/tests.sh b/bin/tests/system/cookie/tests.sh index 0c4d25a77a..f82bb00546 100755 --- a/bin/tests/system/cookie/tests.sh +++ b/bin/tests/system/cookie/tests.sh @@ -211,12 +211,12 @@ status=`expr $status + $ret` # # Test shared cookie-secret support. # -# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2"; +# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352"; # -# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2"; -# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; (alternate) +# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352"; +# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; (alternate) # -# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; +# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; # # Server cookies from NS4 are accepted by NS5 and not NS6 # Server cookies from NS5 are accepted by NS4 and not NS6 diff --git a/config.h.in b/config.h.in index 1f0a9f7d78..180dd00b74 100644 --- a/config.h.in +++ b/config.h.in @@ -3,9 +3,6 @@ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD -/* Use AES for Client Cookie generation */ -#undef AES_CC - /* Define if you cannot bind() before connect() for TCP sockets. */ #undef BROKEN_TCP_BIND_BEFORE_CONNECT @@ -468,12 +465,6 @@ /* Define if __thread keyword is available */ #undef HAVE___THREAD -/* Use HMAC-SHA1 for Client Cookie generation */ -#undef HMAC_SHA1_CC - -/* Use HMAC-SHA256 for Client Cookie generation */ -#undef HMAC_SHA256_CC - /* Define if you want to use inline buffers */ #undef ISC_BUFFER_USEINLINE diff --git a/config.h.win32 b/config.h.win32 index fda2009e51..05296c7b45 100644 --- a/config.h.win32 +++ b/config.h.win32 @@ -298,15 +298,6 @@ typedef __int64 off_t; /* HMAC_*() return ints */ @HMAC_RETURN_INT@ -/* Use AES for Client Cookie generation */ -@AES_CC@ - -/* Use HMAC-SHA1 for Client Cookie generation */ -@HMAC_SHA1_CC@ - -/* Use HMAC-SHA256 for Client Cookie generation */ -@HMAC_SHA256_CC@ - /* Define to 1 if you have the `readline' function. */ @HAVE_READLINE@ diff --git a/configure b/configure index 3b71dd9501..473f114109 100755 --- a/configure +++ b/configure @@ -911,7 +911,6 @@ with_libtool enable_pthread_rwlock with_openssl enable_fips_mode -with_cc_alg enable_native_pkcs11 with_pkcs11 with_gssapi @@ -1661,8 +1660,6 @@ Optional Packages: --with-locktype=ARG Specify mutex lock type (adaptive or standard) --with-libtool use GNU libtool --with-openssl=DIR root of the OpenSSL directory - --with-cc-alg=ALG choose the algorithm for Client Cookie - [aes|sha1|sha256] (default is aes) --with-pkcs11=PATH Build with PKCS11 support [no|path] (PATH is for the PKCS11 provider) --with-gssapi=PATH|/path/krb5-config @@ -16804,44 +16801,6 @@ esac -# -# Client Cookie algorithm choice -# - -# Check whether --with-cc-alg was given. -if test "${with_cc_alg+set}" = set; then : - withval=$with_cc_alg; : -else - with_cc_alg="aes" -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the algorithm for Client Cookie" >&5 -$as_echo_n "checking for the algorithm for Client Cookie... " >&6; } -case $with_cc_alg in #( - sha1|SHA1) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: sha1" >&5 -$as_echo "sha1" >&6; } - -$as_echo "#define HMAC_SHA1_CC 1" >>confdefs.h - ;; #( - sha256|SHA256) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: sha256" >&5 -$as_echo "sha256" >&6; } - -$as_echo "#define HMAC_SHA256_CC 1" >>confdefs.h - ;; #( - aes|AES|auto) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: aes" >&5 -$as_echo "aes" >&6; } - -$as_echo "#define AES_CC 1" >>confdefs.h - ;; #( - *) : - as_fn_error $? "Invalid $with_cc_alg algorithm for Client Cookie" "$LINENO" 5 ;; -esac - - PKCS11_TOOLS= PKCS11_TEST= # diff --git a/configure.ac b/configure.ac index 63e7b30160..d681f80e68 100644 --- a/configure.ac +++ b/configure.ac @@ -825,26 +825,6 @@ AX_RESTORE_FLAGS([openssl]) AC_SUBST([OPENSSL_CFLAGS]) AC_SUBST([OPENSSL_LIBS]) -# -# Client Cookie algorithm choice -# -AC_ARG_WITH([cc-alg], - [AS_HELP_STRING([--with-cc-alg=ALG], - [choose the algorithm for Client Cookie - [aes|sha1|sha256] (default is aes)])], - [:], [with_cc_alg="aes"]) - -AC_MSG_CHECKING([for the algorithm for Client Cookie]) -AS_CASE([$with_cc_alg], - [sha1|SHA1],[AC_MSG_RESULT([sha1]) - AC_DEFINE([HMAC_SHA1_CC], [1], [Use HMAC-SHA1 for Client Cookie generation])], - [sha256|SHA256],[AC_MSG_RESULT([sha256]) - AC_DEFINE([HMAC_SHA256_CC], [1], [Use HMAC-SHA256 for Client Cookie generation])], - [aes|AES|auto],[AC_MSG_RESULT([aes]) - AC_DEFINE([AES_CC], [1], [Use AES for Client Cookie generation])], - [AC_MSG_ERROR([Invalid $with_cc_alg algorithm for Client Cookie])]) - - PKCS11_TOOLS= PKCS11_TEST= # diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 4a4cfbd5e2..c82d3b0894 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -261,6 +261,22 @@ installation path as an optional argument. + + + A SipHash 2-4 based DNS Cookie (RFC 7873) algorithm has been added and + made default. Old non-default HMAC-SHA based DNS Cookie algorithms + have been removed, and only the default AES algorithm is being kept + for legacy reasons. This changes doesn't have any operational impact + in most common scenarios. + + + If you are running multiple DNS Servers (different versions of BIND 9 + or DNS server from multiple vendors) responding from the same IP + address (anycast or load-balancing scenarios), you'll have to make + sure that all the servers are configured with the same DNS Cookie + algorithm and same Server Secret for the best performance. + + diff --git a/doc/misc/options b/doc/misc/options index 61792fd7dc..15638335e0 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -113,7 +113,7 @@ options { check-wildcard ; cleaning-interval ; // obsolete clients-per-query ; - cookie-algorithm ( aes | sha1 | sha256 ); + cookie-algorithm ( aes | siphash24 ); cookie-secret ; // may occur multiple times coresize ( default | unlimited | ); datasize ( default | unlimited | ); diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 3e646077d9..c984d8fd7b 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -857,7 +858,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, dns_name_t *name; isc_buffer_t b; uint32_t lifetime = 3600; - const char *ccalg = "aes"; + const char *ccalg = "siphash24"; /* * { "name", scale, value } @@ -1350,24 +1351,14 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (strcasecmp(ccalg, "aes") == 0 && usedlength != ISC_AES128_KEYLENGTH) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "AES cookie-secret must be " - "128 bits"); + "AES cookie-secret must be 128 bits"); if (result == ISC_R_SUCCESS) result = ISC_R_RANGE; } - if (strcasecmp(ccalg, "sha1") == 0 && - usedlength != ISC_SHA1_DIGESTLENGTH) { + if (strcasecmp(ccalg, "siphash24") == 0 && + usedlength != ISC_SIPHASH24_KEY_LENGTH) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "SHA1 cookie-secret must be " - "160 bits"); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; - } - if (strcasecmp(ccalg, "sha256") == 0 && - usedlength != ISC_SHA256_DIGESTLENGTH) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "SHA256 cookie-secret must be " - "256 bits"); + "SipHash-2-4 cookie-secret must be 128 bits"); if (result == ISC_R_SUCCESS) result = ISC_R_RANGE; } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 37efaa3af6..878b959f80 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -21,18 +21,13 @@ #include #include #include +#include #include #include #include #include #include -#ifdef AES_CC -#include -#else -#include -#endif - #include #include #include @@ -205,7 +200,7 @@ typedef struct query { isc_mem_t * mctx; dns_dispatchmgr_t * dispatchmgr; dns_dispatch_t * dispatch; - bool exclusivesocket; + bool exclusivesocket; dns_adbaddrinfo_t * addrinfo; isc_socket_t * tcpsocket; isc_time_t start; @@ -217,7 +212,7 @@ typedef struct query { dns_tsigkey_t *tsigkey; isc_socketevent_t sendevent; isc_dscp_t dscp; - int ednsversion; + int ednsversion; unsigned int options; isc_sockeventattr_t attributes; unsigned int sends; @@ -2275,64 +2270,56 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link); } +static inline size_t +addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) { + isc_netaddr_t netaddr; + isc_netaddr_fromsockaddr(&netaddr, sockaddr); + switch (netaddr.family) { + case AF_INET: + INSIST(bufsize >= 4); + memmove(buf, &netaddr.type.in, 4); + return (4); + case AF_INET6: + INSIST(bufsize >= 16); + memmove(buf, &netaddr.type.in6, 16); + return (16); + default: + INSIST(0); + ISC_UNREACHABLE(); + } + return (0); +} + +static inline isc_socket_t * +query2sock(const resquery_t *query) { + if (query->exclusivesocket) { + return (dns_dispatch_getentrysocket(query->dispentry)); + } else { + return (dns_dispatch_getsocket(query->dispatch)); + } +} + +static inline size_t +add_serveraddr(uint8_t *buf, const size_t bufsize, const resquery_t *query) +{ + return (addr2buf(buf, bufsize, &query->addrinfo->sockaddr)); +} + +#define CLIENT_COOKIE_SIZE 8U + static void -compute_cc(resquery_t *query, unsigned char *cookie, size_t len) { -#ifdef AES_CC - unsigned char digest[ISC_AES_BLOCK_LENGTH]; - unsigned char input[16]; - isc_netaddr_t netaddr; - unsigned int i; +compute_cc(const resquery_t *query, uint8_t *cookie, const size_t len) { + INSIST(len >= CLIENT_COOKIE_SIZE); + STATIC_ASSERT(sizeof(query->fctx->res->view->secret) + >= ISC_SIPHASH24_KEY_LENGTH, + "The view->secret size can't fit SipHash 2-4 key length"); - INSIST(len >= 8U); + uint8_t buf[16] ISC_NONSTRING = { 0 }; + size_t buflen = add_serveraddr(buf, sizeof(buf), query); - isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); - switch (netaddr.family) { - case AF_INET: - memmove(input, (unsigned char *)&netaddr.type.in, 4); - memset(input + 4, 0, 12); - break; - case AF_INET6: - memmove(input, (unsigned char *)&netaddr.type.in6, 16); - break; - } - isc_aes128_crypt(query->fctx->res->view->secret, input, digest); - for (i = 0; i < 8; i++) - digest[i] ^= digest[i + 8]; - memmove(cookie, digest, 8); -#endif -#if defined(HMAC_SHA1_CC) || defined(HMAC_SHA256_CC) - unsigned char digest[ISC_MAX_MD_SIZE]; - unsigned char *input = NULL; - unsigned int length = 0; - isc_netaddr_t netaddr; -#if defined(HMAC_SHA1_CC) - isc_md_type_t type = ISC_MD_SHA1; - unsigned int secret_len = ISC_SHA1_DIGESTLENGTH; -#elif defined(HMAC_SHA256_CC) - isc_md_type_t type = ISC_MD_SHA256; - unsigned int secret_len = ISC_SHA256_DIGESTLENGTH; -#endif - - INSIST(len >= 8U); - - isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); - switch (netaddr.family) { - case AF_INET: - input = (unsigned char *)&netaddr.type.in; - length = 4; - break; - case AF_INET6: - input = (unsigned char *)&netaddr.type.in6; - length = 16; - break; - } - - RUNTIME_CHECK(isc_hmac(type, - query->fctx->res->view->secret, secret_len, - input, length, - digest, NULL) == ISC_R_SUCCESS); - memmove(cookie, digest, 8); -#endif + uint8_t digest[ISC_SIPHASH24_TAG_LENGTH] ISC_NONSTRING = { 0 }; + isc_siphash24(query->fctx->res->view->secret, buf, buflen, digest); + memmove(cookie, digest, CLIENT_COOKIE_SIZE); } static isc_result_t @@ -2792,10 +2779,8 @@ resquery_send(resquery_t *query) { */ dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); - if (query->exclusivesocket) - sock = dns_dispatch_getentrysocket(query->dispentry); - else - sock = dns_dispatch_getsocket(query->dispatch); + sock = query2sock(query); + /* * Send the query! */ @@ -5373,9 +5358,9 @@ validated(isc_task_t *task, isc_event_t *event) { REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE); valarg = event->ev_arg; fctx = valarg->fctx; + REQUIRE(VALID_FCTX(fctx)); res = fctx->res; addrinfo = valarg->addrinfo; - REQUIRE(VALID_FCTX(fctx)); REQUIRE(!ISC_LIST_EMPTY(fctx->validators)); vevent = (dns_validatorevent_t *)event; @@ -9587,11 +9572,7 @@ rctx_logpacket(respctx_t *rctx) { dtmsgtype = DNS_DTTYPE_RR; } - if (rctx->query->exclusivesocket) { - sock = dns_dispatch_getentrysocket(rctx->query->dispentry); - } else { - sock = dns_dispatch_getsocket(rctx->query->dispatch); - } + sock = query2sock(rctx->query); if (sock != NULL) { result = isc_socket_getsockname(sock, &localaddr); diff --git a/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h index 4dfe1d77e4..6602aac2b3 100644 --- a/lib/isc/include/isc/util.h +++ b/lib/isc/include/isc/util.h @@ -42,6 +42,12 @@ */ #define UNUSED(x) (void)(x) +#if __GNUC__ >= 8 && !defined(__clang__) +#define ISC_NONSTRING __attribute__((nonstring)) +#else +#define ISC_NONSTRING +#endif /* __GNUC__ */ + /*% * The opposite: silent warnings about stored values which are never read. */ diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index bffdce6114..4d6bbf4994 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -899,7 +899,7 @@ static cfg_type_t cfg_type_bracketed_portlist = { &cfg_rep_list, &cfg_type_portrange }; -static const char *cookiealg_enums[] = { "aes", "sha1", "sha256", NULL }; +static const char *cookiealg_enums[] = { "aes", "siphash24", NULL }; static cfg_type_t cfg_type_cookiealg = { "cookiealg", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &cookiealg_enums diff --git a/lib/ns/client.c b/lib/ns/client.c index dd054422e5..cb79448108 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1919,23 +1920,63 @@ static void compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce, const unsigned char *secret, isc_buffer_t *buf) { + unsigned char digest[ISC_MAX_MD_SIZE] ISC_NONSTRING = { 0 };; + STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_SIPHASH24_TAG_LENGTH, + "You need to increase the digest buffer."); + STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_AES_BLOCK_LENGTH, + "You need to increase the digest buffer."); + switch (client->sctx->cookiealg) { + case ns_cookiealg_siphash24: { + unsigned char input[16 + 16] ISC_NONSTRING = { 0 }; + size_t inputlen = 0; + isc_netaddr_t netaddr; + unsigned char *cp; + + cp = isc_buffer_used(buf); + isc_buffer_putmem(buf, client->cookie, 8); + isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1); + isc_buffer_putuint24(buf, 0); /* Reserved */ + isc_buffer_putuint32(buf, when); + + memmove(input, cp, 16); + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + switch (netaddr.family) { + case AF_INET: + cp = (unsigned char *)&netaddr.type.in; + memmove(input + 16, cp, 4); + inputlen = 20; + break; + case AF_INET6: + cp = (unsigned char *)&netaddr.type.in6; + memmove(input + 16, cp, 16); + inputlen = 32; + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } + + isc_siphash24(secret, input, inputlen, digest); + isc_buffer_putmem(buf, digest, 8); + break; + } case ns_cookiealg_aes: { - unsigned char digest[ISC_AES_BLOCK_LENGTH]; - unsigned char input[4 + 4 + 16]; + unsigned char input[4 + 4 + 16] ISC_NONSTRING = { 0 }; isc_netaddr_t netaddr; unsigned char *cp; unsigned int i; - memset(input, 0, sizeof(input)); cp = isc_buffer_used(buf); isc_buffer_putmem(buf, client->cookie, 8); isc_buffer_putuint32(buf, nonce); isc_buffer_putuint32(buf, when); memmove(input, cp, 16); isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { input[i] = digest[i] ^ digest[i + 8]; + } isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); switch (netaddr.family) { case AF_INET: @@ -1948,61 +1989,19 @@ compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce, cp = (unsigned char *)&netaddr.type.in6; memmove(input + 8, cp, 16); isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { input[i + 8] = digest[i] ^ digest[i + 8]; + } isc_aes128_crypt(client->sctx->secret, input + 8, digest); break; - } - for (i = 0; i < 8; i++) - digest[i] ^= digest[i + 8]; - isc_buffer_putmem(buf, digest, 8); - break; - } - - case ns_cookiealg_sha1: - case ns_cookiealg_sha256: { - unsigned char digest[ISC_MAX_MD_SIZE]; - unsigned char input[8 + 4 + 4 + 16]; - isc_netaddr_t netaddr; - unsigned char *cp; - unsigned int length = 0; - isc_md_type_t md_type = - (client->sctx->cookiealg == ns_cookiealg_sha1) - ? ISC_MD_SHA1 - : ISC_MD_SHA256; - unsigned int secret_len = isc_md_type_get_size(md_type); - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - memmove(input, cp, 16); - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - memmove(input + 16, - (unsigned char *)&netaddr.type.in, 4); - length = 16 + 4; - break; - case AF_INET6: - memmove(input + 16, - (unsigned char *)&netaddr.type.in6, 16); - length = 16 + 16; - break; default: INSIST(0); ISC_UNREACHABLE(); } - - /* - * XXXOND: Feels wrong to assert on cookie calculation failure - */ - RUNTIME_CHECK(isc_hmac(md_type, secret, secret_len, - input, length, - digest, NULL) == ISC_R_SUCCESS); - + for (i = 0; i < 8; i++) { + digest[i] ^= digest[i + 8]; + } isc_buffer_putmem(buf, digest, 8); break; } diff --git a/lib/ns/include/ns/types.h b/lib/ns/include/ns/types.h index 0c70332966..422f128861 100644 --- a/lib/ns/include/ns/types.h +++ b/lib/ns/include/ns/types.h @@ -28,8 +28,9 @@ typedef struct ns_stats ns_stats_t; typedef enum { ns_cookiealg_aes, - ns_cookiealg_sha1, - ns_cookiealg_sha256 + ns_cookiealg_siphash24 } ns_cookiealg_t; +#define NS_COOKIE_VERSION_1 1 + #endif /* NS_TYPES_H */ diff --git a/win32utils/Configure b/win32utils/Configure index aee6ee7f0b..8c9dc228f3 100644 --- a/win32utils/Configure +++ b/win32utils/Configure @@ -192,8 +192,7 @@ my @projectlist = ("..\\bin\\check\\win32\\checkconf.vcxproj", my %configdefh; -my @substdefh = ("AES_CC", - "CONFIGARGS", +my @substdefh = ("CONFIGARGS", "DNS_RDATASET_FIXED", "HAVE_GEOIP2", "HAVE_LIBXML2", @@ -209,8 +208,6 @@ my @substdefh = ("AES_CC", "HAVE_PKCS11_ED448", "HAVE_READLINE", "HAVE_ZLIB", - "HMAC_SHA1_CC", - "HMAC_SHA256_CC", "ISC_LIST_CHECKINIT", "TUNE_LARGE", "WANT_QUERYTRACE", @@ -1599,18 +1596,6 @@ if ($use_openssl eq "no") { } } -# with-cc-alg -if ($cookie_algorithm eq "aes") { - $configdefh{"AES_CC"} = 1; -} -if ($cookie_algorithm eq "sha1") { - $configdefh{"HMAC_SHA1_CC"} = 1; -} elsif ($cookie_algorithm eq "sha256") { - $configdefh{"HMAC_SHA256_CC"} = 1; -} elsif ($cookie_algorithm ne "aes") { - die "Unrecognized cookie algorithm: $cookie_algorithm\n"; -} - if ($cryptolib ne "") { print "Cryptographic library for DNSSEC: $cryptolib\n"; } else {