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 {