2 * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Portions Copyright (C) 1999-2002 Internet Software Consortium.
4 * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
13 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
16 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * Principal Author: Brian Wellington
21 * $Id: hmac_link.c,v 1.1.6.5 2006/01/27 23:57:44 marka Exp $
26 #include <isc/buffer.h>
27 #include <isc/hmacmd5.h>
28 #include <isc/hmacsha.h>
32 #include <isc/string.h>
35 #include <dst/result.h>
37 #include "dst_internal.h"
38 #include "dst_parse.h"
41 #define HMAC_IPAD 0x36
42 #define HMAC_OPAD 0x5c
44 static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
46 typedef struct hmackey {
47 unsigned char key[HMAC_LEN];
51 getkeybits(dst_key_t *key, struct dst_private_element *element) {
53 if (element->length != 2)
54 return (DST_R_INVALIDPRIVATEKEY);
56 key->key_bits = (element->data[0] << 8) + element->data[1];
58 return (ISC_R_SUCCESS);
62 hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
63 isc_hmacmd5_t *hmacmd5ctx;
64 HMAC_Key *hkey = key->opaque;
66 hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
67 if (hmacmd5ctx == NULL)
68 return (ISC_R_NOMEMORY);
69 isc_hmacmd5_init(hmacmd5ctx, hkey->key, HMAC_LEN);
70 dctx->opaque = hmacmd5ctx;
71 return (ISC_R_SUCCESS);
75 hmacmd5_destroyctx(dst_context_t *dctx) {
76 isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
78 if (hmacmd5ctx != NULL) {
79 isc_hmacmd5_invalidate(hmacmd5ctx);
80 isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
86 hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
87 isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
89 isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
90 return (ISC_R_SUCCESS);
94 hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
95 isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
96 unsigned char *digest;
98 if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
99 return (ISC_R_NOSPACE);
100 digest = isc_buffer_used(sig);
101 isc_hmacmd5_sign(hmacmd5ctx, digest);
102 isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
104 return (ISC_R_SUCCESS);
108 hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
109 isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
111 if (sig->length > ISC_MD5_DIGESTLENGTH)
112 return (DST_R_VERIFYFAILURE);
114 if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
115 return (ISC_R_SUCCESS);
117 return (DST_R_VERIFYFAILURE);
121 hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
122 HMAC_Key *hkey1, *hkey2;
124 hkey1 = (HMAC_Key *)key1->opaque;
125 hkey2 = (HMAC_Key *)key2->opaque;
127 if (hkey1 == NULL && hkey2 == NULL)
129 else if (hkey1 == NULL || hkey2 == NULL)
132 if (memcmp(hkey1->key, hkey2->key, HMAC_LEN) == 0)
139 hmacmd5_generate(dst_key_t *key, int pseudorandom_ok) {
143 unsigned char data[HMAC_LEN];
145 bytes = (key->key_size + 7) / 8;
146 if (bytes > HMAC_LEN) {
148 key->key_size = HMAC_LEN * 8;
151 memset(data, 0, HMAC_LEN);
152 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
154 if (ret != ISC_R_SUCCESS)
157 isc_buffer_init(&b, data, bytes);
158 isc_buffer_add(&b, bytes);
159 ret = hmacmd5_fromdns(key, &b);
160 memset(data, 0, HMAC_LEN);
166 hmacmd5_isprivate(const dst_key_t *key) {
172 hmacmd5_destroy(dst_key_t *key) {
173 HMAC_Key *hkey = key->opaque;
174 memset(hkey, 0, sizeof(HMAC_Key));
175 isc_mem_put(key->mctx, hkey, sizeof(HMAC_Key));
180 hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
184 REQUIRE(key->opaque != NULL);
186 hkey = (HMAC_Key *) key->opaque;
188 bytes = (key->key_size + 7) / 8;
189 if (isc_buffer_availablelength(data) < bytes)
190 return (ISC_R_NOSPACE);
191 isc_buffer_putmem(data, hkey->key, bytes);
193 return (ISC_R_SUCCESS);
197 hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
203 isc_buffer_remainingregion(data, &r);
205 return (ISC_R_SUCCESS);
207 hkey = (HMAC_Key *) isc_mem_get(key->mctx, sizeof(HMAC_Key));
209 return (ISC_R_NOMEMORY);
211 memset(hkey->key, 0, sizeof(hkey->key));
213 if (r.length > HMAC_LEN) {
214 isc_md5_init(&md5ctx);
215 isc_md5_update(&md5ctx, r.base, r.length);
216 isc_md5_final(&md5ctx, hkey->key);
217 keylen = ISC_MD5_DIGESTLENGTH;
220 memcpy(hkey->key, r.base, r.length);
224 key->key_size = keylen * 8;
227 return (ISC_R_SUCCESS);
231 hmacmd5_tofile(const dst_key_t *key, const char *directory) {
235 int bytes = (key->key_size + 7) / 8;
236 unsigned char buf[2];
238 if (key->opaque == NULL)
239 return (DST_R_NULLKEY);
241 hkey = (HMAC_Key *) key->opaque;
243 priv.elements[cnt].tag = TAG_HMACMD5_KEY;
244 priv.elements[cnt].length = bytes;
245 priv.elements[cnt++].data = hkey->key;
247 buf[0] = (key->key_bits >> 8) & 0xffU;
248 buf[1] = key->key_bits & 0xffU;
249 priv.elements[cnt].tag = TAG_HMACMD5_BITS;
250 priv.elements[cnt].data = buf;
251 priv.elements[cnt++].length = 2;
253 priv.nelements = cnt;
254 return (dst__privstruct_writefile(key, &priv, directory));
258 hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer) {
260 isc_result_t result, tresult;
262 isc_mem_t *mctx = key->mctx;
265 /* read private key file */
266 result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv);
267 if (result != ISC_R_SUCCESS)
271 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
272 switch (priv.elements[i].tag) {
273 case TAG_HMACMD5_KEY:
274 isc_buffer_init(&b, priv.elements[i].data,
275 priv.elements[i].length);
276 isc_buffer_add(&b, priv.elements[i].length);
277 tresult = hmacmd5_fromdns(key, &b);
278 if (tresult != ISC_R_SUCCESS)
281 case TAG_HMACMD5_BITS:
282 tresult = getkeybits(key, &priv.elements[i]);
283 if (tresult != ISC_R_SUCCESS)
287 result = DST_R_INVALIDPRIVATEKEY;
291 dst__privstruct_free(&priv, mctx);
292 memset(&priv, 0, sizeof(priv));
296 static dst_func_t hmacmd5_functions = {
302 NULL, /*%< computesecret */
304 NULL, /*%< paramcompare */
312 NULL, /*%< cleanup */
316 dst__hmacmd5_init(dst_func_t **funcp) {
317 REQUIRE(funcp != NULL);
319 *funcp = &hmacmd5_functions;
320 return (ISC_R_SUCCESS);
323 static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
326 unsigned char key[ISC_SHA1_DIGESTLENGTH];
330 hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
331 isc_hmacsha1_t *hmacsha1ctx;
332 HMACSHA1_Key *hkey = key->opaque;
334 hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
335 if (hmacsha1ctx == NULL)
336 return (ISC_R_NOMEMORY);
337 isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_DIGESTLENGTH);
338 dctx->opaque = hmacsha1ctx;
339 return (ISC_R_SUCCESS);
343 hmacsha1_destroyctx(dst_context_t *dctx) {
344 isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
346 if (hmacsha1ctx != NULL) {
347 isc_hmacsha1_invalidate(hmacsha1ctx);
348 isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
354 hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
355 isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
357 isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
358 return (ISC_R_SUCCESS);
362 hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
363 isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
364 unsigned char *digest;
366 if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
367 return (ISC_R_NOSPACE);
368 digest = isc_buffer_used(sig);
369 isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
370 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
372 return (ISC_R_SUCCESS);
376 hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
377 isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
379 if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
380 return (DST_R_VERIFYFAILURE);
382 if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
383 return (ISC_R_SUCCESS);
385 return (DST_R_VERIFYFAILURE);
389 hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
390 HMACSHA1_Key *hkey1, *hkey2;
392 hkey1 = (HMACSHA1_Key *)key1->opaque;
393 hkey2 = (HMACSHA1_Key *)key2->opaque;
395 if (hkey1 == NULL && hkey2 == NULL)
397 else if (hkey1 == NULL || hkey2 == NULL)
400 if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_DIGESTLENGTH) == 0)
407 hmacsha1_generate(dst_key_t *key, int pseudorandom_ok) {
411 unsigned char data[HMAC_LEN];
413 bytes = (key->key_size + 7) / 8;
414 if (bytes > HMAC_LEN) {
416 key->key_size = HMAC_LEN * 8;
419 memset(data, 0, HMAC_LEN);
420 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
422 if (ret != ISC_R_SUCCESS)
425 isc_buffer_init(&b, data, bytes);
426 isc_buffer_add(&b, bytes);
427 ret = hmacsha1_fromdns(key, &b);
428 memset(data, 0, ISC_SHA1_DIGESTLENGTH);
434 hmacsha1_isprivate(const dst_key_t *key) {
440 hmacsha1_destroy(dst_key_t *key) {
441 HMACSHA1_Key *hkey = key->opaque;
442 memset(hkey, 0, sizeof(HMACSHA1_Key));
443 isc_mem_put(key->mctx, hkey, sizeof(HMACSHA1_Key));
448 hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
452 REQUIRE(key->opaque != NULL);
454 hkey = (HMACSHA1_Key *) key->opaque;
456 bytes = (key->key_size + 7) / 8;
457 if (isc_buffer_availablelength(data) < bytes)
458 return (ISC_R_NOSPACE);
459 isc_buffer_putmem(data, hkey->key, bytes);
461 return (ISC_R_SUCCESS);
465 hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
471 isc_buffer_remainingregion(data, &r);
473 return (ISC_R_SUCCESS);
475 hkey = (HMACSHA1_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA1_Key));
477 return (ISC_R_NOMEMORY);
479 memset(hkey->key, 0, sizeof(hkey->key));
481 if (r.length > ISC_SHA1_DIGESTLENGTH) {
482 isc_sha1_init(&sha1ctx);
483 isc_sha1_update(&sha1ctx, r.base, r.length);
484 isc_sha1_final(&sha1ctx, hkey->key);
485 keylen = ISC_SHA1_DIGESTLENGTH;
488 memcpy(hkey->key, r.base, r.length);
492 key->key_size = keylen * 8;
495 return (ISC_R_SUCCESS);
499 hmacsha1_tofile(const dst_key_t *key, const char *directory) {
503 int bytes = (key->key_size + 7) / 8;
504 unsigned char buf[2];
506 if (key->opaque == NULL)
507 return (DST_R_NULLKEY);
509 hkey = (HMACSHA1_Key *) key->opaque;
511 priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
512 priv.elements[cnt].length = bytes;
513 priv.elements[cnt++].data = hkey->key;
515 buf[0] = (key->key_bits >> 8) & 0xffU;
516 buf[1] = key->key_bits & 0xffU;
517 priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
518 priv.elements[cnt].data = buf;
519 priv.elements[cnt++].length = 2;
521 priv.nelements = cnt;
522 return (dst__privstruct_writefile(key, &priv, directory));
526 hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer) {
528 isc_result_t result, tresult;
530 isc_mem_t *mctx = key->mctx;
533 /* read private key file */
534 result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
536 if (result != ISC_R_SUCCESS)
540 for (i = 0; i < priv.nelements; i++) {
541 switch (priv.elements[i].tag) {
542 case TAG_HMACSHA1_KEY:
543 isc_buffer_init(&b, priv.elements[i].data,
544 priv.elements[i].length);
545 isc_buffer_add(&b, priv.elements[i].length);
546 tresult = hmacsha1_fromdns(key, &b);
547 if (tresult != ISC_R_SUCCESS)
550 case TAG_HMACSHA1_BITS:
551 tresult = getkeybits(key, &priv.elements[i]);
552 if (tresult != ISC_R_SUCCESS)
556 result = DST_R_INVALIDPRIVATEKEY;
560 dst__privstruct_free(&priv, mctx);
561 memset(&priv, 0, sizeof(priv));
565 static dst_func_t hmacsha1_functions = {
571 NULL, /* computesecret */
573 NULL, /* paramcompare */
585 dst__hmacsha1_init(dst_func_t **funcp) {
586 REQUIRE(funcp != NULL);
588 *funcp = &hmacsha1_functions;
589 return (ISC_R_SUCCESS);
592 static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
595 unsigned char key[ISC_SHA224_DIGESTLENGTH];
599 hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
600 isc_hmacsha224_t *hmacsha224ctx;
601 HMACSHA224_Key *hkey = key->opaque;
603 hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
604 if (hmacsha224ctx == NULL)
605 return (ISC_R_NOMEMORY);
606 isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_DIGESTLENGTH);
607 dctx->opaque = hmacsha224ctx;
608 return (ISC_R_SUCCESS);
612 hmacsha224_destroyctx(dst_context_t *dctx) {
613 isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
615 if (hmacsha224ctx != NULL) {
616 isc_hmacsha224_invalidate(hmacsha224ctx);
617 isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
623 hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
624 isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
626 isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
627 return (ISC_R_SUCCESS);
631 hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
632 isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
633 unsigned char *digest;
635 if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
636 return (ISC_R_NOSPACE);
637 digest = isc_buffer_used(sig);
638 isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
639 isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
641 return (ISC_R_SUCCESS);
645 hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
646 isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
648 if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
649 return (DST_R_VERIFYFAILURE);
651 if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
652 return (ISC_R_SUCCESS);
654 return (DST_R_VERIFYFAILURE);
658 hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
659 HMACSHA224_Key *hkey1, *hkey2;
661 hkey1 = (HMACSHA224_Key *)key1->opaque;
662 hkey2 = (HMACSHA224_Key *)key2->opaque;
664 if (hkey1 == NULL && hkey2 == NULL)
666 else if (hkey1 == NULL || hkey2 == NULL)
669 if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_DIGESTLENGTH) == 0)
676 hmacsha224_generate(dst_key_t *key, int pseudorandom_ok) {
680 unsigned char data[HMAC_LEN];
682 bytes = (key->key_size + 7) / 8;
683 if (bytes > HMAC_LEN) {
685 key->key_size = HMAC_LEN * 8;
688 memset(data, 0, HMAC_LEN);
689 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
691 if (ret != ISC_R_SUCCESS)
694 isc_buffer_init(&b, data, bytes);
695 isc_buffer_add(&b, bytes);
696 ret = hmacsha224_fromdns(key, &b);
697 memset(data, 0, ISC_SHA224_DIGESTLENGTH);
703 hmacsha224_isprivate(const dst_key_t *key) {
709 hmacsha224_destroy(dst_key_t *key) {
710 HMACSHA224_Key *hkey = key->opaque;
711 memset(hkey, 0, sizeof(HMACSHA224_Key));
712 isc_mem_put(key->mctx, hkey, sizeof(HMACSHA224_Key));
717 hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
718 HMACSHA224_Key *hkey;
721 REQUIRE(key->opaque != NULL);
723 hkey = (HMACSHA224_Key *) key->opaque;
725 bytes = (key->key_size + 7) / 8;
726 if (isc_buffer_availablelength(data) < bytes)
727 return (ISC_R_NOSPACE);
728 isc_buffer_putmem(data, hkey->key, bytes);
730 return (ISC_R_SUCCESS);
734 hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
735 HMACSHA224_Key *hkey;
738 isc_sha224_t sha224ctx;
740 isc_buffer_remainingregion(data, &r);
742 return (ISC_R_SUCCESS);
744 hkey = (HMACSHA224_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA224_Key));
746 return (ISC_R_NOMEMORY);
748 memset(hkey->key, 0, sizeof(hkey->key));
750 if (r.length > ISC_SHA224_DIGESTLENGTH) {
751 isc_sha224_init(&sha224ctx);
752 isc_sha224_update(&sha224ctx, r.base, r.length);
753 isc_sha224_final(hkey->key, &sha224ctx);
754 keylen = ISC_SHA224_DIGESTLENGTH;
757 memcpy(hkey->key, r.base, r.length);
761 key->key_size = keylen * 8;
764 return (ISC_R_SUCCESS);
768 hmacsha224_tofile(const dst_key_t *key, const char *directory) {
770 HMACSHA224_Key *hkey;
772 int bytes = (key->key_size + 7) / 8;
773 unsigned char buf[2];
775 if (key->opaque == NULL)
776 return (DST_R_NULLKEY);
778 hkey = (HMACSHA224_Key *) key->opaque;
780 priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
781 priv.elements[cnt].length = bytes;
782 priv.elements[cnt++].data = hkey->key;
784 buf[0] = (key->key_bits >> 8) & 0xffU;
785 buf[1] = key->key_bits & 0xffU;
786 priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
787 priv.elements[cnt].data = buf;
788 priv.elements[cnt++].length = 2;
790 priv.nelements = cnt;
791 return (dst__privstruct_writefile(key, &priv, directory));
795 hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer) {
797 isc_result_t result, tresult;
799 isc_mem_t *mctx = key->mctx;
802 /* read private key file */
803 result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
805 if (result != ISC_R_SUCCESS)
809 for (i = 0; i < priv.nelements; i++) {
810 switch (priv.elements[i].tag) {
811 case TAG_HMACSHA224_KEY:
812 isc_buffer_init(&b, priv.elements[i].data,
813 priv.elements[i].length);
814 isc_buffer_add(&b, priv.elements[i].length);
815 tresult = hmacsha224_fromdns(key, &b);
816 if (tresult != ISC_R_SUCCESS)
819 case TAG_HMACSHA224_BITS:
820 tresult = getkeybits(key, &priv.elements[i]);
821 if (tresult != ISC_R_SUCCESS)
825 result = DST_R_INVALIDPRIVATEKEY;
829 dst__privstruct_free(&priv, mctx);
830 memset(&priv, 0, sizeof(priv));
834 static dst_func_t hmacsha224_functions = {
835 hmacsha224_createctx,
836 hmacsha224_destroyctx,
840 NULL, /* computesecret */
842 NULL, /* paramcompare */
844 hmacsha224_isprivate,
854 dst__hmacsha224_init(dst_func_t **funcp) {
855 REQUIRE(funcp != NULL);
857 *funcp = &hmacsha224_functions;
858 return (ISC_R_SUCCESS);
861 static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
864 unsigned char key[ISC_SHA256_DIGESTLENGTH];
868 hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
869 isc_hmacsha256_t *hmacsha256ctx;
870 HMACSHA256_Key *hkey = key->opaque;
872 hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
873 if (hmacsha256ctx == NULL)
874 return (ISC_R_NOMEMORY);
875 isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_DIGESTLENGTH);
876 dctx->opaque = hmacsha256ctx;
877 return (ISC_R_SUCCESS);
881 hmacsha256_destroyctx(dst_context_t *dctx) {
882 isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
884 if (hmacsha256ctx != NULL) {
885 isc_hmacsha256_invalidate(hmacsha256ctx);
886 isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
892 hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
893 isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
895 isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
896 return (ISC_R_SUCCESS);
900 hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
901 isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
902 unsigned char *digest;
904 if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
905 return (ISC_R_NOSPACE);
906 digest = isc_buffer_used(sig);
907 isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
908 isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
910 return (ISC_R_SUCCESS);
914 hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
915 isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
917 if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
918 return (DST_R_VERIFYFAILURE);
920 if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
921 return (ISC_R_SUCCESS);
923 return (DST_R_VERIFYFAILURE);
927 hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
928 HMACSHA256_Key *hkey1, *hkey2;
930 hkey1 = (HMACSHA256_Key *)key1->opaque;
931 hkey2 = (HMACSHA256_Key *)key2->opaque;
933 if (hkey1 == NULL && hkey2 == NULL)
935 else if (hkey1 == NULL || hkey2 == NULL)
938 if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_DIGESTLENGTH) == 0)
945 hmacsha256_generate(dst_key_t *key, int pseudorandom_ok) {
949 unsigned char data[HMAC_LEN];
951 bytes = (key->key_size + 7) / 8;
952 if (bytes > HMAC_LEN) {
954 key->key_size = HMAC_LEN * 8;
957 memset(data, 0, HMAC_LEN);
958 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
960 if (ret != ISC_R_SUCCESS)
963 isc_buffer_init(&b, data, bytes);
964 isc_buffer_add(&b, bytes);
965 ret = hmacsha256_fromdns(key, &b);
966 memset(data, 0, ISC_SHA256_DIGESTLENGTH);
972 hmacsha256_isprivate(const dst_key_t *key) {
978 hmacsha256_destroy(dst_key_t *key) {
979 HMACSHA256_Key *hkey = key->opaque;
980 memset(hkey, 0, sizeof(HMACSHA256_Key));
981 isc_mem_put(key->mctx, hkey, sizeof(HMACSHA256_Key));
986 hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
987 HMACSHA256_Key *hkey;
990 REQUIRE(key->opaque != NULL);
992 hkey = (HMACSHA256_Key *) key->opaque;
994 bytes = (key->key_size + 7) / 8;
995 if (isc_buffer_availablelength(data) < bytes)
996 return (ISC_R_NOSPACE);
997 isc_buffer_putmem(data, hkey->key, bytes);
999 return (ISC_R_SUCCESS);
1003 hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
1004 HMACSHA256_Key *hkey;
1007 isc_sha256_t sha256ctx;
1009 isc_buffer_remainingregion(data, &r);
1011 return (ISC_R_SUCCESS);
1013 hkey = (HMACSHA256_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA256_Key));
1015 return (ISC_R_NOMEMORY);
1017 memset(hkey->key, 0, sizeof(hkey->key));
1019 if (r.length > ISC_SHA256_DIGESTLENGTH) {
1020 isc_sha256_init(&sha256ctx);
1021 isc_sha256_update(&sha256ctx, r.base, r.length);
1022 isc_sha256_final(hkey->key, &sha256ctx);
1023 keylen = ISC_SHA256_DIGESTLENGTH;
1026 memcpy(hkey->key, r.base, r.length);
1030 key->key_size = keylen * 8;
1033 return (ISC_R_SUCCESS);
1037 hmacsha256_tofile(const dst_key_t *key, const char *directory) {
1039 HMACSHA256_Key *hkey;
1041 int bytes = (key->key_size + 7) / 8;
1042 unsigned char buf[2];
1044 if (key->opaque == NULL)
1045 return (DST_R_NULLKEY);
1047 hkey = (HMACSHA256_Key *) key->opaque;
1049 priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
1050 priv.elements[cnt].length = bytes;
1051 priv.elements[cnt++].data = hkey->key;
1053 buf[0] = (key->key_bits >> 8) & 0xffU;
1054 buf[1] = key->key_bits & 0xffU;
1055 priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
1056 priv.elements[cnt].data = buf;
1057 priv.elements[cnt++].length = 2;
1059 priv.nelements = cnt;
1060 return (dst__privstruct_writefile(key, &priv, directory));
1064 hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer) {
1066 isc_result_t result, tresult;
1068 isc_mem_t *mctx = key->mctx;
1071 /* read private key file */
1072 result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
1074 if (result != ISC_R_SUCCESS)
1078 for (i = 0; i < priv.nelements; i++) {
1079 switch (priv.elements[i].tag) {
1080 case TAG_HMACSHA256_KEY:
1081 isc_buffer_init(&b, priv.elements[i].data,
1082 priv.elements[i].length);
1083 isc_buffer_add(&b, priv.elements[i].length);
1084 tresult = hmacsha256_fromdns(key, &b);
1085 if (tresult != ISC_R_SUCCESS)
1088 case TAG_HMACSHA256_BITS:
1089 tresult = getkeybits(key, &priv.elements[i]);
1090 if (tresult != ISC_R_SUCCESS)
1094 result = DST_R_INVALIDPRIVATEKEY;
1098 dst__privstruct_free(&priv, mctx);
1099 memset(&priv, 0, sizeof(priv));
1103 static dst_func_t hmacsha256_functions = {
1104 hmacsha256_createctx,
1105 hmacsha256_destroyctx,
1109 NULL, /* computesecret */
1111 NULL, /* paramcompare */
1112 hmacsha256_generate,
1113 hmacsha256_isprivate,
1123 dst__hmacsha256_init(dst_func_t **funcp) {
1124 REQUIRE(funcp != NULL);
1126 *funcp = &hmacsha256_functions;
1127 return (ISC_R_SUCCESS);
1130 static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
1133 unsigned char key[ISC_SHA384_DIGESTLENGTH];
1137 hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
1138 isc_hmacsha384_t *hmacsha384ctx;
1139 HMACSHA384_Key *hkey = key->opaque;
1141 hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
1142 if (hmacsha384ctx == NULL)
1143 return (ISC_R_NOMEMORY);
1144 isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_DIGESTLENGTH);
1145 dctx->opaque = hmacsha384ctx;
1146 return (ISC_R_SUCCESS);
1150 hmacsha384_destroyctx(dst_context_t *dctx) {
1151 isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
1153 if (hmacsha384ctx != NULL) {
1154 isc_hmacsha384_invalidate(hmacsha384ctx);
1155 isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
1156 dctx->opaque = NULL;
1161 hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
1162 isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
1164 isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
1165 return (ISC_R_SUCCESS);
1169 hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
1170 isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
1171 unsigned char *digest;
1173 if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
1174 return (ISC_R_NOSPACE);
1175 digest = isc_buffer_used(sig);
1176 isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
1177 isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
1179 return (ISC_R_SUCCESS);
1183 hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
1184 isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
1186 if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
1187 return (DST_R_VERIFYFAILURE);
1189 if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
1190 return (ISC_R_SUCCESS);
1192 return (DST_R_VERIFYFAILURE);
1195 static isc_boolean_t
1196 hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
1197 HMACSHA384_Key *hkey1, *hkey2;
1199 hkey1 = (HMACSHA384_Key *)key1->opaque;
1200 hkey2 = (HMACSHA384_Key *)key2->opaque;
1202 if (hkey1 == NULL && hkey2 == NULL)
1204 else if (hkey1 == NULL || hkey2 == NULL)
1207 if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_DIGESTLENGTH) == 0)
1214 hmacsha384_generate(dst_key_t *key, int pseudorandom_ok) {
1218 unsigned char data[HMAC_LEN];
1220 bytes = (key->key_size + 7) / 8;
1221 if (bytes > HMAC_LEN) {
1223 key->key_size = HMAC_LEN * 8;
1226 memset(data, 0, HMAC_LEN);
1227 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
1229 if (ret != ISC_R_SUCCESS)
1232 isc_buffer_init(&b, data, bytes);
1233 isc_buffer_add(&b, bytes);
1234 ret = hmacsha384_fromdns(key, &b);
1235 memset(data, 0, ISC_SHA384_DIGESTLENGTH);
1240 static isc_boolean_t
1241 hmacsha384_isprivate(const dst_key_t *key) {
1247 hmacsha384_destroy(dst_key_t *key) {
1248 HMACSHA384_Key *hkey = key->opaque;
1249 memset(hkey, 0, sizeof(HMACSHA384_Key));
1250 isc_mem_put(key->mctx, hkey, sizeof(HMACSHA384_Key));
1255 hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
1256 HMACSHA384_Key *hkey;
1259 REQUIRE(key->opaque != NULL);
1261 hkey = (HMACSHA384_Key *) key->opaque;
1263 bytes = (key->key_size + 7) / 8;
1264 if (isc_buffer_availablelength(data) < bytes)
1265 return (ISC_R_NOSPACE);
1266 isc_buffer_putmem(data, hkey->key, bytes);
1268 return (ISC_R_SUCCESS);
1272 hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
1273 HMACSHA384_Key *hkey;
1276 isc_sha384_t sha384ctx;
1278 isc_buffer_remainingregion(data, &r);
1280 return (ISC_R_SUCCESS);
1282 hkey = (HMACSHA384_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA384_Key));
1284 return (ISC_R_NOMEMORY);
1286 memset(hkey->key, 0, sizeof(hkey->key));
1288 if (r.length > ISC_SHA384_DIGESTLENGTH) {
1289 isc_sha384_init(&sha384ctx);
1290 isc_sha384_update(&sha384ctx, r.base, r.length);
1291 isc_sha384_final(hkey->key, &sha384ctx);
1292 keylen = ISC_SHA384_DIGESTLENGTH;
1295 memcpy(hkey->key, r.base, r.length);
1299 key->key_size = keylen * 8;
1302 return (ISC_R_SUCCESS);
1306 hmacsha384_tofile(const dst_key_t *key, const char *directory) {
1308 HMACSHA384_Key *hkey;
1310 int bytes = (key->key_size + 7) / 8;
1311 unsigned char buf[2];
1313 if (key->opaque == NULL)
1314 return (DST_R_NULLKEY);
1316 hkey = (HMACSHA384_Key *) key->opaque;
1318 priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
1319 priv.elements[cnt].length = bytes;
1320 priv.elements[cnt++].data = hkey->key;
1322 buf[0] = (key->key_bits >> 8) & 0xffU;
1323 buf[1] = key->key_bits & 0xffU;
1324 priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
1325 priv.elements[cnt].data = buf;
1326 priv.elements[cnt++].length = 2;
1328 priv.nelements = cnt;
1329 return (dst__privstruct_writefile(key, &priv, directory));
1333 hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer) {
1335 isc_result_t result, tresult;
1337 isc_mem_t *mctx = key->mctx;
1340 /* read private key file */
1341 result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
1343 if (result != ISC_R_SUCCESS)
1347 for (i = 0; i < priv.nelements; i++) {
1348 switch (priv.elements[i].tag) {
1349 case TAG_HMACSHA384_KEY:
1350 isc_buffer_init(&b, priv.elements[i].data,
1351 priv.elements[i].length);
1352 isc_buffer_add(&b, priv.elements[i].length);
1353 tresult = hmacsha384_fromdns(key, &b);
1354 if (tresult != ISC_R_SUCCESS)
1357 case TAG_HMACSHA384_BITS:
1358 tresult = getkeybits(key, &priv.elements[i]);
1359 if (tresult != ISC_R_SUCCESS)
1363 result = DST_R_INVALIDPRIVATEKEY;
1367 dst__privstruct_free(&priv, mctx);
1368 memset(&priv, 0, sizeof(priv));
1372 static dst_func_t hmacsha384_functions = {
1373 hmacsha384_createctx,
1374 hmacsha384_destroyctx,
1378 NULL, /* computesecret */
1380 NULL, /* paramcompare */
1381 hmacsha384_generate,
1382 hmacsha384_isprivate,
1392 dst__hmacsha384_init(dst_func_t **funcp) {
1393 REQUIRE(funcp != NULL);
1395 *funcp = &hmacsha384_functions;
1396 return (ISC_R_SUCCESS);
1399 static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
1402 unsigned char key[ISC_SHA512_DIGESTLENGTH];
1406 hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
1407 isc_hmacsha512_t *hmacsha512ctx;
1408 HMACSHA512_Key *hkey = key->opaque;
1410 hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
1411 if (hmacsha512ctx == NULL)
1412 return (ISC_R_NOMEMORY);
1413 isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_DIGESTLENGTH);
1414 dctx->opaque = hmacsha512ctx;
1415 return (ISC_R_SUCCESS);
1419 hmacsha512_destroyctx(dst_context_t *dctx) {
1420 isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
1422 if (hmacsha512ctx != NULL) {
1423 isc_hmacsha512_invalidate(hmacsha512ctx);
1424 isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
1425 dctx->opaque = NULL;
1430 hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
1431 isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
1433 isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
1434 return (ISC_R_SUCCESS);
1438 hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
1439 isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
1440 unsigned char *digest;
1442 if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
1443 return (ISC_R_NOSPACE);
1444 digest = isc_buffer_used(sig);
1445 isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
1446 isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
1448 return (ISC_R_SUCCESS);
1452 hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
1453 isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
1455 if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
1456 return (DST_R_VERIFYFAILURE);
1458 if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
1459 return (ISC_R_SUCCESS);
1461 return (DST_R_VERIFYFAILURE);
1464 static isc_boolean_t
1465 hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
1466 HMACSHA512_Key *hkey1, *hkey2;
1468 hkey1 = (HMACSHA512_Key *)key1->opaque;
1469 hkey2 = (HMACSHA512_Key *)key2->opaque;
1471 if (hkey1 == NULL && hkey2 == NULL)
1473 else if (hkey1 == NULL || hkey2 == NULL)
1476 if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_DIGESTLENGTH) == 0)
1483 hmacsha512_generate(dst_key_t *key, int pseudorandom_ok) {
1487 unsigned char data[HMAC_LEN];
1489 bytes = (key->key_size + 7) / 8;
1490 if (bytes > HMAC_LEN) {
1492 key->key_size = HMAC_LEN * 8;
1495 memset(data, 0, HMAC_LEN);
1496 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
1498 if (ret != ISC_R_SUCCESS)
1501 isc_buffer_init(&b, data, bytes);
1502 isc_buffer_add(&b, bytes);
1503 ret = hmacsha512_fromdns(key, &b);
1504 memset(data, 0, ISC_SHA512_DIGESTLENGTH);
1509 static isc_boolean_t
1510 hmacsha512_isprivate(const dst_key_t *key) {
1516 hmacsha512_destroy(dst_key_t *key) {
1517 HMACSHA512_Key *hkey = key->opaque;
1518 memset(hkey, 0, sizeof(HMACSHA512_Key));
1519 isc_mem_put(key->mctx, hkey, sizeof(HMACSHA512_Key));
1524 hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
1525 HMACSHA512_Key *hkey;
1528 REQUIRE(key->opaque != NULL);
1530 hkey = (HMACSHA512_Key *) key->opaque;
1532 bytes = (key->key_size + 7) / 8;
1533 if (isc_buffer_availablelength(data) < bytes)
1534 return (ISC_R_NOSPACE);
1535 isc_buffer_putmem(data, hkey->key, bytes);
1537 return (ISC_R_SUCCESS);
1541 hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
1542 HMACSHA512_Key *hkey;
1545 isc_sha512_t sha512ctx;
1547 isc_buffer_remainingregion(data, &r);
1549 return (ISC_R_SUCCESS);
1551 hkey = (HMACSHA512_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA512_Key));
1553 return (ISC_R_NOMEMORY);
1555 memset(hkey->key, 0, sizeof(hkey->key));
1557 if (r.length > ISC_SHA512_DIGESTLENGTH) {
1558 isc_sha512_init(&sha512ctx);
1559 isc_sha512_update(&sha512ctx, r.base, r.length);
1560 isc_sha512_final(hkey->key, &sha512ctx);
1561 keylen = ISC_SHA512_DIGESTLENGTH;
1564 memcpy(hkey->key, r.base, r.length);
1568 key->key_size = keylen * 8;
1571 return (ISC_R_SUCCESS);
1575 hmacsha512_tofile(const dst_key_t *key, const char *directory) {
1577 HMACSHA512_Key *hkey;
1579 int bytes = (key->key_size + 7) / 8;
1580 unsigned char buf[2];
1582 if (key->opaque == NULL)
1583 return (DST_R_NULLKEY);
1585 hkey = (HMACSHA512_Key *) key->opaque;
1587 priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
1588 priv.elements[cnt].length = bytes;
1589 priv.elements[cnt++].data = hkey->key;
1591 buf[0] = (key->key_bits >> 8) & 0xffU;
1592 buf[1] = key->key_bits & 0xffU;
1593 priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
1594 priv.elements[cnt].data = buf;
1595 priv.elements[cnt++].length = 2;
1597 priv.nelements = cnt;
1598 return (dst__privstruct_writefile(key, &priv, directory));
1602 hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer) {
1604 isc_result_t result, tresult;
1606 isc_mem_t *mctx = key->mctx;
1609 /* read private key file */
1610 result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
1612 if (result != ISC_R_SUCCESS)
1616 for (i = 0; i < priv.nelements; i++) {
1617 switch (priv.elements[i].tag) {
1618 case TAG_HMACSHA512_KEY:
1619 isc_buffer_init(&b, priv.elements[i].data,
1620 priv.elements[i].length);
1621 isc_buffer_add(&b, priv.elements[i].length);
1622 tresult = hmacsha512_fromdns(key, &b);
1623 if (tresult != ISC_R_SUCCESS)
1626 case TAG_HMACSHA512_BITS:
1627 tresult = getkeybits(key, &priv.elements[i]);
1628 if (tresult != ISC_R_SUCCESS)
1632 result = DST_R_INVALIDPRIVATEKEY;
1636 dst__privstruct_free(&priv, mctx);
1637 memset(&priv, 0, sizeof(priv));
1641 static dst_func_t hmacsha512_functions = {
1642 hmacsha512_createctx,
1643 hmacsha512_destroyctx,
1647 NULL, /* computesecret */
1649 NULL, /* paramcompare */
1650 hmacsha512_generate,
1651 hmacsha512_isprivate,
1661 dst__hmacsha512_init(dst_func_t **funcp) {
1662 REQUIRE(funcp != NULL);
1664 *funcp = &hmacsha512_functions;
1665 return (ISC_R_SUCCESS);