]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add new default siphash24 cookie algorithm, but keep AES as legacy
authorOndřej Surý <ondrej@sury.org>
Sun, 21 Jul 2019 18:26:49 +0000 (14:26 -0400)
committerOndřej Surý <ondrej@sury.org>
Sun, 21 Jul 2019 19:16:28 +0000 (15:16 -0400)
This commit changes the BIND cookie algorithms to match
draft-sury-toorop-dnsop-server-cookies-00.  Namely, it changes the Client Cookie
algorithm to use SipHash 2-4, adds the new Server Cookie algorithm using SipHash
2-4, and changes the default for the Server Cookie algorithm to be siphash24.

Add siphash24 cookie algorithm, and make it keep legacy aes as

19 files changed:
bin/named/config.c
bin/named/named.conf.docbook
bin/named/server.c
bin/tests/system/cookie/bad-cookie-badaes.conf [moved from bin/tests/system/cookie/good-cookie-sha1.conf with 80% similarity]
bin/tests/system/cookie/bad-cookie-badsiphash24.conf [moved from bin/tests/system/cookie/bad-cookie-badsha256.conf with 81% similarity]
bin/tests/system/cookie/good-cookie-aes.conf [moved from bin/tests/system/cookie/bad-cookie-badsha1.conf with 80% similarity]
bin/tests/system/cookie/good-cookie-siphash24.conf [moved from bin/tests/system/cookie/good-cookie-sha256.conf with 78% similarity]
bin/tests/system/cookie/ns4/named.conf.in
bin/tests/system/cookie/ns5/named.conf.in
bin/tests/system/cookie/ns6/named.conf.in
bin/tests/system/cookie/tests.sh
configure
doc/misc/options
lib/bind9/check.c
lib/dns/resolver.c
lib/isc/include/isc/util.h
lib/isccfg/namedconf.c
lib/ns/client.c
lib/ns/include/ns/types.h

index cc74012e7fa649dc3701f54406f8680d6fbe3471..300a21b161b996271e68c7572841fd5dc1dad622 100644 (file)
@@ -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"
index 77d6db9a71fa62082ec2dda88a588978cbe6c6cd..61d6225e779df2b7e9105b881c537fa19bdcdc19 100644 (file)
@@ -222,7 +222,7 @@ options {
        check-srv-cname ( fail | warn | ignore );
        check-wildcard <replaceable>boolean</replaceable>;
        clients-per-query <replaceable>integer</replaceable>;
-       cookie-algorithm ( aes );
+       cookie-algorithm ( aes | siphash24 );
        cookie-secret <replaceable>string</replaceable>;
        coresize ( default | unlimited | <replaceable>sizeval</replaceable> );
        datasize ( default | unlimited | <replaceable>sizeval</replaceable> );
index d0d63806262b5ee09af6928da4cb1532ba329cbe..5691cdc489235e5bce806cfc0afac65591d3d995 100644 (file)
@@ -39,6 +39,7 @@
 #include <isc/print.h>
 #include <isc/refcount.h>
 #include <isc/resource.h>
+#include <isc/siphash.h>
 #include <isc/socket.h>
 #include <isc/stat.h>
 #include <isc/stats.h>
@@ -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;
                        }
similarity index 80%
rename from bin/tests/system/cookie/good-cookie-sha1.conf
rename to bin/tests/system/cookie/bad-cookie-badaes.conf
index 315732bfbf3ac1763d7be2fb7778bc3409350265..6c8e42cabd5db7103fcaf16cea831fd7166a4ceb 100644 (file)
@@ -10,6 +10,6 @@
  */
 
 options {
-       cookie-algorithm sha1;
-       cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f";  // 160 bits
+       cookie-algorithm aes;
+       cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa";  // 136 bits
 };
similarity index 81%
rename from bin/tests/system/cookie/bad-cookie-badsha256.conf
rename to bin/tests/system/cookie/bad-cookie-badsiphash24.conf
index 3442099a685d7863f2621021ef04be22892ea39f..392cb04473b424e52a2749119e8d32fc12064f81 100644 (file)
@@ -10,6 +10,6 @@
  */
 
 options {
-       cookie-algorithm sha256;
-       cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f";  // 160 bits
+       cookie-algorithm siphash24;
+       cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd";  // 160 bits
 };
