]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add generic hashed message authentication code API (isc_hmac) to replace specific...
authorOndřej Surý <ondrej@sury.org>
Tue, 20 Mar 2018 17:20:50 +0000 (17:20 +0000)
committerOndřej Surý <ondrej@sury.org>
Thu, 25 Oct 2018 06:15:42 +0000 (08:15 +0200)
28 files changed:
bin/named/server.c
bin/tests/optional/Makefile.in
bin/tests/optional/hash_test.c [deleted file]
lib/dns/dst_api.c
lib/dns/dst_internal.h
lib/dns/hmac_link.c
lib/dns/pkcs11rsa_link.c
lib/dns/resolver.c
lib/isc/Makefile.in
lib/isc/hmac.c [new file with mode: 0644]
lib/isc/hmacmd5.c [deleted file]
lib/isc/hmacsha.c [deleted file]
lib/isc/include/isc/Makefile.in
lib/isc/include/isc/hmac.h [new file with mode: 0644]
lib/isc/include/isc/hmacmd5.h [deleted file]
lib/isc/include/isc/hmacsha.h [deleted file]
lib/isc/openssl_shim.c
lib/isc/openssl_shim.h
lib/isc/tests/Kyuafile
lib/isc/tests/Makefile.in
lib/isc/tests/hash_test.c
lib/isc/tests/hmac_test.c [new file with mode: 0644]
lib/isc/win32/libisc.def.in
lib/isc/win32/libisc.vcxproj.filters.in
lib/isc/win32/libisc.vcxproj.in
lib/isccc/cc.c
lib/ns/client.c
util/copyrights

index 58b8b4678a5d7451a61d45faa8f8a02b7b961d13..c1839f98fe2c7189780ca2d9f105cd1dfe171026 100644 (file)
@@ -30,7 +30,7 @@
 #include <isc/file.h>
 #include <isc/hash.h>
 #include <isc/hex.h>
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
 #include <isc/httpd.h>
 #include <isc/lex.h>
 #include <isc/meminfo.h>
index 8e3e4f32487ac46009627d5929e15f21de3e19a7..856899f81a1dddbfeab83e04e7e85ba1d2631842 100644 (file)
@@ -49,7 +49,6 @@ XTARGETS =    adb_test@EXEEXT@ \
                db_test@EXEEXT@ \
                dst_test@EXEEXT@ \
                gsstest@EXEEXT@ \
-               hash_test@EXEEXT@ \
                fsaccess_test@EXEEXT@ \
                inter_test@EXEEXT@ \
                lex_test@EXEEXT@ \
@@ -78,7 +77,6 @@ XSRCS =               adb_test.c \
                byname_test.c \
                db_test.c \
                dst_test.c \
-               hash_test.c \
                fsaccess_test.c \
                gsstest.c \
                inter_test.c \
@@ -167,10 +165,6 @@ name_test@EXEEXT@: name_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
        ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ name_test.@O@ \
                ${DNSLIBS} ${ISCLIBS} ${LIBS}
 
-hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS}
-       ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ hash_test.@O@ \
-               ${ISCLIBS} ${LIBS}
-
 entropy_test@EXEEXT@: entropy_test.@O@ ${ISCDEPLIBS}
        ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ entropy_test.@O@ \
                ${ISCLIBS} ${LIBS}
diff --git a/bin/tests/optional/hash_test.c b/bin/tests/optional/hash_test.c
deleted file mode 100644 (file)
index 64a0839..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file */
-#include <config.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
-#include <isc/util.h>
-#include <isc/print.h>
-#include <isc/string.h>
-
-#include <pk11/site.h>
-
-static void
-print_digest(const char *s, const char *hash, unsigned char *d,
-            unsigned int words)
-{
-       unsigned int i, j;
-
-       printf("hash (%s) %s:\n\t", hash, s);
-       for (i = 0; i < words; i++) {
-               printf(" ");
-               for (j = 0; j < 4; j++)
-                       printf("%02x", d[i * 4 + j]);
-       }
-       printf("\n");
-}
-
-int
-main(int argc, char **argv) {
-       isc_hmacmd5_t hmacmd5;
-       isc_hmacsha1_t hmacsha1;
-       isc_hmacsha224_t hmacsha224;
-       isc_hmacsha256_t hmacsha256;
-       isc_hmacsha384_t hmacsha384;
-       isc_hmacsha512_t hmacsha512;
-       unsigned char digest[ISC_MAX_MD_SIZE];
-       unsigned char buffer[1024];
-       const char *s;
-       unsigned char key[20];
-
-       UNUSED(argc);
-       UNUSED(argv);
-
-       /*
-        * The 3 HMAC-MD5 examples from RFC2104
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 16);
-       isc_hmacmd5_init(&hmacmd5, key, 16);
-       memmove(buffer, s, strlen(s));
-       isc_hmacmd5_update(&hmacmd5, buffer, strlen(s));
-       isc_hmacmd5_sign(&hmacmd5, digest);
-       print_digest(s, "hmacmd5", digest, 4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacmd5_init(&hmacmd5, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacmd5_update(&hmacmd5, buffer, strlen(s));
-       isc_hmacmd5_sign(&hmacmd5, digest);
-       print_digest(s, "hmacmd5", digest, 4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 16);
-       isc_hmacmd5_init(&hmacmd5, key, 16);
-       memmove(buffer, s, strlen(s));
-       isc_hmacmd5_update(&hmacmd5, buffer, strlen(s));
-       isc_hmacmd5_sign(&hmacmd5, digest);
-       print_digest(s, "hmacmd5", digest, 4);
-
-       /*
-        * The 3 HMAC-SHA1 examples from RFC4634.
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 20);
-       isc_hmacsha1_init(&hmacsha1, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha1_update(&hmacsha1, buffer, strlen(s));
-       isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH);
-       print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacsha1_init(&hmacsha1, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha1_update(&hmacsha1, buffer, strlen(s));
-       isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH);
-       print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 20);
-       isc_hmacsha1_init(&hmacsha1, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha1_update(&hmacsha1, buffer, strlen(s));
-       isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH);
-       print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4);
-
-       /*
-        * The 3 HMAC-SHA224 examples from RFC4634.
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 20);
-       isc_hmacsha224_init(&hmacsha224, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha224_update(&hmacsha224, buffer, strlen(s));
-       isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH);
-       print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacsha224_init(&hmacsha224, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha224_update(&hmacsha224, buffer, strlen(s));
-       isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH);
-       print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 20);
-       isc_hmacsha224_init(&hmacsha224, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha224_update(&hmacsha224, buffer, strlen(s));
-       isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH);
-       print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4);
-
-       /*
-        * The 3 HMAC-SHA256 examples from RFC4634.
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 20);
-       isc_hmacsha256_init(&hmacsha256, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha256_update(&hmacsha256, buffer, strlen(s));
-       isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH);
-       print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacsha256_init(&hmacsha256, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha256_update(&hmacsha256, buffer, strlen(s));
-       isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH);
-       print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 20);
-       isc_hmacsha256_init(&hmacsha256, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha256_update(&hmacsha256, buffer, strlen(s));
-       isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH);
-       print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4);
-
-       /*
-        * The 3 HMAC-SHA384 examples from RFC4634.
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 20);
-       isc_hmacsha384_init(&hmacsha384, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha384_update(&hmacsha384, buffer, strlen(s));
-       isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH);
-       print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacsha384_init(&hmacsha384, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha384_update(&hmacsha384, buffer, strlen(s));
-       isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH);
-       print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 20);
-       isc_hmacsha384_init(&hmacsha384, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha384_update(&hmacsha384, buffer, strlen(s));
-       isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH);
-       print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4);
-
-       /*
-        * The 3 HMAC-SHA512 examples from RFC4634.
-        */
-       s = "Hi There";
-       memset(key, 0x0b, 20);
-       isc_hmacsha512_init(&hmacsha512, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha512_update(&hmacsha512, buffer, strlen(s));
-       isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH);
-       print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4);
-
-       s = "what do ya want for nothing?";
-       strlcpy((char *)key, "Jefe", sizeof(key));
-       isc_hmacsha512_init(&hmacsha512, key, 4);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha512_update(&hmacsha512, buffer, strlen(s));
-       isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH);
-       print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4);
-
-       s = "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335"
-           "\335\335\335\335\335\335\335\335\335\335";
-       memset(key, 0xaa, 20);
-       isc_hmacsha512_init(&hmacsha512, key, 20);
-       memmove(buffer, s, strlen(s));
-       isc_hmacsha512_update(&hmacsha512, buffer, strlen(s));
-       isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH);
-       print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4);
-
-       return (0);
-}
index 82b619fdaab63b80bcfeed35dc42673ebef9e2a2..c30269447cf484be336c594c62560e76ba805a52 100644 (file)
@@ -35,7 +35,6 @@
 #include <isc/buffer.h>
 #include <isc/dir.h>
 #include <isc/fsaccess.h>
-#include <isc/hmacsha.h>
 #include <isc/lex.h>
 #include <isc/mem.h>
 #include <isc/once.h>
index b8ef410128794ab12c02914cd594291261889086..f2d95f172304d9d244928220dbdedd7e6b0cd9c9 100644 (file)
@@ -38,8 +38,7 @@
 #include <isc/types.h>
 #include <isc/refcount.h>
 #include <isc/stdtime.h>
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
 
 #if USE_PKCS11
 #include <pk11/pk11.h>
@@ -72,12 +71,7 @@ LIBDNS_EXTERNAL_DATA extern isc_mem_t *dst__memory_pool;
 
 typedef struct dst_func dst_func_t;
 
-typedef struct dst_hmacmd5_key   dst_hmacmd5_key_t;
-typedef struct dst_hmacsha1_key   dst_hmacsha1_key_t;
-typedef struct dst_hmacsha224_key dst_hmacsha224_key_t;
-typedef struct dst_hmacsha256_key dst_hmacsha256_key_t;
-typedef struct dst_hmacsha384_key dst_hmacsha384_key_t;
-typedef struct dst_hmacsha512_key dst_hmacsha512_key_t;
+typedef struct dst_hmac_key      dst_hmac_key_t;
 
 /*%
  * Indicate whether a DST context will be used for signing
@@ -113,13 +107,7 @@ struct dst_key {
 #if USE_PKCS11
                pk11_object_t *pkey;
 #endif
-               dst_hmacmd5_key_t *hmacmd5;
-               dst_hmacsha1_key_t *hmacsha1;
-               dst_hmacsha224_key_t *hmacsha224;
-               dst_hmacsha256_key_t *hmacsha256;
-               dst_hmacsha384_key_t *hmacsha384;
-               dst_hmacsha512_key_t *hmacsha512;
-
+               dst_hmac_key_t *hmac_key;
        } keydata;                      /*%< pointer to key in crypto pkg fmt */
 
        isc_stdtime_t   times[DST_MAX_TIMES + 1];    /*%< timing metadata */
