diff --git a/bin/named/server.c b/bin/named/server.c index 58b8b4678a..c1839f98fe 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/bin/tests/optional/Makefile.in b/bin/tests/optional/Makefile.in index 8e3e4f3248..856899f81a 100644 --- a/bin/tests/optional/Makefile.in +++ b/bin/tests/optional/Makefile.in @@ -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 index 64a0839e1a..0000000000 --- a/bin/tests/optional/hash_test.c +++ /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 - -#include -#include - -#include -#include -#include -#include -#include - -#include - -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); -} diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 82b619fdaa..c30269447c 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index b8ef410128..f2d95f1723 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -38,8 +38,7 @@ #include #include #include -#include -#include +#include #if USE_PKCS11 #include @@ -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; diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index 80fb179a08..d4222cc67d 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -26,13 +26,13 @@ #include #include +#include #include -#include -#include +#include +#include #include #include -#include #include #include #include @@ -48,182 +48,317 @@ #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 -struct dst_hmacmd5_key { - unsigned char key[ISC_HMAC_MAX_MD_CBLOCK]; +#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_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_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); + } + + dctx->ctxdata.hmac_ctx = ctx; + return (ISC_R_SUCCESS); +} + +static inline void +hmac_destroyctx(dst_context_t *dctx) { + isc_hmac_t *ctx = dctx->ctxdata.hmac_ctx; + REQUIRE(ctx != NULL); + + isc_hmac_free(ctx); + dctx->ctxdata.hmac_ctx = NULL; +} + +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; + + REQUIRE(ctx != NULL); + + result = isc_hmac_update(ctx, data->base, data->length); + if (result != ISC_R_SUCCESS) { + return (DST_R_OPENSSLFAILURE); + } + + return (ISC_R_SUCCESS); +} + +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]; + + if (isc_hmac_final(ctx, digest, &digestlen) != ISC_R_SUCCESS) { + return (DST_R_OPENSSLFAILURE); + } + + if (isc_hmac_reset(ctx) != ISC_R_SUCCESS) { + return (DST_R_OPENSSLFAILURE); + } + + if (isc_buffer_availablelength(sig) < digestlen) { + return (ISC_R_NOSPACE); + } + + isc_buffer_putmem(sig, digest, digestlen); + + return (ISC_R_SUCCESS); +} + +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]; + + REQUIRE(ctx != NULL); + + if (isc_hmac_final(ctx, digest, &digestlen) != ISC_R_SUCCESS) { + return (DST_R_OPENSSLFAILURE); + } + + if (isc_hmac_reset(ctx) != ISC_R_SUCCESS) { + return (DST_R_OPENSSLFAILURE); + } + + if (sig->length > digestlen) { + return (DST_R_VERIFYFAILURE); + } + + return (isc_safe_memequal(digest, sig->base, sig->length) ? + ISC_R_SUCCESS : + DST_R_VERIFYFAILURE); +} + +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.hmac_key; + hkey2 = key2->keydata.hmac_key; + + if (hkey1 == NULL && hkey2 == NULL) { + return (true); + } else if (hkey1 == NULL || hkey2 == NULL) { + return (false); + } + + return (isc_safe_memequal(hkey1->key, hkey2->key, + isc_md_type_get_block_size(type))); +} + +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_MD5_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_MD5_BLOCK_LENGTH) { - bytes = ISC_MD5_BLOCK_LENGTH; - key->key_size = ISC_MD5_BLOCK_LENGTH * 8; + + if (bytes > len) { + bytes = len; + key->key_size = len * 8; } - 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); + + ret = hmac_fromdns(type, key, &b); + isc_safe_memwipe(data, sizeof(data)); return (ret); } -static bool -hmacmd5_isprivate(const dst_key_t *key) { +static inline bool +hmac_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; - +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.hmacmd5 = NULL; + key->keydata.hmac_key = NULL; } -static isc_result_t -hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacmd5_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.hmacmd5 != NULL); - - hkey = key->keydata.hmacmd5; + 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 -hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacmd5_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_hmacmd5_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_MD5_BLOCK_LENGTH) { - res = isc_md(ISC_MD_MD5, r.base, r.length, - hkey->key, &keylen); - 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); @@ -231,45 +366,106 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { } key->key_size = keylen * 8; - key->keydata.hmacmd5 = hkey; + key->keydata.hmac_key = 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; +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.hmacmd5 == NULL) + if (key->keydata.hmac_key == NULL) { return (DST_R_NULLKEY); + } - if (key->external) + if (key->external) { return (DST_R_EXTERNALKEY); + } - hkey = key->keydata.hmacmd5; + hkey = key->keydata.hmac_key; - priv.elements[cnt].tag = TAG_HMACMD5_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; + priv.elements[0].tag = hmac__get_tag_key(type); + priv.elements[0].length = bytes; + priv.elements[0].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; + bits = htons(key->key_bits); + + 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 -hmacmd5_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; @@ -278,1485 +474,43 @@ hmacmd5_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_HMACMD5, 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: - 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; - } - } - 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); - } -#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; - } -} - -static isc_result_t -hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - - 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; - - 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); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - - if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha1_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha1; - hkey2 = key2->keydata.hmacsha1; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - 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); -} - -static isc_result_t -hmacsha1_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_SHA1_BLOCK_LENGTH]; - - UNUSED(pseudorandom_ok); - UNUSED(callback); - - 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; - } - - 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); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha1_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; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha1 = NULL; -} - -static isc_result_t -hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha1_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha1 != NULL); - - hkey = key->keydata.hmacsha1; - - 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 -hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha1_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_hmacsha1_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); - } - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha1 = 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; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha1 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha1; - - priv.elements[cnt].tag = TAG_HMACSHA1_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_HMACSHA1_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 -hmacsha1_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_HMACSHA1, 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_HMACSHA1_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) - result = tresult; - break; - case TAG_HMACSHA1_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 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) + 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; @@ -1768,36 +522,11 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 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 */ diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c index 7343ed3508..ef452d58fd 100644 --- a/lib/dns/pkcs11rsa_link.c +++ b/lib/dns/pkcs11rsa_link.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index f2b81e7ca3..06ad322a27 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -32,7 +32,7 @@ #ifdef AES_CC #include #else -#include +#include #endif #include @@ -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 } diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index 69216a91f0..d242757cf1 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -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 index 0000000000..31fc691419 --- /dev/null +++ b/lib/isc/hmac.c @@ -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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 index 3f48bc00b7..0000000000 --- a/lib/isc/hmacmd5.c +++ /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 - -#include - -#include -#include -#include -#include -#include -#include -#include - -#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 index 6f621c9dba..0000000000 --- a/lib/isc/hmacsha.c +++ /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 - -#include - -#include -#include -#include -#include -#include -#include -#include - -#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))); -} diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index fa127e2e95..94a42e4a0c 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -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 index 0000000000..20bcde3d0a --- /dev/null +++ b/lib/isc/include/isc/hmac.h @@ -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 + +#include +#include +#include +#include +#include + +#include + +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 index 0f87b2a1b7..0000000000 --- a/lib/isc/include/isc/hmacmd5.h +++ /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 - -#include -#include -#include -#include - -#define ISC_HMACMD5_KEYLENGTH 64 - -#include -#include - -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 index 346dc20251..0000000000 --- a/lib/isc/include/isc/hmacsha.h +++ /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 - -#include -#include -#include -#include - -#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 -#include - -#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 diff --git a/lib/isc/openssl_shim.c b/lib/isc/openssl_shim.c index ee98050f6d..d8e9fc2250 100644 --- a/lib/isc/openssl_shim.c +++ b/lib/isc/openssl_shim.c @@ -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) */ diff --git a/lib/isc/openssl_shim.h b/lib/isc/openssl_shim.h index 1a148b50c3..6088e05b46 100644 --- a/lib/isc/openssl_shim.h +++ b/lib/isc/openssl_shim.h @@ -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) */ diff --git a/lib/isc/tests/Kyuafile b/lib/isc/tests/Kyuafile index ed92a77532..26785b5669 100644 --- a/lib/isc/tests/Kyuafile +++ b/lib/isc/tests/Kyuafile @@ -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'} diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in index 1a84de0df9..1a17d13c0e 100644 --- a/lib/isc/tests/Makefile.in +++ b/lib/isc/tests/Makefile.in @@ -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} diff --git a/lib/isc/tests/hash_test.c b/lib/isc/tests/hash_test.c index 3745dfbbbe..9a1f30707a 100644 --- a/lib/isc/tests/hash_test.c +++ b/lib/isc/tests/hash_test.c @@ -25,39 +25,14 @@ #include #include -#include -#include -#include #include #include #include #include -/* - * 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 index 0000000000..d8fa7be8fa --- /dev/null +++ b/lib/isc/tests/hmac_test.c @@ -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 + +#if HAVE_CMOCKA + +#include +#include +#include +#include + +#include + +#define UNIT_TESTING +#include + +#include +#include +#include +#include +#include + +#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 + +int main(void) { + printf("1..0 # Skipped: cmocka not available\n"); + return (0); +} + +#endif diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 7847f2bb0e..d450915169 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -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 diff --git a/lib/isc/win32/libisc.vcxproj.filters.in b/lib/isc/win32/libisc.vcxproj.filters.in index e18b64a316..48b317c8dc 100644 --- a/lib/isc/win32/libisc.vcxproj.filters.in +++ b/lib/isc/win32/libisc.vcxproj.filters.in @@ -98,10 +98,7 @@ Library Header Files - - Library Header Files - - + Library Header Files @@ -514,10 +511,7 @@ Library Source Files - - Library Source Files - - + Library Source Files diff --git a/lib/isc/win32/libisc.vcxproj.in b/lib/isc/win32/libisc.vcxproj.in index 7bf367814e..6cb8f5f371 100644 --- a/lib/isc/win32/libisc.vcxproj.in +++ b/lib/isc/win32/libisc.vcxproj.in @@ -314,8 +314,7 @@ copy InstallFiles ..\Build\Release\ - - + @@ -430,8 +429,7 @@ copy InstallFiles ..\Build\Release\ - - + diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c index 960da65523..e86c4b7826 100644 --- a/lib/isccc/cc.c +++ b/lib/isccc/cc.c @@ -34,8 +34,7 @@ #include #include -#include -#include +#include #include #include @@ -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)); diff --git a/lib/ns/client.c b/lib/ns/client.c index b5c3175dc2..32c8ddfe22 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -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]; - isc_netaddr_t netaddr; - unsigned char *cp; - isc_hmacsha1_t hmacsha1; - 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); - - 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; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - length = 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_sha1: case ns_cookiealg_sha256: { - unsigned char digest[ISC_SHA256_DIGESTLENGTH]; + unsigned char digest[ISC_MAX_MD_SIZE]; + unsigned char input[8 + 4 + 4 + 16]; isc_netaddr_t netaddr; unsigned char *cp; - isc_hmacsha256_t hmacsha256; - 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_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; + 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_hmacsha256_update(&hmacsha256, cp, length); - isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest)); + + /* + * 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_buffer_putmem(buf, digest, 8); - isc_hmacsha256_invalidate(&hmacsha256); break; } + default: INSIST(0); } diff --git a/util/copyrights b/util/copyrights index 5e2a74d6c5..e1bf381c9f 100644 --- a/util/copyrights +++ b/util/copyrights @@ -312,7 +312,6 @@ ./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 @@ -3356,8 +3355,7 @@ ./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 @@ -3387,8 +3385,7 @@ ./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 @@ -3509,6 +3506,7 @@ ./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