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 77d6db9a71..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 ); + 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 d0d6380626..5691cdc489 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -9129,7 +9130,9 @@ 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 { INSIST(0); @@ -9188,12 +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"); + "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/configure b/configure index 5b63b66b8f..473f114109 100755 --- a/configure +++ b/configure @@ -850,7 +850,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -1019,7 +1018,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1272,15 +1270,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1418,7 +1407,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1571,7 +1560,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -4010,7 +3998,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -4056,7 +4044,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -4080,7 +4068,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -4125,7 +4113,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -4149,7 +4137,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; diff --git a/doc/misc/options b/doc/misc/options index bfba324f1f..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 ); + 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 40ad91aa16..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,8 +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, "siphash24") == 0 && + usedlength != ISC_SIPHASH24_KEY_LENGTH) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "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 1818ce7a87..878b959f80 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -21,14 +21,13 @@ #include #include #include +#include #include #include #include #include #include -#include - #include #include #include @@ -201,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; @@ -213,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; @@ -2271,29 +2270,56 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link); } -static void -compute_cc(resquery_t *query, unsigned char *cookie, size_t len) { - unsigned char digest[ISC_AES_BLOCK_LENGTH]; - unsigned char input[16]; +static inline size_t +addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; - unsigned int i; - - INSIST(len >= 8U); - - isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); + isc_netaddr_fromsockaddr(&netaddr, sockaddr); switch (netaddr.family) { case AF_INET: - memmove(input, (unsigned char *)&netaddr.type.in, 4); - memset(input + 4, 0, 12); - break; + INSIST(bufsize >= 4); + memmove(buf, &netaddr.type.in, 4); + return (4); case AF_INET6: - memmove(input, (unsigned char *)&netaddr.type.in6, 16); - break; + INSIST(bufsize >= 16); + memmove(buf, &netaddr.type.in6, 16); + return (16); + default: + INSIST(0); + ISC_UNREACHABLE(); } - 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); + 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(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"); + + uint8_t buf[16] ISC_NONSTRING = { 0 }; + size_t buflen = add_serveraddr(buf, sizeof(buf), query); + + 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 @@ -2753,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! */ @@ -5334,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; @@ -9548,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 3ee8365eb1..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", 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 b2151632b7..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,14 +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; + default: + INSIST(0); + ISC_UNREACHABLE(); } - for (i = 0; i < 8; i++) + 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 ced6b5c06e..422f128861 100644 --- a/lib/ns/include/ns/types.h +++ b/lib/ns/include/ns/types.h @@ -27,7 +27,10 @@ typedef struct ns_server ns_server_t; typedef struct ns_stats ns_stats_t; typedef enum { - ns_cookiealg_aes + ns_cookiealg_aes, + ns_cookiealg_siphash24 } ns_cookiealg_t; +#define NS_COOKIE_VERSION_1 1 + #endif /* NS_TYPES_H */