@@ -146,12 +134,7 @@ struct dst_context {
        union {
                void *generic;
                dst_gssapi_signverifyctx_t *gssctx;
-               isc_hmacmd5_t *hmacmd5ctx;
-               isc_hmacsha1_t *hmacsha1ctx;
-               isc_hmacsha224_t *hmacsha224ctx;
-               isc_hmacsha256_t *hmacsha256ctx;
-               isc_hmacsha384_t *hmacsha384ctx;
-               isc_hmacsha512_t *hmacsha512ctx;
+               isc_hmac_t *hmac_ctx;
                EVP_MD_CTX *evp_md_ctx;
 #if USE_PKCS11
                pk11_context_t *pk11_ctx;
index 80fb179a08f0cc3c4de4aa7804d560e769668ed2..d4222cc67d877b72593422414f93138fce8d38b0 100644 (file)
 #include <config.h>
 
 #include <stdbool.h>
+#include <arpa/inet.h>
 
 #include <isc/buffer.h>
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
+#include <isc/md.h>
 #include <isc/nonce.h>
 #include <isc/random.h>
-#include <isc/md.h>
 #include <isc/mem.h>
 #include <isc/safe.h>
 #include <isc/string.h>
 #endif
 #include "dst_parse.h"
 
-static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
+#define ISC_MD_md5    ISC_MD_MD5
+#define ISC_MD_sha1   ISC_MD_SHA1
+#define ISC_MD_sha224 ISC_MD_SHA224
+#define ISC_MD_sha256 ISC_MD_SHA256
+#define ISC_MD_sha384 ISC_MD_SHA384
+#define ISC_MD_sha512 ISC_MD_SHA512
+
+#define hmac_register_algorithm(alg)                                   \
+       static isc_result_t                                     \
+       hmac##alg##_createctx(dst_key_t *key,                           \
+                             dst_context_t *dctx) {                    \
+               return (hmac_createctx(ISC_MD_##alg, key, dctx));       \
+       }                                                               \
+       static void                                             \
+       hmac##alg##_destroyctx(dst_context_t *dctx) {                   \
+               hmac_destroyctx(dctx);                                  \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_adddata(dst_context_t *dctx,                        \
+                           const isc_region_t *data) {                 \
+               return (hmac_adddata(dctx, data));                      \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_sign(dst_context_t *dctx,                           \
+                        isc_buffer_t *sig) {                           \
+               return (hmac_sign(dctx, sig));                          \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_verify(dst_context_t *dctx,                         \
+                          const isc_region_t *sig) {                   \
+               return (hmac_verify(dctx, sig));                        \
+       }                                                               \
+       static bool                                             \
+       hmac##alg##_compare(const dst_key_t *key1,                      \
+                           const dst_key_t *key2) {                    \
+               return (hmac_compare(ISC_MD_##alg, key1, key2));        \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_generate(dst_key_t *key,                            \
+                            int pseudorandom_ok,                       \
+                            void (*callback)(int)) {                   \
+               UNUSED(pseudorandom_ok);                                \
+               UNUSED(callback);                                       \
+               return (hmac_generate(ISC_MD_##alg, key));              \
+       }                                                               \
+       static bool                                             \
+       hmac##alg##_isprivate(const dst_key_t *key) {                   \
+               return (hmac_isprivate(key));                           \
+       }                                                               \
+       static void                                             \
+       hmac##alg##_destroy(dst_key_t *key) {                           \
+               hmac_destroy(key);                                      \
+       }                                                               \
+       static isc_result_t                                             \
+       hmac##alg##_todns(const dst_key_t *key, isc_buffer_t *data) {   \
+               return (hmac_todns(key, data));                         \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_fromdns(dst_key_t *key, isc_buffer_t *data) {       \
+               return (hmac_fromdns(ISC_MD_##alg, key, data));         \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_tofile(const dst_key_t *key, const char *directory) { \
+               return (hmac_tofile(ISC_MD_##alg, key, directory));     \
+       }                                                               \
+       static isc_result_t                                     \
+       hmac##alg##_parse(dst_key_t *key, isc_lex_t *lexer,             \
+                         dst_key_t *pub) {                             \
+               return(hmac_parse(ISC_MD_##alg, key, lexer, pub));      \
+       }                                                               \
+       static dst_func_t hmac##alg##_functions = {                     \
+               hmac##alg##_createctx,                                  \
+               NULL, /*%< createctx2 */                                \
+               hmac##alg##_destroyctx,                                 \
+               hmac##alg##_adddata,                                    \
+               hmac##alg##_sign,                                       \
+               hmac##alg##_verify,                                     \
+               NULL, /*%< verify2 */                                   \
+               NULL, /*%< computesecret */                             \
+               hmac##alg##_compare,                                    \
+               NULL, /*%< paramcompare */                              \
+               hmac##alg##_generate,                                   \
+               hmac##alg##_isprivate,                                  \
+               hmac##alg##_destroy,                                    \
+               hmac##alg##_todns,                                      \
+               hmac##alg##_fromdns,                                    \
+               hmac##alg##_tofile,                                     \
+               hmac##alg##_parse,                                      \
+               NULL, /*%< cleanup */                                   \
+               NULL, /*%< fromlabel */                                 \
+               NULL, /*%< dump */                                      \
+               NULL, /*%< restore */                                   \
+       };                                                              \
+       isc_result_t                                                    \
+       dst__hmac##alg##_init(dst_func_t **funcp) {                     \
+               REQUIRE(funcp != NULL);                                 \
+               if (*funcp == NULL) {                                   \
+                       *funcp = &hmac##alg##_functions;                \
+               }                                                       \
+               return (ISC_R_SUCCESS);                                 \
+       }
+
+static isc_result_t
+hmac_fromdns(isc_md_type_t type, dst_key_t *key, isc_buffer_t *data);
 
-struct dst_hmacmd5_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
+struct dst_hmac_key  {
+       uint8_t key[ISC_MAX_BLOCK_SIZE];
 };
 
-static isc_result_t
+static inline isc_result_t
 getkeybits(dst_key_t *key, struct dst_private_element *element) {
+       uint16_t *bits = (uint16_t *)element->data;
 
-       if (element->length != 2)
+       if (element->length != 2) {
                return (DST_R_INVALIDPRIVATEKEY);
-
-       key->key_bits = (element->data[0] << 8) + element->data[1];
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacmd5_t *hmacmd5ctx;
-       dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
-
-       hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
-       if (hmacmd5ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_MD5_BLOCK_LENGTH);
-       dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
-       return (ISC_R_SUCCESS);
-}
-
-static void
-hmacmd5_destroyctx(dst_context_t *dctx) {
-       isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
-       if (hmacmd5ctx != NULL) {
-               isc_hmacmd5_invalidate(hmacmd5ctx);
-               isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
-               dctx->ctxdata.hmacmd5ctx = NULL;
        }
-}
-
-static isc_result_t
-hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
-       isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
-       return (ISC_R_SUCCESS);
-}
 
-static isc_result_t
-hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-       unsigned char *digest;
-
-       if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacmd5_sign(hmacmd5ctx, digest);
-       isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
+       key->key_bits = ntohs(*bits);
 
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
-       if (sig->length > ISC_MD5_DIGESTLENGTH)
-               return (DST_R_VERIFYFAILURE);
-
-       if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
-}
-
-static bool
-hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacmd5_key_t *hkey1, *hkey2;
-
-       hkey1 = key1->keydata.hmacmd5;
-       hkey2 = key2->keydata.hmacmd5;
-
-       if (hkey1 == NULL && hkey2 == NULL)
-               return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
-               return (false);
-
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_MD5_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
-}
-
-static isc_result_t
-hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
+static inline isc_result_t
+hmac_createctx(isc_md_type_t type, const dst_key_t *key,
+              dst_context_t *dctx)
 {
-       isc_buffer_t b;
-       isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_MD5_BLOCK_LENGTH];
-
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
-
-       bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_MD5_BLOCK_LENGTH) {
-               bytes = ISC_MD5_BLOCK_LENGTH;
-               key->key_size = ISC_MD5_BLOCK_LENGTH * 8;
+       isc_result_t result;
+       const dst_hmac_key_t *hkey = key->keydata.hmac_key;
+       isc_hmac_t *ctx = isc_hmac_new(); /* Either returns or abort()s */
+
+       result = isc_hmac_init(ctx, hkey->key,
+                              isc_md_type_get_block_size(type), type);
+       if (result != ISC_R_SUCCESS) {
+               return (DST_R_UNSUPPORTEDALG);
        }
 
-       memset(data, 0, ISC_MD5_BLOCK_LENGTH);
-       isc_nonce_buf(data, bytes);
-
-       isc_buffer_init(&b, data, bytes);
-       isc_buffer_add(&b, bytes);
-       ret = hmacmd5_fromdns(key, &b);
-       isc_safe_memwipe(data, sizeof(data));
-
-       return (ret);
-}
-
-static bool
-hmacmd5_isprivate(const dst_key_t *key) {
-       UNUSED(key);
-       return (true);
-}
-
-static void
-hmacmd5_destroy(dst_key_t *key) {
-       dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
-
-       isc_safe_memwipe(hkey, sizeof(*hkey));
-       isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacmd5 = NULL;
-}
-
-static isc_result_t
-hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacmd5_key_t *hkey;
-       unsigned int bytes;
-
-       REQUIRE(key->keydata.hmacmd5 != NULL);
-
-       hkey = key->keydata.hmacmd5;
-
-       bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
-               return (ISC_R_NOSPACE);
-       isc_buffer_putmem(data, hkey->key, bytes);
-
+       dctx->ctxdata.hmac_ctx = ctx;
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacmd5_key_t *hkey;
-       unsigned int keylen;
-       isc_region_t r;
-       isc_result_t res;
+static inline void
+hmac_destroyctx(dst_context_t *dctx) {
+       isc_hmac_t *ctx = dctx->ctxdata.hmac_ctx;
+       REQUIRE(ctx != NULL);
 
-       isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
-               return (ISC_R_SUCCESS);
+       isc_hmac_free(ctx);
+       dctx->ctxdata.hmac_ctx = NULL;
+}
 
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
-       if (hkey == NULL)
-               return (ISC_R_NOMEMORY);
+static inline isc_result_t
+hmac_adddata(const dst_context_t *dctx, const isc_region_t *data) {
+       isc_result_t result;
+       isc_hmac_t *ctx = dctx->ctxdata.hmac_ctx;
 
-       memset(hkey->key, 0, sizeof(hkey->key));
+       REQUIRE(ctx != NULL);
 
-       if (r.length > ISC_MD5_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_MD5, r.base, r.length,
-                            hkey->key, &keylen);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
-               }
-       } else {
-               memmove(hkey->key, r.base, r.length);
-               keylen = r.length;
+       result = isc_hmac_update(ctx, data->base, data->length);
+       if (result != ISC_R_SUCCESS) {
+               return (DST_R_OPENSSLFAILURE);
        }
 
-       key->key_size = keylen * 8;
-       key->keydata.hmacmd5 = hkey;
-
-       isc_buffer_forward(data, r.length);
-
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacmd5_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacmd5_key_t *hkey;
-       dst_private_t priv;
-       int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
-
-       if (key->keydata.hmacmd5 == NULL)
-               return (DST_R_NULLKEY);
-
-       if (key->external)
-               return (DST_R_EXTERNALKEY);
-
-       hkey = key->keydata.hmacmd5;
-
-       priv.elements[cnt].tag = TAG_HMACMD5_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
-
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACMD5_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
-
-       priv.nelements = cnt;
-       return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
-       dst_private_t priv;
-       isc_result_t result, tresult;
-       isc_buffer_t b;
-       isc_mem_t *mctx = key->mctx;
-       unsigned int i;
-
-       UNUSED(pub);
-       /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx,
-                                      &priv);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       if (key->external)
-               result = DST_R_EXTERNALKEY;
+static inline isc_result_t
+hmac_sign(const dst_context_t *dctx, isc_buffer_t *sig) {
+       isc_hmac_t *ctx = dctx->ctxdata.hmac_ctx;
+       REQUIRE(ctx != NULL);
+       unsigned int digestlen;
+       unsigned char digest[ISC_MAX_MD_SIZE];
 
-       key->key_bits = 0;
-       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
-               switch (priv.elements[i].tag) {
-               case TAG_HMACMD5_KEY:
-                       isc_buffer_init(&b, priv.elements[i].data,
-                                       priv.elements[i].length);
-                       isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacmd5_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               case TAG_HMACMD5_BITS:
-                       tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               default:
-                       result = DST_R_INVALIDPRIVATEKEY;
-                       break;
-               }
+       if (isc_hmac_final(ctx, digest, &digestlen) != ISC_R_SUCCESS) {
+               return (DST_R_OPENSSLFAILURE);
        }
-       dst__privstruct_free(&priv, mctx);
-       isc_safe_memwipe(&priv, sizeof(priv));
-       return (result);
-}
-
-static dst_func_t hmacmd5_functions = {
-       hmacmd5_createctx,
-       NULL, /*%< createctx2 */
-       hmacmd5_destroyctx,
-       hmacmd5_adddata,
-       hmacmd5_sign,
-       hmacmd5_verify,
-       NULL, /*%< verify2 */
-       NULL, /*%< computesecret */
-       hmacmd5_compare,
-       NULL, /*%< paramcompare */
-       hmacmd5_generate,
-       hmacmd5_isprivate,
-       hmacmd5_destroy,
-       hmacmd5_todns,
-       hmacmd5_fromdns,
-       hmacmd5_tofile,
-       hmacmd5_parse,
-       NULL, /*%< cleanup */
-       NULL, /*%< fromlabel */
-       NULL, /*%< dump */
-       NULL, /*%< restore */
-};
 
-isc_result_t
-dst__hmacmd5_init(dst_func_t **funcp) {
-#ifdef HAVE_FIPS_MODE
-       /*
-        * Problems from OpenSSL are likely from FIPS mode
-        */
-       int fips_mode = FIPS_mode();
-
-       if (fips_mode != 0) {
-               UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                "FIPS mode is %d: MD5 is only supported "
-                                "if the value is 0.\n"
-                                "Please disable either FIPS mode or MD5.",
-                                fips_mode);
+       if (isc_hmac_reset(ctx) != ISC_R_SUCCESS) {
+               return (DST_R_OPENSSLFAILURE);
        }
-#endif
-
-       /*
-        * Prevent use of incorrect crypto
-        */
-
-       RUNTIME_CHECK(isc_hmacmd5_check(0));
-
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacmd5_functions;
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha1_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
-};
-
-static isc_result_t
-hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacsha1_t *hmacsha1ctx;
-       dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
-
-       hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
-       if (hmacsha1ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
-       dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
-       return (ISC_R_SUCCESS);
-}
 
-static void
-hmacsha1_destroyctx(dst_context_t *dctx) {
-       isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
-
-       if (hmacsha1ctx != NULL) {
-               isc_hmacsha1_invalidate(hmacsha1ctx);
-               isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
-               dctx->ctxdata.hmacsha1ctx = NULL;
+       if (isc_buffer_availablelength(sig) < digestlen) {
+               return (ISC_R_NOSPACE);
        }
-}
 
-static isc_result_t
-hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
+       isc_buffer_putmem(sig, digest, digestlen);
 
-       isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
-       unsigned char *digest;
+static inline isc_result_t
+hmac_verify(const dst_context_t *dctx, const isc_region_t *sig) {
+       isc_hmac_t *ctx = dctx->ctxdata.hmac_ctx;
+       unsigned int digestlen;
+       unsigned char digest[ISC_MAX_MD_SIZE];
 
-       if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
-       isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
+       REQUIRE(ctx != NULL);
 
-       return (ISC_R_SUCCESS);
-}
+       if (isc_hmac_final(ctx, digest, &digestlen) != ISC_R_SUCCESS) {
+               return (DST_R_OPENSSLFAILURE);
+       }
 
-static isc_result_t
-hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
+       if (isc_hmac_reset(ctx) != ISC_R_SUCCESS) {
+               return (DST_R_OPENSSLFAILURE);
+       }
 
-       if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
+       if (sig->length > digestlen) {
                return (DST_R_VERIFYFAILURE);
+       }
 
-       if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
+       return (isc_safe_memequal(digest, sig->base, sig->length) ?
+               ISC_R_SUCCESS :
+               DST_R_VERIFYFAILURE);
 }
 
-static bool
-hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacsha1_key_t *hkey1, *hkey2;
+static inline bool
+hmac_compare(isc_md_type_t type, const dst_key_t *key1, const dst_key_t *key2) {
+       dst_hmac_key_t *hkey1, *hkey2;
 
-       hkey1 = key1->keydata.hmacsha1;
-       hkey2 = key2->keydata.hmacsha1;
+       hkey1 = key1->keydata.hmac_key;
+       hkey2 = key2->keydata.hmac_key;
 
-       if (hkey1 == NULL && hkey2 == NULL)
+       if (hkey1 == NULL && hkey2 == NULL) {
                return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
+       } else if (hkey1 == NULL || hkey2 == NULL) {
                return (false);
+       }
 
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
+       return (isc_safe_memequal(hkey1->key, hkey2->key,
+                                 isc_md_type_get_block_size(type)));
 }
 
-static isc_result_t
-hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
-{
+static inline isc_result_t
+hmac_generate(isc_md_type_t type, dst_key_t *key) {
        isc_buffer_t b;
        isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_SHA1_BLOCK_LENGTH];
+       unsigned int bytes, len;
+       unsigned char data[ISC_MAX_MD_SIZE] = { 0 };
 
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
+       len = isc_md_type_get_block_size(type);
 
        bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA1_BLOCK_LENGTH) {
-               bytes = ISC_SHA1_BLOCK_LENGTH;
-               key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
+
+       if (bytes > len) {
+               bytes = len;
+               key->key_size = len * 8;
        }
 
-       memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
        isc_nonce_buf(data, bytes);
 
        isc_buffer_init(&b, data, bytes);
        isc_buffer_add(&b, bytes);
-       ret = hmacsha1_fromdns(key, &b);
+
+       ret = hmac_fromdns(type, key, &b);
+
        isc_safe_memwipe(data, sizeof(data));
 
        return (ret);
 }
 
-static bool
-hmacsha1_isprivate(const dst_key_t *key) {
+static inline bool
+hmac_isprivate(const dst_key_t *key) {
        UNUSED(key);
        return (true);
 }
 
-static void
-hmacsha1_destroy(dst_key_t *key) {
-       dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
-
+static inline void
+hmac_destroy(dst_key_t *key) {
+       dst_hmac_key_t *hkey = key->keydata.hmac_key;
        isc_safe_memwipe(hkey, sizeof(*hkey));
        isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacsha1 = NULL;
+       key->keydata.hmac_key = NULL;
 }
 
-static isc_result_t
-hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha1_key_t *hkey;
+static inline isc_result_t
+hmac_todns(const dst_key_t *key, isc_buffer_t *data) {
+       dst_hmac_key_t *hkey = key->keydata.hmac_key;
        unsigned int bytes;
 
-       REQUIRE(key->keydata.hmacsha1 != NULL);
-
-       hkey = key->keydata.hmacsha1;
+       REQUIRE(hkey != NULL);
 
        bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
+       if (isc_buffer_availablelength(data) < bytes) {
                return (ISC_R_NOSPACE);
+       }
        isc_buffer_putmem(data, hkey->key, bytes);
 
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha1_key_t *hkey;
+static inline isc_result_t
+hmac_fromdns(isc_md_type_t type, dst_key_t *key, isc_buffer_t *data) {
+       dst_hmac_key_t *hkey;
        unsigned int keylen;
        isc_region_t r;
-       isc_result_t res;
 
        isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
+       if (r.length == 0) {
                return (ISC_R_SUCCESS);
+       }
 
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
-       if (hkey == NULL)
+       hkey = isc_mem_get(key->mctx, sizeof(dst_hmac_key_t));
+       if (hkey == NULL) {
                return (ISC_R_NOMEMORY);
+       }
 
        memset(hkey->key, 0, sizeof(hkey->key));
 
-       if (r.length > ISC_SHA1_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_SHA1, r.base, r.length,
-                            hkey->key, &keylen);
-               REQUIRE(res != ISC_R_SUCCESS);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
+       /* Hash the key if the key is longer then chosen MD block size */
+       if (r.length > (unsigned int)isc_md_type_get_block_size(type)) {
+               if (isc_md(type, r.base, r.length, hkey->key, &keylen)
+                   != ISC_R_SUCCESS) {
+                       return (DST_R_OPENSSLFAILURE);
                }
        } else {
                memmove(hkey->key, r.base, r.length);
@@ -538,45 +366,106 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
        }
 
        key->key_size = keylen * 8;
-       key->keydata.hmacsha1 = hkey;
+       key->keydata.hmac_key = hkey;
 
        isc_buffer_forward(data, r.length);
 
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-hmacsha1_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacsha1_key_t *hkey;
+static inline int
+hmac__get_tag_key(isc_md_type_t type) {
+       if (type == ISC_MD_MD5) {
+               return (TAG_HMACMD5_KEY);
+       } else if (type == ISC_MD_SHA1) {
+               return (TAG_HMACSHA1_KEY);
+       } else if (type == ISC_MD_SHA224) {
+               return (TAG_HMACSHA224_KEY);
+       } else if (type == ISC_MD_SHA256) {
+               return (TAG_HMACSHA256_KEY);
+       } else if (type == ISC_MD_SHA384) {
+               return (TAG_HMACSHA384_KEY);
+       } else if (type == ISC_MD_SHA512) {
+               return (TAG_HMACSHA512_KEY);
+       } else {
+               INSIST(0);
+       }
+}
+
+static inline int
+hmac__get_tag_bits(isc_md_type_t type) {
+       if (type == ISC_MD_MD5) {
+               return (TAG_HMACMD5_BITS);
+       } else if (type == ISC_MD_SHA1) {
+               return (TAG_HMACSHA1_BITS);
+       } else if (type == ISC_MD_SHA224) {
+               return (TAG_HMACSHA224_BITS);
+       } else if (type == ISC_MD_SHA256) {
+               return (TAG_HMACSHA256_BITS);
+       } else if (type == ISC_MD_SHA384) {
+               return (TAG_HMACSHA384_BITS);
+       } else if (type == ISC_MD_SHA512) {
+               return (TAG_HMACSHA512_BITS);
+       } else {
+               INSIST(0);
+       }
+}
+
+static inline isc_result_t
+hmac_tofile(isc_md_type_t type, const dst_key_t *key, const char *directory) {
+       dst_hmac_key_t *hkey;
        dst_private_t priv;
        int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
+       uint16_t bits;
 
-       if (key->keydata.hmacsha1 == NULL)
+       if (key->keydata.hmac_key == NULL) {
                return (DST_R_NULLKEY);
+       }
 
-       if (key->external)
+       if (key->external) {
                return (DST_R_EXTERNALKEY);
+       }
+
+       hkey = key->keydata.hmac_key;
 
-       hkey = key->keydata.hmacsha1;
+       priv.elements[0].tag = hmac__get_tag_key(type);
+       priv.elements[0].length = bytes;
+       priv.elements[0].data = hkey->key;
 
-       priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
+       bits = htons(key->key_bits);
 
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
+       priv.elements[1].tag = hmac__get_tag_bits(type);
+       priv.elements[1].length = sizeof(bits);
+       priv.elements[1].data = (uint8_t *)&bits;
+
+       priv.nelements = 2;
 
-       priv.nelements = cnt;
        return (dst__privstruct_writefile(key, &priv, directory));
 }
 
-static isc_result_t
-hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
+static inline int
+hmac__to_dst_alg(isc_md_type_t type) {
+       if (type == ISC_MD_MD5) {
+               return (DST_ALG_HMACMD5);
+       } else if (type == ISC_MD_SHA1) {
+               return (DST_ALG_HMACSHA1);
+       } else if (type == ISC_MD_SHA224) {
+               return (DST_ALG_HMACSHA224);
+       } else if (type == ISC_MD_SHA256) {
+               return (DST_ALG_HMACSHA256);
+       } else if (type == ISC_MD_SHA384) {
+               return (DST_ALG_HMACSHA384);
+       } else if (type == ISC_MD_SHA512) {
+               return (DST_ALG_HMACSHA512);
+       } else {
+               INSIST(0);
+       }
+}
+
+static inline isc_result_t
+hmac_parse(isc_md_type_t type, dst_key_t *key,
+          isc_lex_t *lexer, dst_key_t *pub)
+{
        dst_private_t priv;
        isc_result_t result, tresult;
        isc_buffer_t b;
@@ -585,29 +474,43 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
 
        UNUSED(pub);
        /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
+       result = dst__privstruct_parse(key, hmac__to_dst_alg(type), lexer, mctx,
                                       &priv);
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                return (result);
+       }
 
-       if (key->external)
+       if (key->external) {
                result = DST_R_EXTERNALKEY;
+       }
 
        key->key_bits = 0;
        for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
+               case TAG_HMACMD5_KEY:
                case TAG_HMACSHA1_KEY:
+               case TAG_HMACSHA224_KEY:
+               case TAG_HMACSHA256_KEY:
+               case TAG_HMACSHA384_KEY:
+               case TAG_HMACSHA512_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
                                        priv.elements[i].length);
                        isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacsha1_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
+                       tresult = hmac_fromdns(type, key, &b);
+                       if (tresult != ISC_R_SUCCESS) {
                                result = tresult;
+                       }
                        break;
+               case TAG_HMACMD5_BITS:
                case TAG_HMACSHA1_BITS:
+               case TAG_HMACSHA224_BITS:
+               case TAG_HMACSHA256_BITS:
+               case TAG_HMACSHA384_BITS:
+               case TAG_HMACSHA512_BITS:
                        tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
+                       if (tresult != ISC_R_SUCCESS) {
                                result = tresult;
+                       }
                        break;
                default:
                        result = DST_R_INVALIDPRIVATEKEY;
@@ -619,1185 +522,11 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        return (result);
 }
 
-static dst_func_t hmacsha1_functions = {
-       hmacsha1_createctx,
-       NULL, /*%< createctx2 */
-       hmacsha1_destroyctx,
-       hmacsha1_adddata,
-       hmacsha1_sign,
-       hmacsha1_verify,
-       NULL, /* verify2 */
-       NULL, /* computesecret */
-       hmacsha1_compare,
-       NULL, /* paramcompare */
-       hmacsha1_generate,
-       hmacsha1_isprivate,
-       hmacsha1_destroy,
-       hmacsha1_todns,
-       hmacsha1_fromdns,
-       hmacsha1_tofile,
-       hmacsha1_parse,
-       NULL, /* cleanup */
-       NULL, /* fromlabel */
-       NULL, /* dump */
-       NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha1_init(dst_func_t **funcp) {
-       /*
-        * Prevent use of incorrect crypto
-        */
-       RUNTIME_CHECK(isc_hmacsha1_check(0));
-
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacsha1_functions;
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha224_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
-};
-
-static isc_result_t
-hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacsha224_t *hmacsha224ctx;
-       dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
-
-       hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
-       if (hmacsha224ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH);
-       dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
-       return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha224_destroyctx(dst_context_t *dctx) {
-       isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
-       if (hmacsha224ctx != NULL) {
-               isc_hmacsha224_invalidate(hmacsha224ctx);
-               isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
-               dctx->ctxdata.hmacsha224ctx = NULL;
-       }
-}
-
-static isc_result_t
-hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
-       isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-       unsigned char *digest;
-
-       if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
-       isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
-       if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
-               return (DST_R_VERIFYFAILURE);
-
-       if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
-}
-
-static bool
-hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacsha224_key_t *hkey1, *hkey2;
-
-       hkey1 = key1->keydata.hmacsha224;
-       hkey2 = key2->keydata.hmacsha224;
-
-       if (hkey1 == NULL && hkey2 == NULL)
-               return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
-               return (false);
-
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
-}
-
-static isc_result_t
-hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
-{
-       isc_buffer_t b;
-       isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_SHA224_BLOCK_LENGTH];
-
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
-
-       bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA224_BLOCK_LENGTH) {
-               bytes = ISC_SHA224_BLOCK_LENGTH;
-               key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
-       }
-
-       memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
-       isc_nonce_buf(data, bytes);
-
-       isc_buffer_init(&b, data, bytes);
-       isc_buffer_add(&b, bytes);
-       ret = hmacsha224_fromdns(key, &b);
-       isc_safe_memwipe(data, sizeof(data));
-
-       return (ret);
-}
-
-static bool
-hmacsha224_isprivate(const dst_key_t *key) {
-       UNUSED(key);
-       return (true);
-}
-
-static void
-hmacsha224_destroy(dst_key_t *key) {
-       dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
-
-       isc_safe_memwipe(hkey, sizeof(*hkey));
-       isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacsha224 = NULL;
-}
-
-static isc_result_t
-hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha224_key_t *hkey;
-       unsigned int bytes;
-
-       REQUIRE(key->keydata.hmacsha224 != NULL);
-
-       hkey = key->keydata.hmacsha224;
-
-       bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
-               return (ISC_R_NOSPACE);
-       isc_buffer_putmem(data, hkey->key, bytes);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha224_key_t *hkey;
-       unsigned int keylen;
-       isc_region_t r;
-       isc_result_t res;
-
-       isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
-               return (ISC_R_SUCCESS);
-
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
-       if (hkey == NULL)
-               return (ISC_R_NOMEMORY);
-
-       memset(hkey->key, 0, sizeof(hkey->key));
-
-       if (r.length > ISC_SHA224_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_SHA224, r.base, r.length,
-                            hkey->key, &keylen);
-               REQUIRE(res != ISC_R_SUCCESS);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
-               }
-       } else {
-               memmove(hkey->key, r.base, r.length);
-               keylen = r.length;
-       }
-
-       key->key_size = keylen * 8;
-       key->keydata.hmacsha224 = hkey;
-
-       isc_buffer_forward(data, r.length);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacsha224_key_t *hkey;
-       dst_private_t priv;
-       int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
-
-       if (key->keydata.hmacsha224 == NULL)
-               return (DST_R_NULLKEY);
-
-       if (key->external)
-               return (DST_R_EXTERNALKEY);
-
-       hkey = key->keydata.hmacsha224;
-
-       priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
-
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
-
-       priv.nelements = cnt;
-       return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
-       dst_private_t priv;
-       isc_result_t result, tresult;
-       isc_buffer_t b;
-       isc_mem_t *mctx = key->mctx;
-       unsigned int i;
-
-       UNUSED(pub);
-       /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
-                                      &priv);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       if (key->external)
-               result = DST_R_EXTERNALKEY;
-
-       key->key_bits = 0;
-       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
-               switch (priv.elements[i].tag) {
-               case TAG_HMACSHA224_KEY:
-                       isc_buffer_init(&b, priv.elements[i].data,
-                                       priv.elements[i].length);
-                       isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacsha224_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               case TAG_HMACSHA224_BITS:
-                       tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               default:
-                       result = DST_R_INVALIDPRIVATEKEY;
-                       break;
-               }
-       }
-       dst__privstruct_free(&priv, mctx);
-       isc_safe_memwipe(&priv, sizeof(priv));
-       return (result);
-}
-
-static dst_func_t hmacsha224_functions = {
-       hmacsha224_createctx,
-       NULL, /*%< createctx2 */
-       hmacsha224_destroyctx,
-       hmacsha224_adddata,
-       hmacsha224_sign,
-       hmacsha224_verify,
-       NULL, /* verify2 */
-       NULL, /* computesecret */
-       hmacsha224_compare,
-       NULL, /* paramcompare */
-       hmacsha224_generate,
-       hmacsha224_isprivate,
-       hmacsha224_destroy,
-       hmacsha224_todns,
-       hmacsha224_fromdns,
-       hmacsha224_tofile,
-       hmacsha224_parse,
-       NULL, /* cleanup */
-       NULL, /* fromlabel */
-       NULL, /* dump */
-       NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha224_init(dst_func_t **funcp) {
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacsha224_functions;
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha256_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
-};
-
-static isc_result_t
-hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacsha256_t *hmacsha256ctx;
-       dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
-
-       hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
-       if (hmacsha256ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH);
-       dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
-       return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha256_destroyctx(dst_context_t *dctx) {
-       isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
-       if (hmacsha256ctx != NULL) {
-               isc_hmacsha256_invalidate(hmacsha256ctx);
-               isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
-               dctx->ctxdata.hmacsha256ctx = NULL;
-       }
-}
-
-static isc_result_t
-hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
-       isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-       unsigned char *digest;
-
-       if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
-       isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
-       if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
-               return (DST_R_VERIFYFAILURE);
-
-       if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
-}
-
-static bool
-hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacsha256_key_t *hkey1, *hkey2;
-
-       hkey1 = key1->keydata.hmacsha256;
-       hkey2 = key2->keydata.hmacsha256;
-
-       if (hkey1 == NULL && hkey2 == NULL)
-               return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
-               return (false);
-
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
-}
-
-static isc_result_t
-hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
-{
-       isc_buffer_t b;
-       isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_SHA256_BLOCK_LENGTH];
-
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
-
-       bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA256_BLOCK_LENGTH) {
-               bytes = ISC_SHA256_BLOCK_LENGTH;
-               key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
-       }
-
-       memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
-       isc_nonce_buf(data, bytes);
-
-       isc_buffer_init(&b, data, bytes);
-       isc_buffer_add(&b, bytes);
-       ret = hmacsha256_fromdns(key, &b);
-       isc_safe_memwipe(data, sizeof(data));
-
-       return (ret);
-}
-
-static bool
-hmacsha256_isprivate(const dst_key_t *key) {
-       UNUSED(key);
-       return (true);
-}
-
-static void
-hmacsha256_destroy(dst_key_t *key) {
-       dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
-
-       isc_safe_memwipe(hkey, sizeof(*hkey));
-       isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacsha256 = NULL;
-}
-
-static isc_result_t
-hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha256_key_t *hkey;
-       unsigned int bytes;
-
-       REQUIRE(key->keydata.hmacsha256 != NULL);
-
-       hkey = key->keydata.hmacsha256;
-
-       bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
-               return (ISC_R_NOSPACE);
-       isc_buffer_putmem(data, hkey->key, bytes);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha256_key_t *hkey;
-       unsigned int keylen;
-       isc_region_t r;
-       isc_result_t res;
-
-       isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
-               return (ISC_R_SUCCESS);
-
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
-       if (hkey == NULL)
-               return (ISC_R_NOMEMORY);
-
-       memset(hkey->key, 0, sizeof(hkey->key));
-
-       if (r.length > ISC_SHA256_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_SHA256, r.base, r.length,
-                            hkey->key, &keylen);
-               REQUIRE(res != ISC_R_SUCCESS);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
-               }
-       } else {
-               memmove(hkey->key, r.base, r.length);
-               keylen = r.length;
-       }
-
-       key->key_size = keylen * 8;
-       key->keydata.hmacsha256 = hkey;
-
-       isc_buffer_forward(data, r.length);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacsha256_key_t *hkey;
-       dst_private_t priv;
-       int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
-
-       if (key->keydata.hmacsha256 == NULL)
-               return (DST_R_NULLKEY);
-
-       if (key->external)
-               return (DST_R_EXTERNALKEY);
-
-       hkey = key->keydata.hmacsha256;
-
-       priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
-
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
-
-       priv.nelements = cnt;
-       return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
-       dst_private_t priv;
-       isc_result_t result, tresult;
-       isc_buffer_t b;
-       isc_mem_t *mctx = key->mctx;
-       unsigned int i;
-
-       UNUSED(pub);
-       /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
-                                      &priv);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       if (key->external)
-               result = DST_R_EXTERNALKEY;
-
-       key->key_bits = 0;
-       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
-               switch (priv.elements[i].tag) {
-               case TAG_HMACSHA256_KEY:
-                       isc_buffer_init(&b, priv.elements[i].data,
-                                       priv.elements[i].length);
-                       isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacsha256_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               case TAG_HMACSHA256_BITS:
-                       tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               default:
-                       result = DST_R_INVALIDPRIVATEKEY;
-                       break;
-               }
-       }
-       dst__privstruct_free(&priv, mctx);
-       isc_safe_memwipe(&priv, sizeof(priv));
-       return (result);
-}
-
-static dst_func_t hmacsha256_functions = {
-       hmacsha256_createctx,
-       NULL, /*%< createctx2 */
-       hmacsha256_destroyctx,
-       hmacsha256_adddata,
-       hmacsha256_sign,
-       hmacsha256_verify,
-       NULL, /* verify2 */
-       NULL, /* computesecret */
-       hmacsha256_compare,
-       NULL, /* paramcompare */
-       hmacsha256_generate,
-       hmacsha256_isprivate,
-       hmacsha256_destroy,
-       hmacsha256_todns,
-       hmacsha256_fromdns,
-       hmacsha256_tofile,
-       hmacsha256_parse,
-       NULL, /* cleanup */
-       NULL, /* fromlabel */
-       NULL, /* dump */
-       NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha256_init(dst_func_t **funcp) {
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacsha256_functions;
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha384_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
-};
-
-static isc_result_t
-hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacsha384_t *hmacsha384ctx;
-       dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
-
-       hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
-       if (hmacsha384ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH);
-       dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
-       return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha384_destroyctx(dst_context_t *dctx) {
-       isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
-       if (hmacsha384ctx != NULL) {
-               isc_hmacsha384_invalidate(hmacsha384ctx);
-               isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
-               dctx->ctxdata.hmacsha384ctx = NULL;
-       }
-}
-
-static isc_result_t
-hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
-       isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-       unsigned char *digest;
-
-       if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
-       isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
-       if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
-               return (DST_R_VERIFYFAILURE);
-
-       if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
-}
-
-static bool
-hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacsha384_key_t *hkey1, *hkey2;
-
-       hkey1 = key1->keydata.hmacsha384;
-       hkey2 = key2->keydata.hmacsha384;
-
-       if (hkey1 == NULL && hkey2 == NULL)
-               return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
-               return (false);
-
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
-}
-
-static isc_result_t
-hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
-{
-       isc_buffer_t b;
-       isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_SHA384_BLOCK_LENGTH];
-
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
-
-       bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA384_BLOCK_LENGTH) {
-               bytes = ISC_SHA384_BLOCK_LENGTH;
-               key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
-       }
-
-       memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
-       isc_nonce_buf(data, bytes);
-
-       isc_buffer_init(&b, data, bytes);
-       isc_buffer_add(&b, bytes);
-       ret = hmacsha384_fromdns(key, &b);
-       isc_safe_memwipe(data, sizeof(data));
-
-       return (ret);
-}
-
-static bool
-hmacsha384_isprivate(const dst_key_t *key) {
-       UNUSED(key);
-       return (true);
-}
-
-static void
-hmacsha384_destroy(dst_key_t *key) {
-       dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
-
-       isc_safe_memwipe(hkey, sizeof(*hkey));
-       isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacsha384 = NULL;
-}
-
-static isc_result_t
-hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha384_key_t *hkey;
-       unsigned int bytes;
-
-       REQUIRE(key->keydata.hmacsha384 != NULL);
-
-       hkey = key->keydata.hmacsha384;
-
-       bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
-               return (ISC_R_NOSPACE);
-       isc_buffer_putmem(data, hkey->key, bytes);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha384_key_t *hkey;
-       unsigned int keylen;
-       isc_region_t r;
-       isc_result_t res;
-
-       isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
-               return (ISC_R_SUCCESS);
-
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
-       if (hkey == NULL)
-               return (ISC_R_NOMEMORY);
-
-       memset(hkey->key, 0, sizeof(hkey->key));
-
-       if (r.length > ISC_SHA384_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_SHA384, r.base, r.length,
-                            hkey->key, &keylen);
-               REQUIRE(res != ISC_R_SUCCESS);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
-               }
-       } else {
-               memmove(hkey->key, r.base, r.length);
-               keylen = r.length;
-       }
-
-       key->key_size = keylen * 8;
-       key->keydata.hmacsha384 = hkey;
-
-       isc_buffer_forward(data, r.length);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacsha384_key_t *hkey;
-       dst_private_t priv;
-       int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
-
-       if (key->keydata.hmacsha384 == NULL)
-               return (DST_R_NULLKEY);
-
-       if (key->external)
-               return (DST_R_EXTERNALKEY);
-
-       hkey = key->keydata.hmacsha384;
-
-       priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
-
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
-
-       priv.nelements = cnt;
-       return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
-       dst_private_t priv;
-       isc_result_t result, tresult;
-       isc_buffer_t b;
-       isc_mem_t *mctx = key->mctx;
-       unsigned int i;
-
-       UNUSED(pub);
-       /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
-                                      &priv);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       if (key->external)
-               result = DST_R_EXTERNALKEY;
-
-       key->key_bits = 0;
-       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
-               switch (priv.elements[i].tag) {
-               case TAG_HMACSHA384_KEY:
-                       isc_buffer_init(&b, priv.elements[i].data,
-                                       priv.elements[i].length);
-                       isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacsha384_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               case TAG_HMACSHA384_BITS:
-                       tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               default:
-                       result = DST_R_INVALIDPRIVATEKEY;
-                       break;
-               }
-       }
-       dst__privstruct_free(&priv, mctx);
-       isc_safe_memwipe(&priv, sizeof(priv));
-       return (result);
-}
-
-static dst_func_t hmacsha384_functions = {
-       hmacsha384_createctx,
-       NULL, /*%< createctx2 */
-       hmacsha384_destroyctx,
-       hmacsha384_adddata,
-       hmacsha384_sign,
-       hmacsha384_verify,
-       NULL, /* verify2 */
-       NULL, /* computesecret */
-       hmacsha384_compare,
-       NULL, /* paramcompare */
-       hmacsha384_generate,
-       hmacsha384_isprivate,
-       hmacsha384_destroy,
-       hmacsha384_todns,
-       hmacsha384_fromdns,
-       hmacsha384_tofile,
-       hmacsha384_parse,
-       NULL, /* cleanup */
-       NULL, /* fromlabel */
-       NULL, /* dump */
-       NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha384_init(dst_func_t **funcp) {
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacsha384_functions;
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha512_key {
-       unsigned char key[ISC_HMAC_MAX_MD_CBLOCK];
-};
-
-static isc_result_t
-hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
-       isc_hmacsha512_t *hmacsha512ctx;
-       dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
-
-       hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
-       if (hmacsha512ctx == NULL)
-               return (ISC_R_NOMEMORY);
-       isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH);
-       dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
-       return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha512_destroyctx(dst_context_t *dctx) {
-       isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
-       if (hmacsha512ctx != NULL) {
-               isc_hmacsha512_invalidate(hmacsha512ctx);
-               isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
-               dctx->ctxdata.hmacsha512ctx = NULL;
-       }
-}
-
-static isc_result_t
-hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
-       isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
-       isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
-       isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-       unsigned char *digest;
-
-       if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
-               return (ISC_R_NOSPACE);
-       digest = isc_buffer_used(sig);
-       isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
-       isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
-       isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
-       if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
-               return (DST_R_VERIFYFAILURE);
-
-       if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
-               return (ISC_R_SUCCESS);
-       else
-               return (DST_R_VERIFYFAILURE);
-}
-
-static bool
-hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
-       dst_hmacsha512_key_t *hkey1, *hkey2;
-
-       hkey1 = key1->keydata.hmacsha512;
-       hkey2 = key2->keydata.hmacsha512;
-
-       if (hkey1 == NULL && hkey2 == NULL)
-               return (true);
-       else if (hkey1 == NULL || hkey2 == NULL)
-               return (false);
-
-       if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH))
-               return (true);
-       else
-               return (false);
-}
-
-static isc_result_t
-hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
-{
-       isc_buffer_t b;
-       isc_result_t ret;
-       unsigned int bytes;
-       unsigned char data[ISC_SHA512_BLOCK_LENGTH];
-
-       UNUSED(pseudorandom_ok);
-       UNUSED(callback);
-
-       bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA512_BLOCK_LENGTH) {
-               bytes = ISC_SHA512_BLOCK_LENGTH;
-               key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
-       }
-
-       memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
-       isc_nonce_buf(data, bytes);
-
-       isc_buffer_init(&b, data, bytes);
-       isc_buffer_add(&b, bytes);
-       ret = hmacsha512_fromdns(key, &b);
-       isc_safe_memwipe(data, sizeof(data));
-
-       return (ret);
-}
-
-static bool
-hmacsha512_isprivate(const dst_key_t *key) {
-       UNUSED(key);
-       return (true);
-}
-
-static void
-hmacsha512_destroy(dst_key_t *key) {
-       dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
-
-       isc_safe_memwipe(hkey, sizeof(*hkey));
-       isc_mem_put(key->mctx, hkey, sizeof(*hkey));
-       key->keydata.hmacsha512 = NULL;
-}
-
-static isc_result_t
-hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha512_key_t *hkey;
-       unsigned int bytes;
-
-       REQUIRE(key->keydata.hmacsha512 != NULL);
-
-       hkey = key->keydata.hmacsha512;
-
-       bytes = (key->key_size + 7) / 8;
-       if (isc_buffer_availablelength(data) < bytes)
-               return (ISC_R_NOSPACE);
-       isc_buffer_putmem(data, hkey->key, bytes);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
-       dst_hmacsha512_key_t *hkey;
-       unsigned int keylen;
-       isc_region_t r;
-       isc_result_t res;
-
-       isc_buffer_remainingregion(data, &r);
-       if (r.length == 0)
-               return (ISC_R_SUCCESS);
-
-       hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
-       if (hkey == NULL)
-               return (ISC_R_NOMEMORY);
-
-       memset(hkey->key, 0, sizeof(hkey->key));
-
-       if (r.length > ISC_SHA512_BLOCK_LENGTH) {
-               res = isc_md(ISC_MD_SHA512, r.base, r.length,
-                            hkey->key, &keylen);
-               REQUIRE(res != ISC_R_SUCCESS);
-               if (res != ISC_R_SUCCESS) {
-                       return (res);
-               }
-       } else {
-               memmove(hkey->key, r.base, r.length);
-               keylen = r.length;
-       }
-
-       key->key_size = keylen * 8;
-       key->keydata.hmacsha512 = hkey;
-
-       isc_buffer_forward(data, r.length);
-
-       return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_tofile(const dst_key_t *key, const char *directory) {
-       int cnt = 0;
-       dst_hmacsha512_key_t *hkey;
-       dst_private_t priv;
-       int bytes = (key->key_size + 7) / 8;
-       unsigned char buf[2];
-
-       if (key->keydata.hmacsha512 == NULL)
-               return (DST_R_NULLKEY);
-
-       if (key->external)
-               return (DST_R_EXTERNALKEY);
-
-       hkey = key->keydata.hmacsha512;
-
-       priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
-       priv.elements[cnt].length = bytes;
-       priv.elements[cnt++].data = hkey->key;
-
-       buf[0] = (key->key_bits >> 8) & 0xffU;
-       buf[1] = key->key_bits & 0xffU;
-       priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
-       priv.elements[cnt].data = buf;
-       priv.elements[cnt++].length = 2;
-
-       priv.nelements = cnt;
-       return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
-       dst_private_t priv;
-       isc_result_t result, tresult;
-       isc_buffer_t b;
-       isc_mem_t *mctx = key->mctx;
-       unsigned int i;
-
-       UNUSED(pub);
-       /* read private key file */
-       result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
-                                      &priv);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       if (key->external)
-               result = DST_R_EXTERNALKEY;
-
-       key->key_bits = 0;
-       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
-               switch (priv.elements[i].tag) {
-               case TAG_HMACSHA512_KEY:
-                       isc_buffer_init(&b, priv.elements[i].data,
-                                       priv.elements[i].length);
-                       isc_buffer_add(&b, priv.elements[i].length);
-                       tresult = hmacsha512_fromdns(key, &b);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               case TAG_HMACSHA512_BITS:
-                       tresult = getkeybits(key, &priv.elements[i]);
-                       if (tresult != ISC_R_SUCCESS)
-                               result = tresult;
-                       break;
-               default:
-                       result = DST_R_INVALIDPRIVATEKEY;
-                       break;
-               }
-       }
-       dst__privstruct_free(&priv, mctx);
-       isc_safe_memwipe(&priv, sizeof(priv));
-       return (result);
-}
-
-static dst_func_t hmacsha512_functions = {
-       hmacsha512_createctx,
-       NULL, /*%< createctx2 */
-       hmacsha512_destroyctx,
-       hmacsha512_adddata,
-       hmacsha512_sign,
-       hmacsha512_verify,
-       NULL, /* verify2 */
-       NULL, /* computesecret */
-       hmacsha512_compare,
-       NULL, /* paramcompare */
-       hmacsha512_generate,
-       hmacsha512_isprivate,
-       hmacsha512_destroy,
-       hmacsha512_todns,
-       hmacsha512_fromdns,
-       hmacsha512_tofile,
-       hmacsha512_parse,
-       NULL, /* cleanup */
-       NULL, /* fromlabel */
-       NULL, /* dump */
-       NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha512_init(dst_func_t **funcp) {
-       REQUIRE(funcp != NULL);
-       if (*funcp == NULL)
-               *funcp = &hmacsha512_functions;
-       return (ISC_R_SUCCESS);
-}
+hmac_register_algorithm(md5);
+hmac_register_algorithm(sha1);
+hmac_register_algorithm(sha224);
+hmac_register_algorithm(sha256);
+hmac_register_algorithm(sha384);
+hmac_register_algorithm(sha512);
 
 /*! \file */
index 7343ed35089a43ec5056f0b13ddac68886fc0d0b..ef452d58fd61ccfad82d06010b4ba8e4b0f819b4 100644 (file)
@@ -18,7 +18,6 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
-#include <isc/hmacmd5.h>
 #include <isc/mem.h>
 #include <isc/safe.h>
 #include <isc/string.h>
index f2b81e7ca30df9f2e78b8b2e1c23f846f42221ef..06ad322a273ff1f52c1b40d17628ea59baa7d7e7 100644 (file)
@@ -32,7 +32,7 @@
 #ifdef AES_CC
 #include <isc/aes.h>
 #else
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
 #endif
 
 #include <dns/acl.h>
@@ -2256,53 +2256,38 @@ compute_cc(resquery_t *query, unsigned char *cookie, size_t len) {
                digest[i] ^= digest[i + 8];
        memmove(cookie, digest, 8);
 #endif
-#ifdef HMAC_SHA1_CC
-       unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+#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;
-       isc_hmacsha1_t hmacsha1;
-
-       INSIST(len >= 8U);
-
-       isc_hmacsha1_init(&hmacsha1, query->fctx->res->view->secret,
-                         ISC_SHA1_DIGESTLENGTH);
-       isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
-       switch (netaddr.family) {
-       case AF_INET:
-               isc_hmacsha1_update(&hmacsha1,
-                                   (unsigned char *)&netaddr.type.in, 4);
-               break;
-       case AF_INET6:
-               isc_hmacsha1_update(&hmacsha1,
-                                   (unsigned char *)&netaddr.type.in6, 16);
-               break;
-       }
-       isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
-       memmove(cookie, digest, 8);
-       isc_hmacsha1_invalidate(&hmacsha1);
+#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_DIGESTLENGHT;
 #endif
-#ifdef HMAC_SHA256_CC
-       unsigned char digest[ISC_SHA256_DIGESTLENGTH];
-       isc_netaddr_t netaddr;
-       isc_hmacsha256_t hmacsha256;
 
        INSIST(len >= 8U);
 
-       isc_hmacsha256_init(&hmacsha256, query->fctx->res->view->secret,
-                           ISC_SHA256_DIGESTLENGTH);
        isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
        switch (netaddr.family) {
        case AF_INET:
-               isc_hmacsha256_update(&hmacsha256,
-                                     (unsigned char *)&netaddr.type.in, 4);
+               input = (unsigned char *)&netaddr.type.in;
+               length = 4;
                break;
        case AF_INET6:
-               isc_hmacsha256_update(&hmacsha256,
-                                     (unsigned char *)&netaddr.type.in6, 16);
+               input = (unsigned char *)&netaddr.type.in6;
+               length = 16;
                break;
        }
-       isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
+
+       RUNTIME_CHECK(isc_hmac(type,
+                              query->fctx->res->view->secret, secret_len,
+                              input, length,
+                              digest, NULL) == ISC_R_SUCCESS);
        memmove(cookie, digest, 8);
-       isc_hmacsha256_invalidate(&hmacsha256);
 #endif
 }
 
index 69216a91f027bd256bf7d2b9624bbb6092b85431..d242757cf116764620781e8c29b6478c3b2cd424 100644 (file)
@@ -47,8 +47,8 @@ OBJS =                pk11.@O@ pk11_result.@O@ \
                aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
                bind9.@O@ buffer.@O@ bufferlist.@O@ \
                commandline.@O@ counter.@O@ crc64.@O@ error.@O@ entropy.@O@ \
-               event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
-               hmacsha.@O@ httpd.@O@ iterated_hash.@O@ \
+               event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmac.@O@ \
+               httpd.@O@ iterated_hash.@O@ \
                lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
                md.@O@ mem.@O@ mutexblock.@O@ \
                netaddr.@O@ netscope.@O@ nonce.@O@ openssl_shim.@O@ pool.@O@ \
@@ -65,8 +65,8 @@ SYMTBLOBJS =  backtrace-emptytbl.@O@
 SRCS =         pk11.c pk11_result.c \
                aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
                buffer.c bufferlist.c commandline.c counter.c crc64.c \
-               entropy.c error.c event.c hash.c ht.c heap.c hex.c hmacmd5.c \
-               hmacsha.c httpd.c iterated_hash.c \
+               entropy.c error.c event.c hash.c ht.c heap.c hex.c hmac.c \
+               httpd.c iterated_hash.c \
                lex.c lfsr.c lib.c log.c \
                md.c mem.c mutexblock.c \
                netaddr.c netscope.c nonce.c openssl_shim.c pool.c \
diff --git a/lib/isc/hmac.c b/lib/isc/hmac.c
new file mode 100644 (file)
index 0000000..31fc691
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <isc/assertions.h>
+#include <isc/hmac.h>
+#include <isc/md.h>
+#include <isc/platform.h>
+#include <isc/safe.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#include <openssl/hmac.h>
+#include <openssl/opensslv.h>
+
+#include "openssl_shim.h"
+
+isc_hmac_t *
+isc_hmac_new(void) {
+       isc_hmac_t *hmac = HMAC_CTX_new();
+       RUNTIME_CHECK(hmac != NULL);
+       return (hmac);
+}
+
+void
+isc_hmac_free(isc_hmac_t *hmac) {
+       if (ISC_UNLIKELY(hmac == NULL)) {
+               return;
+       }
+
+       HMAC_CTX_free(hmac);
+}
+
+isc_result_t
+isc_hmac_init(isc_hmac_t *hmac, const void *key,
+             size_t keylen, isc_md_type_t md_type)
+{
+       REQUIRE(hmac != NULL);
+       REQUIRE(key != NULL);
+
+       if (md_type == NULL) {
+               return (ISC_R_NOTIMPLEMENTED);
+       }
+
+       if (HMAC_Init_ex(hmac, key, keylen, md_type, NULL) != 1) {
+               return (ISC_R_CRYPTOFAILURE);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hmac_reset(isc_hmac_t *hmac) {
+       REQUIRE(hmac != NULL);
+
+       if  (HMAC_CTX_reset(hmac) != 1) {
+               return (ISC_R_CRYPTOFAILURE);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hmac_update(isc_hmac_t *hmac, const unsigned char *buf, const size_t len) {
+       REQUIRE(hmac != NULL);
+
+       if (ISC_UNLIKELY(buf == NULL || len == 0)) {
+               return (ISC_R_SUCCESS);
+       }
+
+       if (HMAC_Update(hmac, buf, len) != 1) {
+               return (ISC_R_CRYPTOFAILURE);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hmac_final(isc_hmac_t *hmac, unsigned char *digest,
+              unsigned int *digestlen)
+{
+       REQUIRE(hmac != NULL);
+       REQUIRE(digest != NULL);
+
+       if (HMAC_Final(hmac, digest, digestlen) != 1) {
+               return (ISC_R_CRYPTOFAILURE);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
+isc_md_type_t
+isc_hmac_get_md_type(isc_hmac_t *hmac) {
+       REQUIRE(hmac != NULL);
+
+       return (HMAC_CTX_get_md(hmac));
+}
+
+size_t
+isc_hmac_get_size(isc_hmac_t *hmac) {
+       REQUIRE(hmac != NULL);
+
+       return ((size_t)EVP_MD_size(HMAC_CTX_get_md(hmac)));
+}
+
+int
+isc_hmac_get_block_size(isc_hmac_t *hmac) {
+       REQUIRE(hmac != NULL);
+
+       return (EVP_MD_block_size(HMAC_CTX_get_md(hmac)));
+}
+
+isc_result_t
+isc_hmac(isc_md_type_t type, const void *key, const int keylen,
+        const unsigned char *buf, const size_t len,
+        unsigned char *digest, unsigned int *digestlen)
+{
+       isc_hmac_t *hmac = NULL;
+       isc_result_t res;
+
+       hmac = isc_hmac_new();
+
+       res = isc_hmac_init(hmac, key, keylen, type);
+       if (res != ISC_R_SUCCESS) {
+               goto end;
+       }
+
+       res = isc_hmac_update(hmac, buf, len);
+       if (res != ISC_R_SUCCESS) {
+               goto end;
+       }
+
+       res = isc_hmac_final(hmac, digest, digestlen);
+       if (res != ISC_R_SUCCESS) {
+               goto end;
+       }
+ end:
+       isc_hmac_free(hmac);
+
+       return (res);
+}
diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c
deleted file mode 100644 (file)
index 3f48bc0..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdbool.h>
-
-#include <isc/assertions.h>
-#include <isc/hmacmd5.h>
-#include <isc/platform.h>
-#include <isc/safe.h>
-#include <isc/string.h>
-#include <isc/types.h>
-#include <isc/util.h>
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
-#define HMAC_CTX_new() &(ctx->_ctx), HMAC_CTX_init(&(ctx->_ctx))
-#define HMAC_CTX_free(ptr) HMAC_CTX_cleanup(ptr)
-#endif
-
-void
-isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
-                unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_md5(), NULL) == 1);
-}
-
-void
-isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, digest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-/*!
- * Verify signature - finalize MD5 operation and reapply MD5, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
-       return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
-}
-
-bool
-isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
-       isc_hmacmd5_sign(ctx, newdigest);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Check for MD5 support; if it does not work, raise a fatal error.
- *
- * Use the first test vector from RFC 2104, with a second round using
- * a too-short key.
- *
- * Standard use is testing 0 and expecting result true.
- * Testing use is testing 1..4 and expecting result false.
- */
-bool
-isc_hmacmd5_check(int testing) {
-       isc_hmacmd5_t ctx;
-       unsigned char key[] = { /* 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b */
-               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
-       };
-       unsigned char input[] = { /* "Hi There" */
-               0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-       };
-       unsigned char expected[] = {
-               0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
-               0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
-       };
-       unsigned char expected2[] = {
-               0xad, 0xb8, 0x48, 0x05, 0xb8, 0x8d, 0x03, 0xe5,
-               0x90, 0x1e, 0x4b, 0x05, 0x69, 0xce, 0x35, 0xea
-       };
-       bool result;
-
-       /*
-        * Introduce a fault for testing.
-        */
-       switch (testing) {
-       case 0:
-       default:
-               break;
-       case 1:
-               key[0] ^= 0x01;
-               break;
-       case 2:
-               input[0] ^= 0x01;
-               break;
-       case 3:
-               expected[0] ^= 0x01;
-               break;
-       case 4:
-               expected2[0] ^= 0x01;
-               break;
-       }
-
-       /*
-        * These functions do not return anything; any failure will be fatal.
-        */
-       isc_hmacmd5_init(&ctx, key, 16U);
-       isc_hmacmd5_update(&ctx, input, 8U);
-       result = isc_hmacmd5_verify2(&ctx, expected, sizeof(expected));
-       if (!result) {
-               return (result);
-       }
-
-       /* Second round using a byte key */
-       isc_hmacmd5_init(&ctx, key, 1U);
-       isc_hmacmd5_update(&ctx, input, 8U);
-       return (isc_hmacmd5_verify2(&ctx, expected2, sizeof(expected2)));
-}
diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c
deleted file mode 100644 (file)
index 6f621c9..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
- * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
- * draft-ietf-dnsext-tsig-sha-01.txt.
- */
-
-#include <config.h>
-
-#include <stdbool.h>
-
-#include <isc/assertions.h>
-#include <isc/hmacsha.h>
-#include <isc/platform.h>
-#include <isc/safe.h>
-#include <isc/string.h>
-#include <isc/types.h>
-#include <isc/util.h>
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
-#define HMAC_CTX_new() &(ctx->_ctx), HMAC_CTX_init(&(ctx->_ctx))
-#define HMAC_CTX_free(ptr) HMAC_CTX_cleanup(ptr)
-#endif
-
-void
-isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
-                 unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_sha1(), NULL) == 1);
-}
-
-void
-isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
-
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-       memmove(digest, newdigest, len);
-       isc_safe_memwipe(newdigest, sizeof(newdigest));
-}
-
-void
-isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
-                   unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_sha224(), NULL) == 1);
-}
-
-void
-isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
-
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-       memmove(digest, newdigest, len);
-       isc_safe_memwipe(newdigest, sizeof(newdigest));
-}
-
-void
-isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
-                   unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_sha256(), NULL) == 1);
-}
-
-void
-isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
-
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-       memmove(digest, newdigest, len);
-       isc_safe_memwipe(newdigest, sizeof(newdigest));
-}
-
-void
-isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
-                   unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_sha384(), NULL) == 1);
-}
-
-void
-isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
-
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-       memmove(digest, newdigest, len);
-       isc_safe_memwipe(newdigest, sizeof(newdigest));
-}
-
-void
-isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
-                   unsigned int len)
-{
-       ctx->ctx = HMAC_CTX_new();
-       RUNTIME_CHECK(ctx->ctx != NULL);
-       RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
-                                  (int) len, EVP_sha512(), NULL) == 1);
-}
-
-void
-isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
-       if (ctx->ctx == NULL)
-               return;
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-}
-
-void
-isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
-                  unsigned int len)
-{
-       RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
-}
-
-void
-isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
-
-       RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
-       HMAC_CTX_free(ctx->ctx);
-       ctx->ctx = NULL;
-       memmove(digest, newdigest, len);
-       isc_safe_memwipe(newdigest, sizeof(newdigest));
-}
-
-/*
- * Verify signature - finalize SHA1 operation and reapply SHA1, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
-       isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Verify signature - finalize SHA224 operation and reapply SHA224, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
-       isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Verify signature - finalize SHA256 operation and reapply SHA256, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
-       isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Verify signature - finalize SHA384 operation and reapply SHA384, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
-       isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Verify signature - finalize SHA512 operation and reapply SHA512, then
- * compare to the supplied digest.
- */
-bool
-isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
-       unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
-
-       REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
-       isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
-       return (isc_safe_memequal(digest, newdigest, len));
-}
-
-/*
- * Check for SHA-1 support; if it does not work, raise a fatal error.
- *
- * Use the first test vector from RFC 2104, with a second round using
- * a too-short key.
- *
- * Standard use is testing 0 and expecting result true.
- * Testing use is testing 1..4 and expecting result false.
- */
-bool
-isc_hmacsha1_check(int testing) {
-       isc_hmacsha1_t ctx;
-       unsigned char key[] = { /* 20*0x0b */
-               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-               0x0b, 0x0b, 0x0b, 0x0b
-       };
-       unsigned char input[] = { /* "Hi There" */
-               0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-       };
-       unsigned char expected[] = {
-               0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
-               0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
-               0xf1, 0x46, 0xbe, 0x00
-       };
-       unsigned char expected2[] = {
-               0xa0, 0x75, 0xe0, 0x5f, 0x7f, 0x17, 0x9d, 0x34,
-               0xb2, 0xab, 0xc5, 0x19, 0x8f, 0x38, 0x62, 0x36,
-               0x42, 0xbd, 0xec, 0xde
-       };
-       bool result;
-
-       /*
-        * Introduce a fault for testing.
-        */
-       switch (testing) {
-       case 0:
-       default:
-               break;
-       case 1:
-               key[0] ^= 0x01;
-               break;
-       case 2:
-               input[0] ^= 0x01;
-               break;
-       case 3:
-               expected[0] ^= 0x01;
-               break;
-       case 4:
-               expected2[0] ^= 0x01;
-               break;
-       }
-
-       /*
-        * These functions do not return anything; any failure will be fatal.
-        */
-       isc_hmacsha1_init(&ctx, key, 20U);
-       isc_hmacsha1_update(&ctx, input, 8U);
-       result = isc_hmacsha1_verify(&ctx, expected, sizeof(expected));
-       if (!result) {
-               return (result);
-       }
-
-       /* Second round using a byte key */
-       isc_hmacsha1_init(&ctx, key, 1U);
-       isc_hmacsha1_update(&ctx, input, 8U);
-       return (isc_hmacsha1_verify(&ctx, expected2, sizeof(expected2)));
-}
index fa127e2e954443b70d2d76385f736bda2593c82a..94a42e4a0c48253b314f4f491b1cb9d245c2da7e 100644 (file)
@@ -23,7 +23,7 @@ HEADERS =     aes.h app.h assertions.h atomic.h backtrace.h base32.h base64.h \
                commandline.h counter.h crc64.h deprecated.h \
                errno.h error.h event.h eventclass.h \
                file.h formatcheck.h fsaccess.h fuzz.h \
