Commit 196b342b authored by Ondřej Surý's avatar Ondřej Surý
Browse files

Add new default siphash24 cookie algorithm

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.  The change doesn't make the SipHash 2-4 to be the default algorithm, this
is up to the operator.
parent 496397eb
......@@ -221,7 +221,7 @@ options {
check-wildcard <replaceable>boolean</replaceable>;
cleaning-interval <replaceable>integer</replaceable>;
clients-per-query <replaceable>integer</replaceable>;
cookie-algorithm ( aes | sha1 | sha256 );
cookie-algorithm ( aes | sha1 | sha256 | siphash24 );
cookie-secret <replaceable>string</replaceable>;
coresize ( default | unlimited | <replaceable>sizeval</replaceable> );
datasize ( default | unlimited | <replaceable>sizeval</replaceable> );
......
......@@ -41,6 +41,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>
......@@ -9150,7 +9151,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 if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0) {
server->sctx->cookiealg = ns_cookiealg_sha1;
......@@ -9213,12 +9216,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;
case ns_cookiealg_sha1:
......
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
cookie-algorithm aes;
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa"; // 136 bits
};
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
cookie-algorithm siphash24;
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd"; // 160 bits
};
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
cookie-algorithm aes;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
};
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
cookie-algorithm siphash24;
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
};
......@@ -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;
};
......
......@@ -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;
};
......
......@@ -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;
};
......
......@@ -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
......
......@@ -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
......@@ -477,12 +474,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
......
......@@ -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@
......
......@@ -1644,8 +1644,7 @@ 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-cc-alg=ALG deprecated
--with-pkcs11=PATH Build with PKCS11 support [no|path] (PATH is for the
PKCS11 provider)
--with-gssapi=PATH|/path/krb5-config
......@@ -16348,36 +16347,18 @@ LDFLAGS="$save_LDFLAGS"
if test "${with_cc_alg+set}" = set; then :
withval=$with_cc_alg; :
else
with_cc_alg="aes"
with_cc_alg="siphash24"
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
;; #(
siphash24) :
: ;; #(
*) :
as_fn_error $? "Invalid $with_cc_alg algorithm for Client Cookie" "$LINENO" 5 ;;
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The Client Cookie is always SipHash 2-4 based" >&5
$as_echo "$as_me: WARNING: The Client Cookie is always SipHash 2-4 based" >&2;} ;;
esac
 
PKCS11_TOOLS=
PKCS11_TEST=
#
......
......@@ -917,21 +917,12 @@ AC_SUBST([OPENSSL_LDFLAGS])
# 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"])
[AS_HELP_STRING([--with-cc-alg=ALG], [deprecated])],
[:], [with_cc_alg="siphash24"])
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])])
[siphash24],[:],
[AC_MSG_WARN([The Client Cookie is always SipHash 2-4 based])])
PKCS11_TOOLS=
PKCS11_TEST=
......
......@@ -107,7 +107,7 @@ options {
check-wildcard <boolean>;
cleaning-interval <integer>;
clients-per-query <integer>;
cookie-algorithm ( aes | sha1 | sha256 );
cookie-algorithm ( aes | sha1 | sha256 | siphash24 );
cookie-secret <string>; // may occur multiple times
coresize ( default | unlimited | <sizeval> );
datasize ( default | unlimited | <sizeval> );
......
......@@ -31,6 +31,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>
......@@ -859,7 +860,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 }
......@@ -1353,8 +1354,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;
}
......
......@@ -23,18 +23,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>
......@@ -207,7 +202,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;
......@@ -219,7 +214,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,64 +2266,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) {
#ifdef AES_CC
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);
#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);
return (0);
}
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;
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));
}
}
RUNTIME_CHECK(isc_hmac(type,
query->fctx->res->view->secret, secret_len,
input, length,
digest, NULL) == ISC_R_SUCCESS);
memmove(cookie, digest, 8);
#endif
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
......@@ -2788,10 +2775,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!
*/
......@@ -5360,9 +5345,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);
......
......@@ -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.
*/
......
......@@ -896,7 +896,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", "sha1", "sha256", "siphash24", NULL };
static cfg_type_t cfg_type_cookiealg = {
"cookiealg", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
&cfg_rep_string, &cookiealg_enums
......
......@@ -27,6 +27,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>
......@@ -1921,23 +1922,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:
......@@ -1950,21 +1991,25 @@ 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;
}
case ns_cookiealg_sha1:
case ns_cookiealg_sha256: {