Merge branch '605-add-siphash24-wpk' into 'master'

Synchronize the Cookie algorithm to SipHash-2-4 with other open-source DNS vendors

Closes #605

See merge request isc-projects/bind9!1788
This commit is contained in:
Ondřej Surý 2019-07-21 15:30:30 -04:00
commit 51ec6f6500
25 changed files with 175 additions and 284 deletions

View file

@ -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.

View 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"

View 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 | sha1 | sha256 );
cookie-algorithm ( aes | siphash24 );
cookie-secret <replaceable>string</replaceable>;
coresize ( default | unlimited | <replaceable>sizeval</replaceable> );
datasize ( default | unlimited | <replaceable>sizeval</replaceable> );

View 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,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;
}

View file

@ -10,6 +10,6 @@
*/
options {
cookie-algorithm sha1;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits
cookie-algorithm aes;
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa"; // 136 bits
};

View file

@ -10,6 +10,6 @@
*/
options {
cookie-algorithm sha256;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits
cookie-algorithm siphash24;
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd"; // 160 bits
};

View file

@ -10,6 +10,6 @@
*/
options {
cookie-algorithm sha1;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272fff"; // 168 bits
cookie-algorithm aes;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
};

View file

@ -10,6 +10,6 @@
*/
options {
cookie-algorithm sha256;
cookie-secret "b174e3800b6734f73268f15831c957860a8ee1229cfb9039c1514836f53efbed";
cookie-algorithm siphash24;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
};

View 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;
};

View 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;
};

View 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;
};

View file

@ -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

View file

@ -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

View file

@ -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@

41
configure vendored
View file

@ -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=
#

View file

@ -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=
#

View file

@ -261,6 +261,22 @@
installation path as an optional argument.
</para>
</listitem>
<listitem>
<para>
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.
</para>
<para>
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.
</para>
</listitem>
</itemizedlist>
</section>

View file

@ -113,7 +113,7 @@ options {
check-wildcard <boolean>;
cleaning-interval <integer>; // obsolete
clients-per-query <integer>;
cookie-algorithm ( aes | sha1 | sha256 );
cookie-algorithm ( aes | siphash24 );
cookie-secret <string>; // may occur multiple times
coresize ( default | unlimited | <sizeval> );
datasize ( default | unlimited | <sizeval> );

View 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,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;
}

View file

@ -21,18 +21,13 @@
#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>
#ifdef AES_CC
#include <isc/aes.h>
#else
#include <isc/hmac.h>
#endif
#include <dns/acl.h>
#include <dns/adb.h>
#include <dns/badcache.h>
@ -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);

View file

@ -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.
*/

View 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", "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

View 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,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;
}

View file

@ -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 */

View file

@ -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 {