-               hash.h heap.h hex.h hmacmd5.h hmacsha.h ht.h httpd.h \
+               hash.h heap.h hex.h hmac.h ht.h httpd.h \
                interfaceiter.h iterated_hash.h \
                json.h lang.h lex.h lfsr.h lib.h likely.h list.h log.h \
                magic.h mem.h meminfo.h msgcat.h msgs.h mutexblock.h \
diff --git a/lib/isc/include/isc/hmac.h b/lib/isc/include/isc/hmac.h
new file mode 100644 (file)
index 0000000..20bcde3
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+/*!
+ * \file isc/hmac.h
+ * \brief This is the header for for message authentication code.
+ */
+
+#pragma once
+
+#include <config.h>
+
+#include <isc/lang.h>
+#include <isc/md.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+#include <isc/result.h>
+
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX isc_hmac_t;
+
+/**
+ * isc_hmac:
+ * @type: the digest type
+ * @key: the key
+ * @keylen: the length of the key
+ * @buf: data to hash
+ * @len: length of the data to hash
+ * @digest: the output buffer
+ * @digestlen: the length of the data written to @digest
+ *
+ * This function computes the message authentication code using a digest type
+ * @type with key @key which is @keylen bytes long from data in @buf which is
+ * @len bytes long, and places the output into @digest, which must have space
+ * for the hash function output (use ISC_MAX_MD_SIZE if unsure).  If the
+ * @digestlen parameter is not NULL then the number of bytes of data written
+ * (i.e. the length of the digest) will be written to the @digestlen.
+ */
+isc_result_t
+isc_hmac(isc_md_type_t type, const void *key, const int keylen,
+        const unsigned char *buf, const size_t len,
+        unsigned char *digest, unsigned int *digestlen);
+
+/**
+ * isc_hmac_new:
+ *
+ * This function allocates, initializes and returns HMAC context.
+ */
+isc_hmac_t *
+isc_hmac_new(void);
+
+/**
+ * isc_hmac_free:
+ * @md: HMAC context
+ *
+ * This function cleans up HMAC context and frees up the space allocated to it.
+ */
+void
+isc_hmac_free(isc_hmac_t *hmac);
+
+/**
+ * isc_hmac_init:
+ * @md: HMAC context
+ * @key: HMAC key
+ * @keylen: HMAC key length
+ * @type: digest type
+ *
+ * This function sets up HMAC context to use a hash function of @type and key
+ * @key which is @keylen bytes long.
+ */
+
+isc_result_t
+isc_hmac_init(isc_hmac_t *hmac, const void *key,
+             size_t keylen, isc_md_type_t type);
+
+/**
+ * isc_hmac_reset:
+ * @hmac: HMAC context
+ *
+ * This function resets the HMAC context.  This can be used to reuse an already
+ * existing context.
+ */
+isc_result_t
+isc_hmac_reset(isc_hmac_t *hmac);
+
+/**
+ * isc_hmac_update:
+ * @hmac: HMAC context
+ * @buf: data to hash
+ * @len: length of the data to hash
+ *
+ * This function can be called repeatedly with chunks of the message @buf to be
+ * authenticated which is @len bytes long.
+ */
+isc_result_t
+isc_hmac_update(isc_hmac_t *hmac, const unsigned char *buf, const size_t len);
+
+/**
+ * isc_hmac_final:
+ * @hmac: HMAC context
+ * @digest: the output buffer
+ * @digestlen: the lenth of the data written to @digest
+ *
+ * This function retrieves the message authentication code from @hmac and places
+ * it in @digest, which must have space for the hash function output.  If the
+ * @digestlen parameter is not NULL then the number of bytes of data written
+ * (i.e. the length of the digest) will be written to the @digestlen.  After
+ * calling this function no additional calls to isc_hmac_update() can be made.
+ */
+isc_result_t
+isc_hmac_final(isc_hmac_t *hmac, unsigned char *digest,
+              unsigned int *digestlen);
+
+/**
+ * isc_hmac_md_type:
+ * @hmac: HMAC context
+ *
+ * This function return the isc_md_type_t previously set for the supplied
+ * HMAC context or NULL if no isc_md_type_t has been set.
+ */
+isc_md_type_t
+isc_hmac_get_md_type(isc_hmac_t *hmac);
+
+/**
+ * isc_hmac_get_size:
+ *
+ * This function return the size of the message digest when passed an isc_hmac_t
+ * structure, i.e. the size of the hash.
+ */
+size_t
+isc_hmac_get_size(isc_hmac_t *hmac);
+
+/**
+ * isc_hmac_get_block_size:
+ *
+ * This function return the block size of the message digest when passed an
+ * isc_hmac_t structure.
+ */
+int
+isc_hmac_get_block_size(isc_hmac_t *hmac);
diff --git a/lib/isc/include/isc/hmacmd5.h b/lib/isc/include/isc/hmacmd5.h
deleted file mode 100644 (file)
index 0f87b2a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- */
-
-
-/*! \file isc/hmacmd5.h
- * \brief This is the header file for the HMAC-MD5 keyed hash algorithm
- * described in RFC2104.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#include <isc/lang.h>
-#include <isc/md.h>
-#include <isc/platform.h>
-#include <isc/types.h>
-
-#define ISC_HMACMD5_KEYLENGTH 64
-
-#include <openssl/opensslv.h>
-#include <openssl/hmac.h>
-
-typedef struct {
-       HMAC_CTX *ctx;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
-       HMAC_CTX _ctx;
-#endif
-} isc_hmacmd5_t;
-
-ISC_LANG_BEGINDECLS
-
-void
-isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
-                unsigned int len);
-
-void
-isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx);
-
-void
-isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
-                  unsigned int len);
-
-void
-isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest);
-
-bool
-isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest);
-
-bool
-isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacmd5_check(int testing);
-
-ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/hmacsha.h b/lib/isc/include/isc/hmacsha.h
deleted file mode 100644 (file)
index 346dc20..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.
- */
-
-
-/*! \file isc/hmacsha.h
- * This is the header file for the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256,
- * HMAC-SHA334 and HMAC-SHA512 hash algorithm described in RFC 2104.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#include <isc/lang.h>
-#include <isc/platform.h>
-#include <isc/md.h>
-#include <isc/types.h>
-
-#define ISC_HMACSHA1_KEYLENGTH   ISC_SHA1_BLOCK_LENGTH
-#define ISC_HMACSHA224_KEYLENGTH ISC_SHA224_BLOCK_LENGTH
-#define ISC_HMACSHA256_KEYLENGTH ISC_SHA256_BLOCK_LENGTH
-#define ISC_HMACSHA384_KEYLENGTH ISC_SHA384_BLOCK_LENGTH
-#define ISC_HMACSHA512_KEYLENGTH ISC_SHA512_BLOCK_LENGTH
-
-#include <openssl/opensslv.h>
-#include <openssl/hmac.h>
-
-#define ISC_HMAC_MAX_MD_CBLOCK HMAC_MAX_MD_CBLOCK
-
-typedef struct {
-       HMAC_CTX *ctx;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
-       HMAC_CTX _ctx;
-#endif
-} isc_hmacsha_t;
-
-typedef isc_hmacsha_t isc_hmacsha1_t;
-typedef isc_hmacsha_t isc_hmacsha224_t;
-typedef isc_hmacsha_t isc_hmacsha256_t;
-typedef isc_hmacsha_t isc_hmacsha384_t;
-typedef isc_hmacsha_t isc_hmacsha512_t;
-
-ISC_LANG_BEGINDECLS
-
-void
-isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
-                 unsigned int len);
-
-void
-isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx);
-
-void
-isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
-                   unsigned int len);
-
-void
-isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha1_check(int testing);
-
-
-void
-isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
-                   unsigned int len);
-
-void
-isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx);
-
-void
-isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
-                     unsigned int len);
-
-void
-isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
-
-
-void
-isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
-                   unsigned int len);
-
-void
-isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx);
-
-void
-isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
-                     unsigned int len);
-
-void
-isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
-
-
-void
-isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
-                   unsigned int len);
-
-void
-isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx);
-
-void
-isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
-                     unsigned int len);
-
-void
-isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
-
-
-void
-isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
-                   unsigned int len);
-
-void
-isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx);
-
-void
-isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
-                     unsigned int len);
-
-void
-isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
-
-bool
-isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
-
-ISC_LANG_ENDDECLS
index ee98050f6da08f7f77f61341c6676a105ebd51d3..d8e9fc2250396bba4bda939ecbc2bdb7136a5515 100644 (file)
@@ -101,5 +101,9 @@ HMAC_CTX_reset(HMAC_CTX *ctx) {
        return (1);
 }
 
+const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx) {
+       return ctx->md;
+}
+
 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L ||
        * defined(LIBRESSL_VERSION_NUMBER) */