similarity index 80%
rename from bin/tests/system/cookie/bad-cookie-badsha1.conf
rename to bin/tests/system/cookie/good-cookie-aes.conf
index f22dd49e836c49702bf07c95b21951e3ccf16870..efb56a67a4d2c714ccce0b05d1b742891e36310d 100644 (file)
@@ -10,6 +10,6 @@
  */
 
 options {
-       cookie-algorithm sha1;
-       cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272fff";  // 168 bits
+       cookie-algorithm aes;
+       cookie-secret "ebc7701beabb4a40c57d140eeb6733fa";  // 128 bits
 };
similarity index 78%
rename from bin/tests/system/cookie/good-cookie-sha256.conf
rename to bin/tests/system/cookie/good-cookie-siphash24.conf
index 2fe68f2e450efb5df28e073a8b735c0ebc4e115f..2e2f6285435ca8b8df19d11ef19ec96dae8aa237 100644 (file)
@@ -10,6 +10,6 @@
  */
 
 options {
-       cookie-algorithm sha256;
-       cookie-secret "b174e3800b6734f73268f15831c957860a8ee1229cfb9039c1514836f53efbed";
+       cookie-algorithm siphash24;
+       cookie-secret "ebc7701beabb4a40c57d140eeb6733fa";  // 128 bits
 };
index 79d1cda568c0c0834f2c2879b83ece84b94af0e2..7ed0760f174574ef62087bdabca01896eca92076 100644 (file)
@@ -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;
 };
 
index ae51a9071d73058dcec3eacc0fd8b0bb7234bdd7..7dd681b7f3a095296fc2730f0918e15a6447385c 100644 (file)
@@ -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;
 };
 
index 368d9a31927e3d577c8cddf1f62447daf45505d5..2cfd462d225719c1d44969ef30e134965d888793 100644 (file)
@@ -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;
 };
 
index 0c4d25a77ab303cfd5a0f91616098f1adef844b9..f82bb005468772f94e0f670ea30b8e2b7d15a60a 100755 (executable)
@@ -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
index 5b63b66b8f7c09f8448399374c5e5fd1e8c5590a..473f11410960024c731be5669f1c5f25ff17de0a 100755 (executable)
--- 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];
index bfba324f1f78ec8c719d3da8564470a4e3d81e7b..15638335e0014b154a1e1cb929c1d94af40443de 100644 (file)
@@ -113,7 +113,7 @@ options {
         check-wildcard <boolean>;
         cleaning-interval <integer>; // obsolete
         clients-per-query <integer>;
-        cookie-algorithm ( aes );
+        cookie-algorithm ( aes | siphash24 );
         cookie-secret <string>; // may occur multiple times
         coresize ( default | unlimited | <sizeval> );
         datasize ( default | unlimited | <sizeval> );
index 40ad91aa1669941f60aa67b16fbec3b3ebbc25d0..c984d8fd7b145d530d6d17cbc92444afde66e11e 100644 (file)
@@ -29,6 +29,7 @@
 #include <isc/print.h>
 #include <isc/region.h>
 #include <isc/result.h>
+#include <isc/siphash.h>
 #include <isc/sockaddr.h>
 #include <isc/string.h>
 #include <isc/symtab.h>
@@ -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;
                        }
index 1818ce7a8740713b36fff1c980683cefef62cfb1..878b959f8054e3a13588bbc4628db20c0a80f909 100644 (file)
 #include <isc/print.h>
 #include <isc/string.h>
 #include <isc/random.h>
+#include <isc/siphash.h>
 #include <isc/socket.h>
 #include <isc/stats.h>
 #include <isc/task.h>
 #include <isc/timer.h>
 #include <isc/util.h>
 
-#include <isc/aes.h>
-
 #include <dns/acl.h>
 #include <dns/adb.h>
 #include <dns/badcache.h>
@@ -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);
index 4dfe1d77e4aa7798e0a9bad456c5b341fcc30c01..6602aac2b37ab155b92bcbee271154711c17e825 100644 (file)
  */
 #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.
  */
index 3ee8365eb1fd28aa2acd8e27e724dd2c535358e1..4d6bbf4994a7e14a73871b4a4f96d00bce0166ec 100644 (file)
@@ -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
index b2151632b738e7896db839001508c60e0b192335..cb79448108af61ea61160d1a3912891d443bd546 100644 (file)
@@ -25,6 +25,7 @@
 #include <isc/random.h>
 #include <isc/safe.h>
 #include <isc/serial.h>
+#include <isc/siphash.h>
 #include <isc/stats.h>
 #include <isc/stdio.h>
 #include <isc/string.h>
@@ -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;
        }
index ced6b5c06ef3cb4739b404cd70789f6cb35542fd..422f1288617c6b751f439f8ac04b4c0203eb91a9 100644 (file)
@@ -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 */