index 1a148b50c3f11ff7303fcc0d10ce87bdb436c026..6088e05b46e6b9a192907212654df825fa837a43 100644 (file)
@@ -29,6 +29,7 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
 HMAC_CTX *HMAC_CTX_new(void);
 void HMAC_CTX_free(HMAC_CTX *ctx);
 int HMAC_CTX_reset(HMAC_CTX *ctx);
+const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx);
 
 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L ||
        * defined(LIBRESSL_VERSION_NUMBER) */
index ed92a7753224b7522df8a617d26bdfee3b4a1d6d..26785b5669683a3e76d95e64f715e359be5c09c2 100644 (file)
@@ -8,6 +8,7 @@ atf_test_program{name='errno_test'}
 atf_test_program{name='file_test'}
 atf_test_program{name='hash_test'}
 atf_test_program{name='heap_test'}
+tap_test_program{name='hmac_test'}
 atf_test_program{name='ht_test'}
 atf_test_program{name='lex_test'}
 tap_test_program{name='md_test'}
index 1a84de0df999beaa626f2b741250c7edfe4cd6d9..1a17d13c0ee29b79dce8263c9352fc05d988ffee 100644 (file)
@@ -34,7 +34,7 @@ OBJS =                isctest.@O@
 
 SRCS =         isctest.c aes_test.c buffer_test.c \
                counter_test.c errno_test.c file_test.c hash_test.c \
-               heap_test.c ht_test.c lex_test.c \
+               heap_test.c hmac_test.c ht_test.c lex_test.c \
                mem_test.c md_test.c netaddr_test.c parse_test.c pool_test.c \
                queue_test.c radix_test.c random_test.c \
                regex_test.c result_test.c safe_test.c sockaddr_test.c \
@@ -44,7 +44,8 @@ SRCS =                isctest.c aes_test.c buffer_test.c \
 SUBDIRS =
 TARGETS =      aes_test@EXEEXT@ buffer_test@EXEEXT@ \
                counter_test@EXEEXT@ errno_test@EXEEXT@ file_test@EXEEXT@ \
-               hash_test@EXEEXT@ heap_test@EXEEXT@ ht_test@EXEEXT@ \
+               hash_test@EXEEXT@ heap_test@EXEEXT@ hmac_test@EXEEXT@ \
+               ht_test@EXEEXT@ \
                lex_test@EXEEXT@ mem_test@EXEEXT@ md_test@EXEEXT@ \
                netaddr_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \
                queue_test@EXEEXT@ radix_test@EXEEXT@ \
@@ -83,6 +84,10 @@ heap_test@EXEEXT@: heap_test.@O@ ${ISCDEPLIBS}
        ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
                        heap_test.@O@ ${ISCLIBS} ${LIBS}
 
+hmac_test@EXEEXT@: hmac_test.@O@ ${ISCDEPLIBS}
+       ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${CMOCKA_CFLAGS} ${LDFLAGS} -o $@ \
+                       hmac_test.@O@ ${ISCLIBS} ${LIBS} ${CMOCKA_LIBS}
+
 ht_test@EXEEXT@: ht_test.@O@ ${ISCDEPLIBS}
        ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
                        ht_test.@O@ ${ISCLIBS} ${LIBS}
index 3745dfbbbe426b6877643965760d39c4ddbc778b..9a1f30707a475ca7b049deed1d8b4cd95c4d5bf9 100644 (file)
 #include <isc/region.h>
 
 #include <isc/crc64.h>
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
-#include <isc/md.h>
 #include <isc/util.h>
 #include <isc/print.h>
 #include <isc/string.h>
 
 #include <pk11/site.h>
 
-/*
- * Test data from RFC6234
- */
-
-unsigned char digest[ISC_MAX_MD_SIZE];
-unsigned char buffer[1024];
-const char *s;
-char str[2 * ISC_MAX_MD_SIZE + 3];
-unsigned char key[20];
-
 #define TEST_INPUT(x) (x), sizeof(x)-1
 
-static isc_result_t
-tohexstr(unsigned char *in, size_t inlen,
-        char *out, const size_t outlen)
-{
-       isc_buffer_t b;
-       isc_region_t r = { .base = in,
-                          .length = inlen };
-
-       isc_buffer_init(&b, out, outlen);
-       return (isc_hex_totext(&r, 0, "", &b));
-}
-
 typedef struct hash_testcase {
        const char *input;
        size_t input_len;
@@ -65,948 +40,6 @@ typedef struct hash_testcase {
        int repeats;
 } hash_testcase_t;
 
-typedef struct hash_test_key {
-       const char *key;
-       const int len;
-} hash_test_key_t;
-
-/* HMAC-SHA1 test */
-ATF_TC(isc_hmacsha1);
-ATF_TC_HEAD(isc_hmacsha1, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-SHA1 examples from RFC2104");
-}
-ATF_TC_BODY(isc_hmacsha1, tc) {
-       isc_hmacsha1_t hmacsha1;
-
-       UNUSED(tc);
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "B617318655057264E28BC0B6FB378C8EF146BE00",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
-                                  "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
-                                  "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79",
-                       1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "125D7342B9AC11CD91A39AF48AA17B4F63F175D3",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "4C9007F4026250C6BC8414F9BF50C86C2D7235DA",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-#endif
-               /* Test 6 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "AA4AE5E15272D00E95705637CE8A3B55ED402112", 1 },
-               /* Test 7 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key and "
-                                  "Larger Than One Block-Size Data"),
-                       "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
-                       1
-               },
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-#endif
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 },
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacsha1_init(&hmacsha1, buffer, test_key->len);
-               isc_hmacsha1_update(&hmacsha1,
-                                   (const uint8_t *) testcase->input,
-                                   testcase->input_len);
-               isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH);
-               tohexstr(digest, ISC_SHA1_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
-/* HMAC-SHA224 test */
-ATF_TC(isc_hmacsha224);
-ATF_TC_HEAD(isc_hmacsha224, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-SHA224 examples from RFC4634");
-}
-ATF_TC_BODY(isc_hmacsha224, tc) {
-       isc_hmacsha224_t hmacsha224;
-
-       UNUSED(tc);
-
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "896FB1128ABBDF196832107CD49DF33F47B4B1169912BA"
-                               "4F53684B22",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
-                                  "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
-                                  "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E61480"
-                               "08FD05E44",
-                       1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69"
-                               "D1EC8333EA",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC01"
-                               "2DE7AFEC5A",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-#endif
-               /* Test 6 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7"
-                               "273FA6870E",
-                       1
-               },
-               /* Test 7 */
-               {
-                       TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
-                                  "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
-                                  "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
-                                  "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
-                                  "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
-                                  "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
-                                  "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
-                                  "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
-                                  "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
-                                  "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
-                                  "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
-                                  "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
-                                  "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
-                                  "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
-                                  "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
-                                  "\x6d\x2e"),
-                       "3A854166AC5D9F023F54D517D0B39DBD946770DB9C2B95"
-                               "C9F6F565D1",
-                       1
-               },
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-#endif
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacsha224_init(&hmacsha224, buffer, test_key->len);
-               isc_hmacsha224_update(&hmacsha224,
-                                     (const uint8_t *) testcase->input,
-                                     testcase->input_len);
-               isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH);
-               tohexstr(digest, ISC_SHA224_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
-/* HMAC-SHA256 test */
-ATF_TC(isc_hmacsha256);
-ATF_TC_HEAD(isc_hmacsha256, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-SHA256 examples from RFC4634");
-}
-ATF_TC_BODY(isc_hmacsha256, tc) {
-       isc_hmacsha256_t hmacsha256;
-
-       UNUSED(tc);
-
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "B0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833D"
-                               "A726E9376C2E32CFF7",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
-                                  "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
-                                  "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "5BDCC146BF60754E6A042426089575C75A003F089D2739"
-                               "839DEC58B964EC3843",
-                       1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "773EA91E36800E46854DB8EBD09181A72959098B3EF8C1"
-                               "22D9635514CED565FE",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8"
-                               "077A2E3FF46729665B",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-#endif
-               /* Test 6 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5"
-                               "140546040F0EE37F54",
-                       1
-               },
-               /* Test 7 */
-               {
-                       TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
-                                  "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
-                                  "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
-                                  "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
-                                  "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
-                                  "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
-                                  "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
-                                  "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
-                                  "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
-                                  "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
-                                  "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
-                                  "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
-                                  "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
-                                  "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
-                                  "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
-                                  "\x6d\x2e"),
-                       "9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713"
-                               "938A7F51535C3A35E2",
-                       1
-               },
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-#endif
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacsha256_init(&hmacsha256, buffer, test_key->len);
-               isc_hmacsha256_update(&hmacsha256,
-                                     (const uint8_t *) testcase->input,
-                                     testcase->input_len);
-               isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH);
-               tohexstr(digest, ISC_SHA256_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
-/* HMAC-SHA384 test */
-ATF_TC(isc_hmacsha384);
-ATF_TC_HEAD(isc_hmacsha384, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-SHA384 examples from RFC4634");
-}
-ATF_TC_BODY(isc_hmacsha384, tc) {
-       isc_hmacsha384_t hmacsha384;
-
-       UNUSED(tc);
-
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "AFD03944D84895626B0825F4AB46907F15F9DADBE4101E"
-                               "C682AA034C7CEBC59CFAEA9EA9076EDE7F4AF152"
-                               "E8B2FA9CB6",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
-                                  "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
-                                  "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B"
-                               "47E42EC3736322445E8E2240CA5E69E2C78B3239"
-                               "ECFAB21649",
-                       1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9F"
-                               "EBE83EF4E55966144B2A5AB39DC13814B94E3AB6"
-                               "E101A34F27",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "3E8A69B7783C25851933AB6290AF6CA77A998148085000"
-                               "9CC5577C6E1F573B4E6801DD23C4A7D679CCF8A3"
-                               "86C674CFFB",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-#endif
-               /* Test 6 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B58"
-                               "8F3CD11F05033AC4C60C2EF6AB4030FE8296248D"
-                               "F163F44952",
-                       1
-               },
-               /* Test 7 */
-               {
-                       TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
-                                  "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
-                                  "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
-                                  "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
-                                  "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
-                                  "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
-                                  "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
-                                  "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
-                                  "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
-                                  "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
-                                  "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
-                                  "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
-                                  "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
-                                  "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
-                                  "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
-                                  "\x6d\x2e"),
-                       "6617178E941F020D351E2F254E8FD32C602420FEB0B8FB"
-                               "9ADCCEBB82461E99C5A678CC31E799176D3860E6"
-                               "110C46523E",
-                       1
-               },
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-#endif
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacsha384_init(&hmacsha384, buffer, test_key->len);
-               isc_hmacsha384_update(&hmacsha384,
-                                     (const uint8_t *) testcase->input,
-                                     testcase->input_len);
-               isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH);
-               tohexstr(digest, ISC_SHA384_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
-/* HMAC-SHA512 test */
-ATF_TC(isc_hmacsha512);
-ATF_TC_HEAD(isc_hmacsha512, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-SHA512 examples from RFC4634");
-}
-ATF_TC_BODY(isc_hmacsha512, tc) {
-       isc_hmacsha512_t hmacsha512;
-
-       UNUSED(tc);
-
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2"
-                               "787AD0B30545E17CDEDAA833B7D6B8A702038B27"
-                               "4EAEA3F4E4BE9D914EEB61F1702E696C203A126854",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
-                                  "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
-                                  "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831F"
-                               "D610270CD7EA2505549758BF75C05A994A6D034F"
-                               "65F8F0E6FDCAEAB1A34D4A6B4B636E070A38BCE737",
-                       1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "FA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A"
-                               "3655F83E33B2279D39BF3E848279A722C806B485"
-                               "A47E67C807B946A337BEE8942674278859E13292FB",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B87"
-                               "2DE76F8050361EE3DBA91CA5C11AA25EB4D67927"
-                               "5CC5788063A5F19741120C4F2DE2ADEBEB10A298DD",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-#endif
-               /* Test 6 */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEE"
-                               "C1121B013783F8F3526B56D037E05F2598BD0FD2"
-                               "215D6A1E5295E64F73F63F0AEC8B915A985D786598",
-                       1
-               },
-               /* Test 7 */
-               {
-                       TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
-                                  "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
-                                  "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
-                                  "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
-                                  "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
-                                  "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
-                                  "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
-                                  "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
-                                  "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
-                                  "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
-                                  "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
-                                  "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
-                                  "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
-                                  "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
-                                  "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
-                                  "\x6d\x2e"),
-                       "E37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289"
-                               "865DF5A32D20CDC944B6022CAC3C4982B10D5EEB"
-                               "55C3E4DE15134676FB6DE0446065C97440FA8C6A58",
-                       1
-               },
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-#endif
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacsha512_init(&hmacsha512, buffer, test_key->len);
-               isc_hmacsha512_update(&hmacsha512,
-                                     (const uint8_t *) testcase->input,
-                                     testcase->input_len);
-               isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH);
-               tohexstr(digest, ISC_SHA512_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
-
-/* HMAC-MD5 Test */
-ATF_TC(isc_hmacmd5);
-ATF_TC_HEAD(isc_hmacmd5, tc) {
-       atf_tc_set_md_var(tc, "descr", "HMAC-MD5 examples from RFC2104");
-}
-ATF_TC_BODY(isc_hmacmd5, tc) {
-       isc_hmacmd5_t hmacmd5;
-
-       UNUSED(tc);
-
-       /*
-        * These are the various test vectors.  All of these are passed
-        * through the hash function and the results are compared to the
-        * result specified here.
-        */
-       hash_testcase_t testcases[] = {
-               /* Test 1 */
-               {
-                       TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
-                       "9294727A3638BB1C13F48EF8158BFC9D",
-                       1
-               },
-               /* Test 2 */
-               {
-                       TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79"
-                                  "\x61\x20\x77\x61\x6e\x74\x20\x66\x6f"
-                                  "\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
-                       "750C783E6AB0B503EAA86E310A5DB738", 1
-               },
-               /* Test 3 */
-               {
-                       TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-                                  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
-                       "56BE34521D144C88DBB8C733F0E8B3F6",
-                       1
-               },
-               /* Test 4 */
-               {
-                       TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                                  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
-                       "697EAF0ACA3A3AEA3A75164746FFAA79",
-                       1
-               },
-#if 0
-               /* Test 5 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test With Truncation"),
-                       "4C1A03424B55E07FE7F27BE1",
-                       1
-               },
-               /* Test 6 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key - "
-                                  "Hash Key First"),
-                       "AA4AE5E15272D00E95705637CE8A3B55ED402112",
-                       1
-                },
-               /* Test 7 -- unimplemented optional functionality */
-               {
-                       TEST_INPUT("Test Using Larger Than Block-Size Key and "
-                                  "Larger Than One Block-Size Data"),
-                       "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
-                       1
-               },
-#endif
-               { NULL, 0, NULL, 1 }
-       };
-
-       hash_testcase_t *testcase = testcases;
-
-       hash_test_key_t test_keys[] = {
-               /* Key 1 */
-               { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                 "\x0b\x0b\x0b\x0b\x0b\x0b", 16 },
-               /* Key 2 */
-               { "Jefe", 4 },
-               /* Key 3 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa", 16 },
-               /* Key 4 */
-               { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
-                 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
-                 "\x15\x16\x17\x18\x19", 25 },
-#if 0
-               /* Key 5 */
-               { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 },
-               /* Key 6 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-               /* Key 7 */
-               { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 },
-#endif
-               { "", 0 }
-       };
-
-       hash_test_key_t *test_key = test_keys;
-
-       while (testcase->input != NULL && testcase->result != NULL) {
-               memmove(buffer, test_key->key, test_key->len);
-               isc_hmacmd5_init(&hmacmd5, buffer, test_key->len);
-               isc_hmacmd5_update(&hmacmd5,
-                                  (const uint8_t *) testcase->input,
-                                  testcase->input_len);
-               isc_hmacmd5_sign(&hmacmd5, digest);
-               tohexstr(digest, ISC_MD5_DIGESTLENGTH, str, sizeof(str));
-               ATF_CHECK_STREQ(str, testcase->result);
-
-               testcase++;
-               test_key++;
-       }
-}
-
 /* CRC64 Test */
 ATF_TC(isc_crc64);
 ATF_TC_HEAD(isc_crc64, tc) {
@@ -1055,6 +88,8 @@ ATF_TC_BODY(isc_crc64, tc) {
        hash_testcase_t *testcase = testcases;
 
        while (testcase->input != NULL && testcase->result != NULL) {
+               char str[19];
+
                isc_crc64_init(&crc);
                for(i = 0; i < testcase->repeats; i++) {
                        isc_crc64_update(&crc,
@@ -1199,13 +234,6 @@ ATF_TP_ADD_TCS(tp) {
        ATF_TP_ADD_TC(tp, isc_hash_function);
        ATF_TP_ADD_TC(tp, isc_hash_function_reverse);
        ATF_TP_ADD_TC(tp, isc_hash_initializer);
-       ATF_TP_ADD_TC(tp, isc_hmacmd5);
-       ATF_TP_ADD_TC(tp, isc_hmacsha1);
-       ATF_TP_ADD_TC(tp, isc_hmacsha224);
-       ATF_TP_ADD_TC(tp, isc_hmacsha256);
-       ATF_TP_ADD_TC(tp, isc_hmacsha384);
-       ATF_TP_ADD_TC(tp, isc_hmacsha512);
-
        ATF_TP_ADD_TC(tp, isc_crc64);
 
        return (atf_no_error());
diff --git a/lib/isc/tests/hmac_test.c b/lib/isc/tests/hmac_test.c
new file mode 100644 (file)
index 0000000..d8fa7be
--- /dev/null
@@ -0,0 +1,962 @@
+/*
+ * 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.
+ */
+
+/* ! \file */
+
+#include <config.h>
+
+#if HAVE_CMOCKA
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdlib.h>
+
+#include <string.h>
+
+#define UNIT_TESTING
+#include <cmocka.h>
+
+#include <isc/buffer.h>
+#include <isc/hex.h>
+#include <isc/region.h>
+#include <isc/result.h>
+#include <isc/hmac.h>
+
+#include "../hmac.c"
+
+#define TEST_INPUT(x) (x), sizeof(x)-1
+
+static int
+_setup(void **state) {
+       isc_hmac_t *hmac = isc_hmac_new();
+       if (hmac == NULL) {
+               return (-1);
+       }
+       *state = hmac;
+       return (0);
+}
+
+static int
+_teardown(void **state) {
+       if (*state == NULL) {
+               return (-1);
+       }
+       isc_hmac_free(*state);
+       return (0);
+}
+
+static int
+_reset(void **state) {
+       if (*state == NULL) {
+               return (-1);
+       }
+       if (isc_hmac_reset(*state) != ISC_R_SUCCESS) {
+               return (-1);
+       }
+       return (0);
+}
+
+static void
+isc_hmac_new_test(void **state) {
+       UNUSED(state);
+
+       isc_hmac_t *hmac = isc_hmac_new();
+       assert_non_null(hmac);
+       isc_hmac_free(hmac); /* Cleanup */
+}
+
+static void
+isc_hmac_free_test(void **state) {
+       UNUSED(state);
+
+       isc_hmac_t *hmac = isc_hmac_new();
+       assert_non_null(hmac);
+       isc_hmac_free(hmac); /* Test freeing valid message digest context */
+       isc_hmac_free(NULL); /* Test freeing NULL argument */
+}
+
+static void
+isc_hmac_test(isc_hmac_t *hmac, const void *key, size_t keylen,
+             isc_md_type_t type, const char *buf, size_t buflen,
+             const char *result, const int repeats)
+{
+       assert_non_null(hmac);
+       assert_int_equal(isc_hmac_init(hmac, key, keylen, type), ISC_R_SUCCESS);
+
+       int i;
+
+       for (i = 0; i < repeats; i++) {
+               assert_int_equal(
+                       isc_hmac_update(hmac,
+                                       (const unsigned char *)buf, buflen),
+                       ISC_R_SUCCESS);
+       }
+
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       unsigned int digestlen;
+       assert_int_equal(isc_hmac_final(hmac, digest, &digestlen),
+                        ISC_R_SUCCESS);
+
+       char hexdigest[ISC_MAX_MD_SIZE * 2 + 3];
+       isc_region_t r = { .base = digest,
+                          .length = digestlen
+       };
+       isc_buffer_t b;
+       isc_buffer_init(&b, hexdigest, sizeof(hexdigest));
+
+       assert_return_code(isc_hex_totext(&r, 0, "", &b), ISC_R_SUCCESS);
+
+       assert_memory_equal(hexdigest, result, (result?strlen(result):0));
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+}
+
+static void
+isc_hmac_init_test(void **state) {
+       isc_hmac_t *hmac = *state;
+       assert_non_null(hmac);
+
+       expect_assert_failure(isc_hmac_init(NULL, "", 0, ISC_MD_MD5));
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, NULL),
+                        ISC_R_NOTIMPLEMENTED);
+
+       expect_assert_failure(isc_hmac_init(hmac, NULL, 0, ISC_MD_MD5));
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_MD5), ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA1),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA224),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA256),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA384),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA512),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+}
+
+static void
+isc_hmac_update_test(void **state) {
+       isc_hmac_t *hmac = *state;
+       assert_non_null(hmac);
+
+       /* Uses message digest context initialized in isc_hmac_init_test() */
+       expect_assert_failure(isc_hmac_update(NULL, NULL, 0));
+
+       assert_int_equal(isc_hmac_update(hmac, NULL, 100), ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_update(hmac, (const unsigned char *)"", 0),
+                        ISC_R_SUCCESS);
+}
+
+static void
+isc_hmac_reset_test(void **state) {
+       isc_hmac_t *hmac = *state;
+       unsigned char digest[ISC_MAX_MD_SIZE] __attribute((unused));
+       unsigned int digestlen __attribute((unused));
+
+       assert_non_null(hmac);
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA512),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_update(hmac, (const unsigned char *)"a", 1),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_update(hmac, (const unsigned char *)"b", 1),
+                        ISC_R_SUCCESS);
+
+       assert_int_equal(isc_hmac_reset(hmac), ISC_R_SUCCESS);
+
+#if 0
+       /*
+        * This test would require OpenSSL compiled with mock_assert(),
+        * so this could be only manually checked that the test will
+        * segfault when called by hand
+        */
+       expect_assert_failure(isc_hmac_final(hmac, digest, &digestlen));
+#endif
+}
+
+static void
+isc_hmac_final_test(void **state) {
+       isc_hmac_t *hmac = *state;
+       assert_non_null(hmac);
+
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       unsigned int digestlen;
+
+       /* Fail when message digest context is empty */
+       expect_assert_failure(isc_hmac_final(NULL, digest, &digestlen));
+       /* Fail when output buffer is empty */
+       expect_assert_failure(isc_hmac_final(hmac, NULL, &digestlen));
+
+       assert_int_equal(isc_hmac_init(hmac, "", 0, ISC_MD_SHA512),
+                        ISC_R_SUCCESS);
+       assert_int_equal(isc_hmac_final(hmac, digest, NULL), ISC_R_SUCCESS);
+}
+
+static void
+isc_hmac_md5_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_MD5, TEST_INPUT(""),
+                     "74E6F7298A9C2D168935F58C001BAD88",
+                     1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "9294727A3638BB1C13F48EF8158BFC9D",
+                     1);
+
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79"
+                                "\x61\x20\x77\x61\x6e\x74\x20\x66\x6f"
+                                "\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "750C783E6AB0B503EAA86E310A5DB738",
+                     1);
+
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "56BE34521D144C88DBB8C733F0E8B3F6",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "697EAF0ACA3A3AEA3A75164746FFAA79",
+                     1);
+#if 0
+       /* Test 5 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+       /* Test 6 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "AA4AE5E15272D00E95705637CE8A3B55ED402112",
+                     1);
+       /* Test 7 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_MD5,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key and "
+                                "Larger Than One Block-Size Data"),
+                     "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
+                     1);
+#endif
+}
+
+static void
+isc_hmac_sha1_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA1, TEST_INPUT(""),
+                     "FBDB1D1B18AA6C08324B7D64B71FB76370690E1D",
+                     1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "B617318655057264E28BC0B6FB378C8EF146BE00",
+                     1);
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+                                "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+                                "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79",
+                     1);
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "125D7342B9AC11CD91A39AF48AA17B4F63F175D3",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "4C9007F4026250C6BC8414F9BF50C86C2D7235DA",
+                     1);
+#if 0
+       /* Test 5 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+#endif
+       /* Test 6 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "AA4AE5E15272D00E95705637CE8A3B55ED402112", 1);
+       /* Test 7 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA1,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key and "
+                                "Larger Than One Block-Size Data"),
+                     "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
+                     1);
+}
+
+static void
+isc_hmac_sha224_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA224, TEST_INPUT(""),
+                     "5CE14F72894662213E2748D2A6BA234B74263910CEDDE2F5"
+                     "A9271524",
+                     1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "896FB1128ABBDF196832107CD49DF33F47B4B1169912BA"
+                     "4F53684B22",
+                     1);
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+                                "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+                                "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E61480"
+                     "08FD05E44",
+                     1);
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69"
+                     "D1EC8333EA",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC01"
+                     "2DE7AFEC5A",
+                     1);
+#if 0
+       /* Test 5 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+#endif
+       /* Test 6 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7"
+                     "273FA6870E",
+                     1);
+       /* Test 7 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA224,
+                     TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+                                "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+                                "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+                                "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                                "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+                                "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+                                "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+                                "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                                "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+                                "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+                                "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+                                "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+                                "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+                                "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+                                "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+                                "\x6d\x2e"),
+                     "3A854166AC5D9F023F54D517D0B39DBD946770DB9C2B95"
+                     "C9F6F565D1",
+                     1);
+}
+
+static void
+isc_hmac_sha256_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA256, TEST_INPUT(""),
+                     "B613679A0814D9EC772F95D778C35FC5FF1697C493715653"
+                     "C6C712144292C5AD",
+                     1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "B0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833D"
+                     "A726E9376C2E32CFF7",
+                     1);
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+                                "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+                                "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "5BDCC146BF60754E6A042426089575C75A003F089D2739"
+                     "839DEC58B964EC3843",
+                     1);
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "773EA91E36800E46854DB8EBD09181A72959098B3EF8C1"
+                     "22D9635514CED565FE",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8"
+                     "077A2E3FF46729665B",
+                     1);
+#if 0
+       /* Test 5 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+#endif
+       /* Test 6 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5"
+                     "140546040F0EE37F54",
+                     1);
+       /* Test 7 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA256,
+                     TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+                                "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+                                "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+                                "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                                "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+                                "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+                                "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+                                "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                                "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+                                "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+                                "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+                                "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+                                "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+                                "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+                                "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+                                "\x6d\x2e"),
+                     "9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713"
+                     "938A7F51535C3A35E2",
+                     1);
+}
+
+static void
+isc_hmac_sha384_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA384, TEST_INPUT(""),
+                     "6C1F2EE938FAD2E24BD91298474382CA218C75DB3D83E114"
+                     "B3D4367776D14D3551289E75E8209CD4B792302840234ADC",
+                     1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "AFD03944D84895626B0825F4AB46907F15F9DADBE4101E"
+                     "C682AA034C7CEBC59CFAEA9EA9076EDE7F4AF152"
+                     "E8B2FA9CB6",
+                     1);
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+                                "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+                                "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B"
+                     "47E42EC3736322445E8E2240CA5E69E2C78B3239"
+                     "ECFAB21649",
+                     1);
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9F"
+                     "EBE83EF4E55966144B2A5AB39DC13814B94E3AB6"
+                     "E101A34F27",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "3E8A69B7783C25851933AB6290AF6CA77A998148085000"
+                     "9CC5577C6E1F573B4E6801DD23C4A7D679CCF8A3"
+                     "86C674CFFB",
+                     1);
+#if 0
+       /* Test 5 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+#endif
+       /* Test 6 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B58"
+                     "8F3CD11F05033AC4C60C2EF6AB4030FE8296248D"
+                     "F163F44952",
+                     1);
+       /* Test 7 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA384,
+                     TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+                                "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+                                "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+                                "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                                "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+                                "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+                                "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+                                "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                                "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+                                "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+                                "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+                                "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+                                "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+                                "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+                                "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+                                "\x6d\x2e"),
+                     "6617178E941F020D351E2F254E8FD32C602420FEB0B8FB"
+                     "9ADCCEBB82461E99C5A678CC31E799176D3860E6"
+                     "110C46523E",
+                     1);
+}
+
+static void
+isc_hmac_sha512_test(void **state) {
+       isc_hmac_t *hmac = *state;
+
+       /* Test 0 */
+       isc_hmac_test(hmac, TEST_INPUT(""), ISC_MD_SHA512, TEST_INPUT(""),
+                     "B936CEE86C9F87AA5D3C6F2E84CB5A4239A5FE50480A6EC6"
+                     "6B70AB5B1F4AC6730C6C515421B327EC1D69402E53DFB49A"
+                     "D7381EB067B338FD7B0CB22247225D47", 1);
+
+       /* Test 1 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                                "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"),
+                     "87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2"
+                     "787AD0B30545E17CDEDAA833B7D6B8A702038B27"
+                     "4EAEA3F4E4BE9D914EEB61F1702E696C203A126854",
+                     1);
+       /* Test 2 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("Jefe"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61"
+                                "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20"
+                                "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"),
+                     "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831F"
+                     "D610270CD7EA2505549758BF75C05A994A6D034F"
+                     "65F8F0E6FDCAEAB1A34D4A6B4B636E070A38BCE737",
+                     1);
+       /* Test 3 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                                "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"),
+                     "FA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A"
+                     "3655F83E33B2279D39BF3E848279A722C806B485"
+                     "A47E67C807B946A337BEE8942674278859E13292FB",
+                     1);
+       /* Test 4 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+                                "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+                                "\x15\x16\x17\x18\x19"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                                "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
+                     "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B87"
+                     "2DE76F8050361EE3DBA91CA5C11AA25EB4D67927"
+                     "5CC5788063A5F19741120C4F2DE2ADEBEB10A298DD",
+                     1);
+#if 0
+       /* Test 5 -- unimplemented optional functionality */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                                "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("Test With Truncation"),
+                     "4C1A03424B55E07FE7F27BE1",
+                     1);
+#endif
+       /* Test 6 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("Test Using Larger Than Block-Size Key - "
+                                "Hash Key First"),
+                     "80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEE"
+                     "C1121B013783F8F3526B56D037E05F2598BD0FD2"
+                     "215D6A1E5295E64F73F63F0AEC8B915A985D786598",
+                     1);
+       /* Test 7 */
+       isc_hmac_test(hmac,
+                     TEST_INPUT("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                                "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
+                     ISC_MD_SHA512,
+                     TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20"
+                                "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67"
+                                "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+                                "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                                "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20"
+                                "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+                                "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c"
+                                "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                                "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+                                "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74"
+                                "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65"
+                                "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+                                "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20"
+                                "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41"
+                                "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+                                "\x6d\x2e"),
+                     "E37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289"
+                     "865DF5A32D20CDC944B6022CAC3C4982B10D5EEB"
+                     "55C3E4DE15134676FB6DE0446065C97440FA8C6A58",
+                     1);
+}
+
+int main(void) {
+       const struct CMUnitTest tests[] = {
+               /* isc_hmac_new() */
+               cmocka_unit_test(isc_hmac_new_test),
+
+               /* isc_hmac_init() */
+               cmocka_unit_test_setup_teardown(isc_hmac_init_test,
+                                               _reset, _reset),
+
+               /* isc_hmac_reset() */
+               cmocka_unit_test_setup_teardown(isc_hmac_reset_test,
+                                               _reset, _reset),
+
+               /* isc_hmac_init() -> isc_hmac_update() -> isc_hmac_final() */
+               cmocka_unit_test(isc_hmac_md5_test),
+               cmocka_unit_test(isc_hmac_sha1_test),
+               cmocka_unit_test(isc_hmac_sha224_test),
+               cmocka_unit_test(isc_hmac_sha256_test),
+               cmocka_unit_test(isc_hmac_sha384_test),
+               cmocka_unit_test(isc_hmac_sha512_test),
+
+               cmocka_unit_test_setup_teardown(isc_hmac_update_test,
+                                               _reset, _reset),
+               cmocka_unit_test_setup_teardown(isc_hmac_final_test,
+                                               _reset, _reset),
+
+               cmocka_unit_test(isc_hmac_free_test),
+       };
+
+       return (cmocka_run_group_tests(tests, _setup, _teardown));
+}
+
+#else /* HAVE_CMOCKA */
+
+#include <stdio.h>
+
+int main(void) {
+       printf("1..0 # Skipped: cmocka not available\n");
+       return (0);
+}
+
+#endif
index 7847f2bb0e3a1ca16365bf024d1921def9177a6b..d450915169816443a39a265d0cbd1c0922fd37ca 100644 (file)
@@ -252,39 +252,16 @@ isc_heap_insert
 isc_hex_decodestring
 isc_hex_tobuffer
 isc_hex_totext
-isc_hmacmd5_check
-isc_hmacmd5_init
-isc_hmacmd5_invalidate
-isc_hmacmd5_sign
-isc_hmacmd5_update
-isc_hmacmd5_verify
-isc_hmacmd5_verify2
-isc_hmacsha1_check
-isc_hmacsha1_init
-isc_hmacsha1_invalidate
-isc_hmacsha1_sign
-isc_hmacsha1_update
-isc_hmacsha1_verify
-isc_hmacsha224_init
-isc_hmacsha224_invalidate
-isc_hmacsha224_sign
-isc_hmacsha224_update
-isc_hmacsha224_verify
-isc_hmacsha256_init
-isc_hmacsha256_invalidate
-isc_hmacsha256_sign
-isc_hmacsha256_update
-isc_hmacsha256_verify
-isc_hmacsha384_init
-isc_hmacsha384_invalidate
-isc_hmacsha384_sign
-isc_hmacsha384_update
-isc_hmacsha384_verify
-isc_hmacsha512_init
-isc_hmacsha512_invalidate
-isc_hmacsha512_sign
-isc_hmacsha512_update
-isc_hmacsha512_verify
+isc_hmac
+isc_hmac_new
+isc_hmac_free
+isc_hmac_init
+isc_hmac_reset
+isc_hmac_update
+isc_hmac_final
+isc_hmac_get_md_type
+isc_hmac_get_size
+isc_hmac_get_block_size
 isc_ht_add
 isc_ht_count
 isc_ht_delete
index e18b64a31637dfaefb1e62c65b5d7c4090a02277..48b317c8dcee35b4f51658f9b9ecca547c0e1267 100644 (file)
     <ClInclude Include="..\include\isc\hex.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\include\isc\hmacmd5.h">
-      <Filter>Library Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\isc\hmacsha.h">
+    <ClInclude Include="..\include\isc\hmac.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
     <ClInclude Include="..\include\isc\ht.h">
     <ClCompile Include="..\hex.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\hmacmd5.c">
-      <Filter>Library Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\hmacsha.c">
+    <ClCompile Include="..\hmac.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
     <ClCompile Include="..\ht.c">
index 7bf367814eefa263cea631ebca8e6f21dd5a4789..6cb8f5f371d8055eea5549a3b9ca69fc4e290b60 100644 (file)
@@ -314,8 +314,7 @@ copy InstallFiles ..\Build\Release\
     <ClInclude Include="..\include\isc\hash.h" />
     <ClInclude Include="..\include\isc\heap.h" />
     <ClInclude Include="..\include\isc\hex.h" />
-    <ClInclude Include="..\include\isc\hmacmd5.h" />
-    <ClInclude Include="..\include\isc\hmacsha.h" />
+    <ClInclude Include="..\include\isc\hmac.h" />
     <ClInclude Include="..\include\isc\ht.h" />
     <ClInclude Include="..\include\isc\httpd.h" />
     <ClInclude Include="..\include\isc\interfaceiter.h" />
@@ -430,8 +429,7 @@ copy InstallFiles ..\Build\Release\
     <ClCompile Include="..\hash.c" />
     <ClCompile Include="..\heap.c" />
     <ClCompile Include="..\hex.c" />
-    <ClCompile Include="..\hmacmd5.c" />
-    <ClCompile Include="..\hmacsha.c" />
+    <ClCompile Include="..\hmac.c" />
     <ClCompile Include="..\ht.c" />
     <ClCompile Include="..\httpd.c" />
     <ClCompile Include="..\iterated_hash.c" />
index 960da65523185c5de8401c9db0376164cfbdffc1..e86c4b782664cdad3915d9f3200f75e8067a5407 100644 (file)
@@ -34,8 +34,7 @@
 #include <errno.h>
 
 #include <isc/assertions.h>
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
 #include <isc/print.h>
 #include <isc/safe.h>
 
@@ -249,79 +248,47 @@ static isc_result_t
 sign(unsigned char *data, unsigned int length, unsigned char *hmac,
      uint32_t algorithm, isccc_region_t *secret)
 {
-       union {
-               isc_hmacmd5_t hmd5;
-               isc_hmacsha1_t hsha;
-               isc_hmacsha224_t h224;
-               isc_hmacsha256_t h256;
-               isc_hmacsha384_t h384;
-               isc_hmacsha512_t h512;
-       } ctx;
+       isc_md_type_t md_type;
        isc_result_t result;
        isccc_region_t source, target;
-       unsigned char digest[ISC_SHA512_DIGESTLENGTH];
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       unsigned int digestlen;
        unsigned char digestb64[HSHA_LENGTH + 4];
 
        source.rstart = digest;
 
        switch (algorithm) {
        case ISCCC_ALG_HMACMD5:
-               isc_hmacmd5_init(&ctx.hmd5, secret->rstart,
-                                REGION_SIZE(*secret));
-               isc_hmacmd5_update(&ctx.hmd5, data, length);
-               isc_hmacmd5_sign(&ctx.hmd5, digest);
-               source.rend = digest + ISC_MD5_DIGESTLENGTH;
+               md_type = ISC_MD_MD5;
                break;
-
        case ISCCC_ALG_HMACSHA1:
-               isc_hmacsha1_init(&ctx.hsha, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha1_update(&ctx.hsha, data, length);
-               isc_hmacsha1_sign(&ctx.hsha, digest,
-                                   ISC_SHA1_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA1_DIGESTLENGTH;
+               md_type = ISC_MD_SHA1;
                break;
-
        case ISCCC_ALG_HMACSHA224:
-               isc_hmacsha224_init(&ctx.h224, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha224_update(&ctx.h224, data, length);
-               isc_hmacsha224_sign(&ctx.h224, digest,
-                                   ISC_SHA224_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA224_DIGESTLENGTH;
+               md_type = ISC_MD_SHA224;
                break;
-
        case ISCCC_ALG_HMACSHA256:
-               isc_hmacsha256_init(&ctx.h256, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha256_update(&ctx.h256, data, length);
-               isc_hmacsha256_sign(&ctx.h256, digest,
-                                   ISC_SHA256_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA256_DIGESTLENGTH;
+               md_type = ISC_MD_SHA256;
                break;
-
        case ISCCC_ALG_HMACSHA384:
-               isc_hmacsha384_init(&ctx.h384, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha384_update(&ctx.h384, data, length);
-               isc_hmacsha384_sign(&ctx.h384, digest,
-                                   ISC_SHA384_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA384_DIGESTLENGTH;
+               md_type = ISC_MD_SHA384;
                break;
-
        case ISCCC_ALG_HMACSHA512:
-               isc_hmacsha512_init(&ctx.h512, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha512_update(&ctx.h512, data, length);
-               isc_hmacsha512_sign(&ctx.h512, digest,
-                                   ISC_SHA512_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA512_DIGESTLENGTH;
+               md_type = ISC_MD_SHA512;
                break;
-
        default:
-               return (ISC_R_FAILURE);
+               return (ISC_R_NOTIMPLEMENTED);
        }
 
+       result = isc_hmac(md_type,
+                         secret->rstart, REGION_SIZE(*secret),
+                         data, length,
+                         digest, &digestlen);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
+       source.rend = digest + digestlen;
+
        memset(digestb64, 0, sizeof(digestb64));
        target.rstart = digestb64;
        target.rend = digestb64 + sizeof(digestb64);
@@ -401,19 +368,13 @@ static isc_result_t
 verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
        uint32_t algorithm, isccc_region_t *secret)
 {
-       union {
-               isc_hmacmd5_t hmd5;
-               isc_hmacsha1_t hsha;
-               isc_hmacsha224_t h224;
-               isc_hmacsha256_t h256;
-               isc_hmacsha384_t h384;
-               isc_hmacsha512_t h512;
-       } ctx;
+       isc_md_type_t md_type;
        isccc_region_t source;
        isccc_region_t target;
        isc_result_t result;
        isccc_sexpr_t *_auth, *hmac;
-       unsigned char digest[ISC_SHA512_DIGESTLENGTH];
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       unsigned int digestlen;
        unsigned char digestb64[HSHA_LENGTH * 4];
 
        /*
@@ -432,64 +393,39 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
         * Compute digest.
         */
        source.rstart = digest;
-       target.rstart = digestb64;
+
        switch (algorithm) {
        case ISCCC_ALG_HMACMD5:
-               isc_hmacmd5_init(&ctx.hmd5, secret->rstart,
-                                REGION_SIZE(*secret));
-               isc_hmacmd5_update(&ctx.hmd5, data, length);
-               isc_hmacmd5_sign(&ctx.hmd5, digest);
-               source.rend = digest + ISC_MD5_DIGESTLENGTH;
+               md_type = ISC_MD_MD5;
                break;
-
        case ISCCC_ALG_HMACSHA1:
-               isc_hmacsha1_init(&ctx.hsha, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha1_update(&ctx.hsha, data, length);
-               isc_hmacsha1_sign(&ctx.hsha, digest,
-                                   ISC_SHA1_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA1_DIGESTLENGTH;
+               md_type = ISC_MD_SHA1;
                break;
-
        case ISCCC_ALG_HMACSHA224:
-               isc_hmacsha224_init(&ctx.h224, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha224_update(&ctx.h224, data, length);
-               isc_hmacsha224_sign(&ctx.h224, digest,
-                                   ISC_SHA224_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA224_DIGESTLENGTH;
+               md_type = ISC_MD_SHA224;
                break;
-
        case ISCCC_ALG_HMACSHA256:
-               isc_hmacsha256_init(&ctx.h256, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha256_update(&ctx.h256, data, length);
-               isc_hmacsha256_sign(&ctx.h256, digest,
-                                   ISC_SHA256_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA256_DIGESTLENGTH;
+               md_type = ISC_MD_SHA256;
                break;
-
        case ISCCC_ALG_HMACSHA384:
-               isc_hmacsha384_init(&ctx.h384, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha384_update(&ctx.h384, data, length);
-               isc_hmacsha384_sign(&ctx.h384, digest,
-                                   ISC_SHA384_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA384_DIGESTLENGTH;
+               md_type = ISC_MD_SHA384;
                break;
-
        case ISCCC_ALG_HMACSHA512:
-               isc_hmacsha512_init(&ctx.h512, secret->rstart,
-                                   REGION_SIZE(*secret));
-               isc_hmacsha512_update(&ctx.h512, data, length);
-               isc_hmacsha512_sign(&ctx.h512, digest,
-                                   ISC_SHA512_DIGESTLENGTH);
-               source.rend = digest + ISC_SHA512_DIGESTLENGTH;
+               md_type = ISC_MD_SHA512;
                break;
-
        default:
-               return (ISC_R_FAILURE);
+               return (ISC_R_NOTIMPLEMENTED);
+       }
+
+       result = isc_hmac(md_type,
+                         secret->rstart, REGION_SIZE(*secret),
+                         data, length,
+                         digest, &digestlen);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
        }
+       source.rend = digest + digestlen;
+
        target.rstart = digestb64;
        target.rend = digestb64 + sizeof(digestb64);
        memset(digestb64, 0, sizeof(digestb64));
index b5c3175dc2ca7ca67452de6f46f43d3c5d8aab18..32c8ddfe2200d04509201223a9c823e5513ac2cb 100644 (file)
@@ -17,7 +17,7 @@
 #include <isc/aes.h>
 #include <isc/formatcheck.h>
 #include <isc/fuzz.h>
-#include <isc/hmacsha.h>
+#include <isc/hmac.h>
 #include <isc/mutex.h>
 #include <isc/once.h>
 #include <isc/nonce.h>
@@ -1824,74 +1824,52 @@ compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
                break;
        }
 
-       case ns_cookiealg_sha1: {
-               unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+       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;
-               isc_hmacsha1_t hmacsha1;
-               unsigned int length;
+               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_hmacsha1_init(&hmacsha1, secret, ISC_SHA1_DIGESTLENGTH);
-               isc_hmacsha1_update(&hmacsha1, cp, 16);
                isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
                switch (netaddr.family) {
                case AF_INET:
-                       cp = (unsigned char *)&netaddr.type.in;
-                       length = 4;
+                       memmove(input + 16,
+                               (unsigned char *)&netaddr.type.in, 4);
+                       length = 16 + 4;
                        break;
                case AF_INET6:
-                       cp = (unsigned char *)&netaddr.type.in6;
-                       length = 16;
+                       memmove(input + 16,
+                               (unsigned char *)&netaddr.type.in6, 16);
+                       length = 16 + 16;
                        break;
                default:
                        INSIST(0);
                }
-               isc_hmacsha1_update(&hmacsha1, cp, length);
-               isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
-               isc_buffer_putmem(buf, digest, 8);
-               isc_hmacsha1_invalidate(&hmacsha1);
-               break;
-       }
 
-       case ns_cookiealg_sha256: {
-               unsigned char digest[ISC_SHA256_DIGESTLENGTH];
-               isc_netaddr_t netaddr;
-               unsigned char *cp;
-               isc_hmacsha256_t hmacsha256;
-               unsigned int length;
-
-               cp = isc_buffer_used(buf);
-               isc_buffer_putmem(buf, client->cookie, 8);
-               isc_buffer_putuint32(buf, nonce);
-               isc_buffer_putuint32(buf, when);
+               /*
+                * 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);
 
-               isc_hmacsha256_init(&hmacsha256, secret,
-                                   ISC_SHA256_DIGESTLENGTH);
-               isc_hmacsha256_update(&hmacsha256, cp, 16);
-               isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
-               switch (netaddr.family) {
-               case AF_INET:
-                       cp = (unsigned char *)&netaddr.type.in;
-                       length = 4;
-                       break;
-               case AF_INET6:
-                       cp = (unsigned char *)&netaddr.type.in6;
-                       length = 16;
-                       break;
-               default:
-                       INSIST(0);
-               }
-               isc_hmacsha256_update(&hmacsha256, cp, length);
-               isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
                isc_buffer_putmem(buf, digest, 8);
-               isc_hmacsha256_invalidate(&hmacsha256);
                break;
        }
+
        default:
                INSIST(0);
        }
index 5e2a74d6c51a8c995b9494e6e830b2f6173f73d8..e1bf381c9fa30fe7bc77cea0dc8bd06945b1ffde 100644 (file)
 ./bin/tests/optional/dst_test.c                        C       2018
 ./bin/tests/optional/fsaccess_test.c           C       2000,2001,2004,2005,2007,2012,2015,2016,2018
 ./bin/tests/optional/gsstest.c                 C       2018
-./bin/tests/optional/hash_test.c               C       2000,2001,2004,2005,2006,2007,2014,2015,2016,2017,2018
 ./bin/tests/optional/inter_test.c              C       2000,2001,2003,2004,2005,2007,2008,2015,2016,2018
 ./bin/tests/optional/lex_test.c                        C       1998,1999,2000,2001,2004,2005,2007,2015,2016,2018
 ./bin/tests/optional/lfsr_test.c               C       1999,2000,2001,2004,2005,2007,2015,2016,2018
 ./lib/isc/hash.c                               C       2003,2004,2005,2006,2007,2009,2013,2014,2015,2016,2017,2018
 ./lib/isc/heap.c                               C       1997,1998,1999,2000,2001,2004,2005,2006,2007,2010,2011,2012,2013,2014,2015,2016,2017,2018
 ./lib/isc/hex.c                                        C       2000,2001,2002,2003,2004,2005,2007,2008,2013,2014,2015,2016,2018
-./lib/isc/hmacmd5.c                            C       2000,2001,2004,2005,2006,2007,2009,2013,2014,2015,2016,2017,2018
-./lib/isc/hmacsha.c                            C       2005,2006,2007,2009,2011,2012,2013,2014,2015,2016,2017,2018
+./lib/isc/hmac.c                               C       2000,2001,2004,2005,2006,2007,2009,2011,2012,2013,2014,2015,2016,2017,2018
 ./lib/isc/ht.c                                 C       2016,2017,2018
 ./lib/isc/httpd.c                              C       2006,2007,2008,2010,2011,2012,2013,2014,2015,2016,2017,2018
 ./lib/isc/include/Makefile.in                  MAKE    1998,1999,2000,2001,2004,2007,2012,2014,2016,2018
 ./lib/isc/include/isc/hash.h                   C       2003,2004,2005,2006,2007,2009,2013,2014,2015,2016,2017,2018
 ./lib/isc/include/isc/heap.h                   C       1997,1998,1999,2000,2001,2004,2005,2006,2007,2009,2012,2016,2018
 ./lib/isc/include/isc/hex.h                    C       2000,2001,2004,2005,2006,2007,2008,2016,2018
-./lib/isc/include/isc/hmacmd5.h                        C       2000,2001,2004,2005,2006,2007,2009,2014,2016,2017,2018
-./lib/isc/include/isc/hmacsha.h                        C       2005,2006,2007,2009,2014,2016,2017,2018
+./lib/isc/include/isc/hmac.h                   C       2000,2001,2004,2005,2006,2007,2009,2011,2012,2013,2014,2015,2016,2017,2018
 ./lib/isc/include/isc/ht.h                     C       2016,2017,2018
 ./lib/isc/include/isc/httpd.h                  C       2006,2007,2008,2014,2016,2018
 ./lib/isc/include/isc/interfaceiter.h          C       1999,2000,2001,2004,2005,2006,2007,2016,2018
 ./lib/isc/tests/file_test.c                    C       2014,2016,2017,2018
 ./lib/isc/tests/hash_test.c                    C       2011,2012,2013,2014,2015,2016,2017,2018
 ./lib/isc/tests/heap_test.c                    C       2017,2018
+./lib/isc/tests/hmac_test.c                    C       2018
 ./lib/isc/tests/ht_test.c                      C       2016,2017,2018
 ./lib/isc/tests/isctest.c                      C       2011,2012,2013,2014,2016,2017,2018
 ./lib/isc/tests/isctest.h                      C       2011,2012,2016,2018