2 * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
3 * Portions Copyright (C) 1999-2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
12 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
15 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
19 * Permission to use, copy, modify, and/or distribute this software for any
20 * purpose with or without fee is hereby granted, provided that the above
21 * copyright notice and this permission notice appear in all copies.
23 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
24 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
26 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
28 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33 * Principal Author: Brian Wellington
34 * $Id: hmac_link.c,v 1.19 2011/01/11 23:47:13 tbox Exp $
39 #include <isc/buffer.h>
40 #include <isc/hmacmd5.h>
41 #include <isc/hmacsha.h>
45 #include <isc/string.h>
48 #include <dst/result.h>
50 #include "dst_internal.h"
51 #include "dst_parse.h"
53 static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
55 struct dst_hmacmd5_key {
56 unsigned char key[ISC_MD5_BLOCK_LENGTH];
60 getkeybits(dst_key_t *key, struct dst_private_element *element) {
62 if (element->length != 2)
63 return (DST_R_INVALIDPRIVATEKEY);
65 key->key_bits = (element->data[0] << 8) + element->data[1];
67 return (ISC_R_SUCCESS);
71 hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
72 isc_hmacmd5_t *hmacmd5ctx;
73 dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
75 hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
76 if (hmacmd5ctx == NULL)
77 return (ISC_R_NOMEMORY);
78 isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
79 dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
80 return (ISC_R_SUCCESS);
84 hmacmd5_destroyctx(dst_context_t *dctx) {
85 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
87 if (hmacmd5ctx != NULL) {
88 isc_hmacmd5_invalidate(hmacmd5ctx);
89 isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
90 dctx->ctxdata.hmacmd5ctx = NULL;
95 hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
96 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
98 isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
99 return (ISC_R_SUCCESS);
103 hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
104 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
105 unsigned char *digest;
107 if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
108 return (ISC_R_NOSPACE);
109 digest = isc_buffer_used(sig);
110 isc_hmacmd5_sign(hmacmd5ctx, digest);
111 isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
113 return (ISC_R_SUCCESS);
117 hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
118 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
120 if (sig->length > ISC_MD5_DIGESTLENGTH)
121 return (DST_R_VERIFYFAILURE);
123 if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
124 return (ISC_R_SUCCESS);
126 return (DST_R_VERIFYFAILURE);
130 hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
131 dst_hmacmd5_key_t *hkey1, *hkey2;
133 hkey1 = key1->keydata.hmacmd5;
134 hkey2 = key2->keydata.hmacmd5;
136 if (hkey1 == NULL && hkey2 == NULL)
138 else if (hkey1 == NULL || hkey2 == NULL)
141 if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0)
148 hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
152 unsigned char data[ISC_SHA1_BLOCK_LENGTH];
156 bytes = (key->key_size + 7) / 8;
157 if (bytes > ISC_SHA1_BLOCK_LENGTH) {
158 bytes = ISC_SHA1_BLOCK_LENGTH;
159 key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
162 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
163 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
165 if (ret != ISC_R_SUCCESS)
168 isc_buffer_init(&b, data, bytes);
169 isc_buffer_add(&b, bytes);
170 ret = hmacmd5_fromdns(key, &b);
171 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
177 hmacmd5_isprivate(const dst_key_t *key) {
183 hmacmd5_destroy(dst_key_t *key) {
184 dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
186 memset(hkey, 0, sizeof(dst_hmacmd5_key_t));
187 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t));
188 key->keydata.hmacmd5 = NULL;
192 hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
193 dst_hmacmd5_key_t *hkey;
196 REQUIRE(key->keydata.hmacmd5 != NULL);
198 hkey = key->keydata.hmacmd5;
200 bytes = (key->key_size + 7) / 8;
201 if (isc_buffer_availablelength(data) < bytes)
202 return (ISC_R_NOSPACE);
203 isc_buffer_putmem(data, hkey->key, bytes);
205 return (ISC_R_SUCCESS);
209 hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
210 dst_hmacmd5_key_t *hkey;
215 isc_buffer_remainingregion(data, &r);
217 return (ISC_R_SUCCESS);
219 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
221 return (ISC_R_NOMEMORY);
223 memset(hkey->key, 0, sizeof(hkey->key));
225 if (r.length > ISC_SHA1_BLOCK_LENGTH) {
226 isc_md5_init(&md5ctx);
227 isc_md5_update(&md5ctx, r.base, r.length);
228 isc_md5_final(&md5ctx, hkey->key);
229 keylen = ISC_MD5_DIGESTLENGTH;
232 memcpy(hkey->key, r.base, r.length);
236 key->key_size = keylen * 8;
237 key->keydata.hmacmd5 = hkey;
239 return (ISC_R_SUCCESS);
243 hmacmd5_tofile(const dst_key_t *key, const char *directory) {
245 dst_hmacmd5_key_t *hkey;
247 int bytes = (key->key_size + 7) / 8;
248 unsigned char buf[2];
250 if (key->keydata.hmacmd5 == NULL)
251 return (DST_R_NULLKEY);
253 hkey = key->keydata.hmacmd5;
255 priv.elements[cnt].tag = TAG_HMACMD5_KEY;
256 priv.elements[cnt].length = bytes;
257 priv.elements[cnt++].data = hkey->key;
259 buf[0] = (key->key_bits >> 8) & 0xffU;
260 buf[1] = key->key_bits & 0xffU;
261 priv.elements[cnt].tag = TAG_HMACMD5_BITS;
262 priv.elements[cnt].data = buf;
263 priv.elements[cnt++].length = 2;
265 priv.nelements = cnt;
266 return (dst__privstruct_writefile(key, &priv, directory));
270 hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
272 isc_result_t result, tresult;
274 isc_mem_t *mctx = key->mctx;
278 /* read private key file */
279 result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx,
281 if (result != ISC_R_SUCCESS)
285 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
286 switch (priv.elements[i].tag) {
287 case TAG_HMACMD5_KEY:
288 isc_buffer_init(&b, priv.elements[i].data,
289 priv.elements[i].length);
290 isc_buffer_add(&b, priv.elements[i].length);
291 tresult = hmacmd5_fromdns(key, &b);
292 if (tresult != ISC_R_SUCCESS)
295 case TAG_HMACMD5_BITS:
296 tresult = getkeybits(key, &priv.elements[i]);
297 if (tresult != ISC_R_SUCCESS)
301 result = DST_R_INVALIDPRIVATEKEY;
305 dst__privstruct_free(&priv, mctx);
306 memset(&priv, 0, sizeof(priv));
310 static dst_func_t hmacmd5_functions = {
316 NULL, /*%< computesecret */
318 NULL, /*%< paramcompare */
326 NULL, /*%< cleanup */
327 NULL, /*%< fromlabel */
329 NULL, /*%< restore */
333 dst__hmacmd5_init(dst_func_t **funcp) {
334 REQUIRE(funcp != NULL);
336 *funcp = &hmacmd5_functions;
337 return (ISC_R_SUCCESS);
340 static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
342 struct dst_hmacsha1_key {
343 unsigned char key[ISC_SHA1_BLOCK_LENGTH];
347 hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
348 isc_hmacsha1_t *hmacsha1ctx;
349 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
351 hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
352 if (hmacsha1ctx == NULL)
353 return (ISC_R_NOMEMORY);
354 isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
355 dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
356 return (ISC_R_SUCCESS);
360 hmacsha1_destroyctx(dst_context_t *dctx) {
361 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
363 if (hmacsha1ctx != NULL) {
364 isc_hmacsha1_invalidate(hmacsha1ctx);
365 isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
366 dctx->ctxdata.hmacsha1ctx = NULL;
371 hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
372 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
374 isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
375 return (ISC_R_SUCCESS);
379 hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
380 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
381 unsigned char *digest;
383 if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
384 return (ISC_R_NOSPACE);
385 digest = isc_buffer_used(sig);
386 isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
387 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
389 return (ISC_R_SUCCESS);
393 hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
394 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
396 if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
397 return (DST_R_VERIFYFAILURE);
399 if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
400 return (ISC_R_SUCCESS);
402 return (DST_R_VERIFYFAILURE);
406 hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
407 dst_hmacsha1_key_t *hkey1, *hkey2;
409 hkey1 = key1->keydata.hmacsha1;
410 hkey2 = key2->keydata.hmacsha1;
412 if (hkey1 == NULL && hkey2 == NULL)
414 else if (hkey1 == NULL || hkey2 == NULL)
417 if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0)
424 hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
428 unsigned char data[ISC_SHA1_BLOCK_LENGTH];
432 bytes = (key->key_size + 7) / 8;
433 if (bytes > ISC_SHA1_BLOCK_LENGTH) {
434 bytes = ISC_SHA1_BLOCK_LENGTH;
435 key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
438 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
439 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
441 if (ret != ISC_R_SUCCESS)
444 isc_buffer_init(&b, data, bytes);
445 isc_buffer_add(&b, bytes);
446 ret = hmacsha1_fromdns(key, &b);
447 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
453 hmacsha1_isprivate(const dst_key_t *key) {
459 hmacsha1_destroy(dst_key_t *key) {
460 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
462 memset(hkey, 0, sizeof(dst_hmacsha1_key_t));
463 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t));
464 key->keydata.hmacsha1 = NULL;
468 hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
469 dst_hmacsha1_key_t *hkey;
472 REQUIRE(key->keydata.hmacsha1 != NULL);
474 hkey = key->keydata.hmacsha1;
476 bytes = (key->key_size + 7) / 8;
477 if (isc_buffer_availablelength(data) < bytes)
478 return (ISC_R_NOSPACE);
479 isc_buffer_putmem(data, hkey->key, bytes);
481 return (ISC_R_SUCCESS);
485 hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
486 dst_hmacsha1_key_t *hkey;
491 isc_buffer_remainingregion(data, &r);
493 return (ISC_R_SUCCESS);
495 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
497 return (ISC_R_NOMEMORY);
499 memset(hkey->key, 0, sizeof(hkey->key));
501 if (r.length > ISC_SHA1_BLOCK_LENGTH) {
502 isc_sha1_init(&sha1ctx);
503 isc_sha1_update(&sha1ctx, r.base, r.length);
504 isc_sha1_final(&sha1ctx, hkey->key);
505 keylen = ISC_SHA1_DIGESTLENGTH;
508 memcpy(hkey->key, r.base, r.length);
512 key->key_size = keylen * 8;
513 key->keydata.hmacsha1 = hkey;
515 return (ISC_R_SUCCESS);
519 hmacsha1_tofile(const dst_key_t *key, const char *directory) {
521 dst_hmacsha1_key_t *hkey;
523 int bytes = (key->key_size + 7) / 8;
524 unsigned char buf[2];
526 if (key->keydata.hmacsha1 == NULL)
527 return (DST_R_NULLKEY);
529 hkey = key->keydata.hmacsha1;
531 priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
532 priv.elements[cnt].length = bytes;
533 priv.elements[cnt++].data = hkey->key;
535 buf[0] = (key->key_bits >> 8) & 0xffU;
536 buf[1] = key->key_bits & 0xffU;
537 priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
538 priv.elements[cnt].data = buf;
539 priv.elements[cnt++].length = 2;
541 priv.nelements = cnt;
542 return (dst__privstruct_writefile(key, &priv, directory));
546 hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
548 isc_result_t result, tresult;
550 isc_mem_t *mctx = key->mctx;
554 /* read private key file */
555 result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
557 if (result != ISC_R_SUCCESS)
561 for (i = 0; i < priv.nelements; i++) {
562 switch (priv.elements[i].tag) {
563 case TAG_HMACSHA1_KEY:
564 isc_buffer_init(&b, priv.elements[i].data,
565 priv.elements[i].length);
566 isc_buffer_add(&b, priv.elements[i].length);
567 tresult = hmacsha1_fromdns(key, &b);
568 if (tresult != ISC_R_SUCCESS)
571 case TAG_HMACSHA1_BITS:
572 tresult = getkeybits(key, &priv.elements[i]);
573 if (tresult != ISC_R_SUCCESS)
577 result = DST_R_INVALIDPRIVATEKEY;
581 dst__privstruct_free(&priv, mctx);
582 memset(&priv, 0, sizeof(priv));
586 static dst_func_t hmacsha1_functions = {
592 NULL, /* computesecret */
594 NULL, /* paramcompare */
603 NULL, /* fromlabel */
609 dst__hmacsha1_init(dst_func_t **funcp) {
610 REQUIRE(funcp != NULL);
612 *funcp = &hmacsha1_functions;
613 return (ISC_R_SUCCESS);
616 static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
618 struct dst_hmacsha224_key {
619 unsigned char key[ISC_SHA224_BLOCK_LENGTH];
623 hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
624 isc_hmacsha224_t *hmacsha224ctx;
625 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
627 hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
628 if (hmacsha224ctx == NULL)
629 return (ISC_R_NOMEMORY);
630 isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH);
631 dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
632 return (ISC_R_SUCCESS);
636 hmacsha224_destroyctx(dst_context_t *dctx) {
637 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
639 if (hmacsha224ctx != NULL) {
640 isc_hmacsha224_invalidate(hmacsha224ctx);
641 isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
642 dctx->ctxdata.hmacsha224ctx = NULL;
647 hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
648 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
650 isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
651 return (ISC_R_SUCCESS);
655 hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
656 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
657 unsigned char *digest;
659 if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
660 return (ISC_R_NOSPACE);
661 digest = isc_buffer_used(sig);
662 isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
663 isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
665 return (ISC_R_SUCCESS);
669 hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
670 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
672 if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
673 return (DST_R_VERIFYFAILURE);
675 if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
676 return (ISC_R_SUCCESS);
678 return (DST_R_VERIFYFAILURE);
682 hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
683 dst_hmacsha224_key_t *hkey1, *hkey2;
685 hkey1 = key1->keydata.hmacsha224;
686 hkey2 = key2->keydata.hmacsha224;
688 if (hkey1 == NULL && hkey2 == NULL)
690 else if (hkey1 == NULL || hkey2 == NULL)
693 if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH) == 0)
700 hmacsha224_generate(dst_key_t *key, int pseudorandom_ok,
701 void (*callback)(int))
706 unsigned char data[ISC_SHA224_BLOCK_LENGTH];
710 bytes = (key->key_size + 7) / 8;
711 if (bytes > ISC_SHA224_BLOCK_LENGTH) {
712 bytes = ISC_SHA224_BLOCK_LENGTH;
713 key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
716 memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
717 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
719 if (ret != ISC_R_SUCCESS)
722 isc_buffer_init(&b, data, bytes);
723 isc_buffer_add(&b, bytes);
724 ret = hmacsha224_fromdns(key, &b);
725 memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
731 hmacsha224_isprivate(const dst_key_t *key) {
737 hmacsha224_destroy(dst_key_t *key) {
738 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
740 memset(hkey, 0, sizeof(dst_hmacsha224_key_t));
741 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t));
742 key->keydata.hmacsha224 = NULL;
746 hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
747 dst_hmacsha224_key_t *hkey;
750 REQUIRE(key->keydata.hmacsha224 != NULL);
752 hkey = key->keydata.hmacsha224;
754 bytes = (key->key_size + 7) / 8;
755 if (isc_buffer_availablelength(data) < bytes)
756 return (ISC_R_NOSPACE);
757 isc_buffer_putmem(data, hkey->key, bytes);
759 return (ISC_R_SUCCESS);
763 hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
764 dst_hmacsha224_key_t *hkey;
767 isc_sha224_t sha224ctx;
769 isc_buffer_remainingregion(data, &r);
771 return (ISC_R_SUCCESS);
773 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
775 return (ISC_R_NOMEMORY);
777 memset(hkey->key, 0, sizeof(hkey->key));
779 if (r.length > ISC_SHA224_BLOCK_LENGTH) {
780 isc_sha224_init(&sha224ctx);
781 isc_sha224_update(&sha224ctx, r.base, r.length);
782 isc_sha224_final(hkey->key, &sha224ctx);
783 keylen = ISC_SHA224_DIGESTLENGTH;
786 memcpy(hkey->key, r.base, r.length);
790 key->key_size = keylen * 8;
791 key->keydata.hmacsha224 = hkey;
793 return (ISC_R_SUCCESS);
797 hmacsha224_tofile(const dst_key_t *key, const char *directory) {
799 dst_hmacsha224_key_t *hkey;
801 int bytes = (key->key_size + 7) / 8;
802 unsigned char buf[2];
804 if (key->keydata.hmacsha224 == NULL)
805 return (DST_R_NULLKEY);
807 hkey = key->keydata.hmacsha224;
809 priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
810 priv.elements[cnt].length = bytes;
811 priv.elements[cnt++].data = hkey->key;
813 buf[0] = (key->key_bits >> 8) & 0xffU;
814 buf[1] = key->key_bits & 0xffU;
815 priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
816 priv.elements[cnt].data = buf;
817 priv.elements[cnt++].length = 2;
819 priv.nelements = cnt;
820 return (dst__privstruct_writefile(key, &priv, directory));
824 hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
826 isc_result_t result, tresult;
828 isc_mem_t *mctx = key->mctx;
832 /* read private key file */
833 result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
835 if (result != ISC_R_SUCCESS)
839 for (i = 0; i < priv.nelements; i++) {
840 switch (priv.elements[i].tag) {
841 case TAG_HMACSHA224_KEY:
842 isc_buffer_init(&b, priv.elements[i].data,
843 priv.elements[i].length);
844 isc_buffer_add(&b, priv.elements[i].length);
845 tresult = hmacsha224_fromdns(key, &b);
846 if (tresult != ISC_R_SUCCESS)
849 case TAG_HMACSHA224_BITS:
850 tresult = getkeybits(key, &priv.elements[i]);
851 if (tresult != ISC_R_SUCCESS)
855 result = DST_R_INVALIDPRIVATEKEY;
859 dst__privstruct_free(&priv, mctx);
860 memset(&priv, 0, sizeof(priv));
864 static dst_func_t hmacsha224_functions = {
865 hmacsha224_createctx,
866 hmacsha224_destroyctx,
870 NULL, /* computesecret */
872 NULL, /* paramcompare */
874 hmacsha224_isprivate,
881 NULL, /* fromlabel */
887 dst__hmacsha224_init(dst_func_t **funcp) {
888 REQUIRE(funcp != NULL);
890 *funcp = &hmacsha224_functions;
891 return (ISC_R_SUCCESS);
894 static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
896 struct dst_hmacsha256_key {
897 unsigned char key[ISC_SHA256_BLOCK_LENGTH];
901 hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
902 isc_hmacsha256_t *hmacsha256ctx;
903 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
905 hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
906 if (hmacsha256ctx == NULL)
907 return (ISC_R_NOMEMORY);
908 isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH);
909 dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
910 return (ISC_R_SUCCESS);
914 hmacsha256_destroyctx(dst_context_t *dctx) {
915 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
917 if (hmacsha256ctx != NULL) {
918 isc_hmacsha256_invalidate(hmacsha256ctx);
919 isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
920 dctx->ctxdata.hmacsha256ctx = NULL;
925 hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
926 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
928 isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
929 return (ISC_R_SUCCESS);
933 hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
934 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
935 unsigned char *digest;
937 if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
938 return (ISC_R_NOSPACE);
939 digest = isc_buffer_used(sig);
940 isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
941 isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
943 return (ISC_R_SUCCESS);
947 hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
948 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
950 if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
951 return (DST_R_VERIFYFAILURE);
953 if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
954 return (ISC_R_SUCCESS);
956 return (DST_R_VERIFYFAILURE);
960 hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
961 dst_hmacsha256_key_t *hkey1, *hkey2;
963 hkey1 = key1->keydata.hmacsha256;
964 hkey2 = key2->keydata.hmacsha256;
966 if (hkey1 == NULL && hkey2 == NULL)
968 else if (hkey1 == NULL || hkey2 == NULL)
971 if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH) == 0)
978 hmacsha256_generate(dst_key_t *key, int pseudorandom_ok,
979 void (*callback)(int))
984 unsigned char data[ISC_SHA256_BLOCK_LENGTH];
988 bytes = (key->key_size + 7) / 8;
989 if (bytes > ISC_SHA256_BLOCK_LENGTH) {
990 bytes = ISC_SHA256_BLOCK_LENGTH;
991 key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
994 memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
995 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
997 if (ret != ISC_R_SUCCESS)
1000 isc_buffer_init(&b, data, bytes);
1001 isc_buffer_add(&b, bytes);
1002 ret = hmacsha256_fromdns(key, &b);
1003 memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
1008 static isc_boolean_t
1009 hmacsha256_isprivate(const dst_key_t *key) {
1015 hmacsha256_destroy(dst_key_t *key) {
1016 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
1018 memset(hkey, 0, sizeof(dst_hmacsha256_key_t));
1019 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t));
1020 key->keydata.hmacsha256 = NULL;
1024 hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
1025 dst_hmacsha256_key_t *hkey;
1028 REQUIRE(key->keydata.hmacsha256 != NULL);
1030 hkey = key->keydata.hmacsha256;
1032 bytes = (key->key_size + 7) / 8;
1033 if (isc_buffer_availablelength(data) < bytes)
1034 return (ISC_R_NOSPACE);
1035 isc_buffer_putmem(data, hkey->key, bytes);
1037 return (ISC_R_SUCCESS);
1041 hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
1042 dst_hmacsha256_key_t *hkey;
1045 isc_sha256_t sha256ctx;
1047 isc_buffer_remainingregion(data, &r);
1049 return (ISC_R_SUCCESS);
1051 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
1053 return (ISC_R_NOMEMORY);
1055 memset(hkey->key, 0, sizeof(hkey->key));
1057 if (r.length > ISC_SHA256_BLOCK_LENGTH) {
1058 isc_sha256_init(&sha256ctx);
1059 isc_sha256_update(&sha256ctx, r.base, r.length);
1060 isc_sha256_final(hkey->key, &sha256ctx);
1061 keylen = ISC_SHA256_DIGESTLENGTH;
1064 memcpy(hkey->key, r.base, r.length);
1068 key->key_size = keylen * 8;
1069 key->keydata.hmacsha256 = hkey;
1071 return (ISC_R_SUCCESS);
1075 hmacsha256_tofile(const dst_key_t *key, const char *directory) {
1077 dst_hmacsha256_key_t *hkey;
1079 int bytes = (key->key_size + 7) / 8;
1080 unsigned char buf[2];
1082 if (key->keydata.hmacsha256 == NULL)
1083 return (DST_R_NULLKEY);
1085 hkey = key->keydata.hmacsha256;
1087 priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
1088 priv.elements[cnt].length = bytes;
1089 priv.elements[cnt++].data = hkey->key;
1091 buf[0] = (key->key_bits >> 8) & 0xffU;
1092 buf[1] = key->key_bits & 0xffU;
1093 priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
1094 priv.elements[cnt].data = buf;
1095 priv.elements[cnt++].length = 2;
1097 priv.nelements = cnt;
1098 return (dst__privstruct_writefile(key, &priv, directory));
1102 hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
1104 isc_result_t result, tresult;
1106 isc_mem_t *mctx = key->mctx;
1110 /* read private key file */
1111 result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
1113 if (result != ISC_R_SUCCESS)
1117 for (i = 0; i < priv.nelements; i++) {
1118 switch (priv.elements[i].tag) {
1119 case TAG_HMACSHA256_KEY:
1120 isc_buffer_init(&b, priv.elements[i].data,
1121 priv.elements[i].length);
1122 isc_buffer_add(&b, priv.elements[i].length);
1123 tresult = hmacsha256_fromdns(key, &b);
1124 if (tresult != ISC_R_SUCCESS)
1127 case TAG_HMACSHA256_BITS:
1128 tresult = getkeybits(key, &priv.elements[i]);
1129 if (tresult != ISC_R_SUCCESS)
1133 result = DST_R_INVALIDPRIVATEKEY;
1137 dst__privstruct_free(&priv, mctx);
1138 memset(&priv, 0, sizeof(priv));
1142 static dst_func_t hmacsha256_functions = {
1143 hmacsha256_createctx,
1144 hmacsha256_destroyctx,
1148 NULL, /* computesecret */
1150 NULL, /* paramcompare */
1151 hmacsha256_generate,
1152 hmacsha256_isprivate,
1159 NULL, /* fromlabel */
1165 dst__hmacsha256_init(dst_func_t **funcp) {
1166 REQUIRE(funcp != NULL);
1168 *funcp = &hmacsha256_functions;
1169 return (ISC_R_SUCCESS);
1172 static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
1174 struct dst_hmacsha384_key {
1175 unsigned char key[ISC_SHA384_BLOCK_LENGTH];
1179 hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
1180 isc_hmacsha384_t *hmacsha384ctx;
1181 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
1183 hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
1184 if (hmacsha384ctx == NULL)
1185 return (ISC_R_NOMEMORY);
1186 isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH);
1187 dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
1188 return (ISC_R_SUCCESS);
1192 hmacsha384_destroyctx(dst_context_t *dctx) {
1193 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
1195 if (hmacsha384ctx != NULL) {
1196 isc_hmacsha384_invalidate(hmacsha384ctx);
1197 isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
1198 dctx->ctxdata.hmacsha384ctx = NULL;
1203 hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
1204 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
1206 isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
1207 return (ISC_R_SUCCESS);
1211 hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
1212 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
1213 unsigned char *digest;
1215 if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
1216 return (ISC_R_NOSPACE);
1217 digest = isc_buffer_used(sig);
1218 isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
1219 isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
1221 return (ISC_R_SUCCESS);
1225 hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
1226 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
1228 if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
1229 return (DST_R_VERIFYFAILURE);
1231 if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
1232 return (ISC_R_SUCCESS);
1234 return (DST_R_VERIFYFAILURE);
1237 static isc_boolean_t
1238 hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
1239 dst_hmacsha384_key_t *hkey1, *hkey2;
1241 hkey1 = key1->keydata.hmacsha384;
1242 hkey2 = key2->keydata.hmacsha384;
1244 if (hkey1 == NULL && hkey2 == NULL)
1246 else if (hkey1 == NULL || hkey2 == NULL)
1249 if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH) == 0)
1256 hmacsha384_generate(dst_key_t *key, int pseudorandom_ok,
1257 void (*callback)(int))
1262 unsigned char data[ISC_SHA384_BLOCK_LENGTH];
1266 bytes = (key->key_size + 7) / 8;
1267 if (bytes > ISC_SHA384_BLOCK_LENGTH) {
1268 bytes = ISC_SHA384_BLOCK_LENGTH;
1269 key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
1272 memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
1273 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
1275 if (ret != ISC_R_SUCCESS)
1278 isc_buffer_init(&b, data, bytes);
1279 isc_buffer_add(&b, bytes);
1280 ret = hmacsha384_fromdns(key, &b);
1281 memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
1286 static isc_boolean_t
1287 hmacsha384_isprivate(const dst_key_t *key) {
1293 hmacsha384_destroy(dst_key_t *key) {
1294 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
1296 memset(hkey, 0, sizeof(dst_hmacsha384_key_t));
1297 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t));
1298 key->keydata.hmacsha384 = NULL;
1302 hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
1303 dst_hmacsha384_key_t *hkey;
1306 REQUIRE(key->keydata.hmacsha384 != NULL);
1308 hkey = key->keydata.hmacsha384;
1310 bytes = (key->key_size + 7) / 8;
1311 if (isc_buffer_availablelength(data) < bytes)
1312 return (ISC_R_NOSPACE);
1313 isc_buffer_putmem(data, hkey->key, bytes);
1315 return (ISC_R_SUCCESS);
1319 hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
1320 dst_hmacsha384_key_t *hkey;
1323 isc_sha384_t sha384ctx;
1325 isc_buffer_remainingregion(data, &r);
1327 return (ISC_R_SUCCESS);
1329 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
1331 return (ISC_R_NOMEMORY);
1333 memset(hkey->key, 0, sizeof(hkey->key));
1335 if (r.length > ISC_SHA384_BLOCK_LENGTH) {
1336 isc_sha384_init(&sha384ctx);
1337 isc_sha384_update(&sha384ctx, r.base, r.length);
1338 isc_sha384_final(hkey->key, &sha384ctx);
1339 keylen = ISC_SHA384_DIGESTLENGTH;
1342 memcpy(hkey->key, r.base, r.length);
1346 key->key_size = keylen * 8;
1347 key->keydata.hmacsha384 = hkey;
1349 return (ISC_R_SUCCESS);
1353 hmacsha384_tofile(const dst_key_t *key, const char *directory) {
1355 dst_hmacsha384_key_t *hkey;
1357 int bytes = (key->key_size + 7) / 8;
1358 unsigned char buf[2];
1360 if (key->keydata.hmacsha384 == NULL)
1361 return (DST_R_NULLKEY);
1363 hkey = key->keydata.hmacsha384;
1365 priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
1366 priv.elements[cnt].length = bytes;
1367 priv.elements[cnt++].data = hkey->key;
1369 buf[0] = (key->key_bits >> 8) & 0xffU;
1370 buf[1] = key->key_bits & 0xffU;
1371 priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
1372 priv.elements[cnt].data = buf;
1373 priv.elements[cnt++].length = 2;
1375 priv.nelements = cnt;
1376 return (dst__privstruct_writefile(key, &priv, directory));
1380 hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
1382 isc_result_t result, tresult;
1384 isc_mem_t *mctx = key->mctx;
1388 /* read private key file */
1389 result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
1391 if (result != ISC_R_SUCCESS)
1395 for (i = 0; i < priv.nelements; i++) {
1396 switch (priv.elements[i].tag) {
1397 case TAG_HMACSHA384_KEY:
1398 isc_buffer_init(&b, priv.elements[i].data,
1399 priv.elements[i].length);
1400 isc_buffer_add(&b, priv.elements[i].length);
1401 tresult = hmacsha384_fromdns(key, &b);
1402 if (tresult != ISC_R_SUCCESS)
1405 case TAG_HMACSHA384_BITS:
1406 tresult = getkeybits(key, &priv.elements[i]);
1407 if (tresult != ISC_R_SUCCESS)
1411 result = DST_R_INVALIDPRIVATEKEY;
1415 dst__privstruct_free(&priv, mctx);
1416 memset(&priv, 0, sizeof(priv));
1420 static dst_func_t hmacsha384_functions = {
1421 hmacsha384_createctx,
1422 hmacsha384_destroyctx,
1426 NULL, /* computesecret */
1428 NULL, /* paramcompare */
1429 hmacsha384_generate,
1430 hmacsha384_isprivate,
1437 NULL, /* fromlabel */
1443 dst__hmacsha384_init(dst_func_t **funcp) {
1444 REQUIRE(funcp != NULL);
1446 *funcp = &hmacsha384_functions;
1447 return (ISC_R_SUCCESS);
1450 static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
1452 struct dst_hmacsha512_key {
1453 unsigned char key[ISC_SHA512_BLOCK_LENGTH];
1457 hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
1458 isc_hmacsha512_t *hmacsha512ctx;
1459 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
1461 hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
1462 if (hmacsha512ctx == NULL)
1463 return (ISC_R_NOMEMORY);
1464 isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH);
1465 dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
1466 return (ISC_R_SUCCESS);
1470 hmacsha512_destroyctx(dst_context_t *dctx) {
1471 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
1473 if (hmacsha512ctx != NULL) {
1474 isc_hmacsha512_invalidate(hmacsha512ctx);
1475 isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
1476 dctx->ctxdata.hmacsha512ctx = NULL;
1481 hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
1482 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
1484 isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
1485 return (ISC_R_SUCCESS);
1489 hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
1490 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
1491 unsigned char *digest;
1493 if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
1494 return (ISC_R_NOSPACE);
1495 digest = isc_buffer_used(sig);
1496 isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
1497 isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
1499 return (ISC_R_SUCCESS);
1503 hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
1504 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
1506 if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
1507 return (DST_R_VERIFYFAILURE);
1509 if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
1510 return (ISC_R_SUCCESS);
1512 return (DST_R_VERIFYFAILURE);
1515 static isc_boolean_t
1516 hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
1517 dst_hmacsha512_key_t *hkey1, *hkey2;
1519 hkey1 = key1->keydata.hmacsha512;
1520 hkey2 = key2->keydata.hmacsha512;
1522 if (hkey1 == NULL && hkey2 == NULL)
1524 else if (hkey1 == NULL || hkey2 == NULL)
1527 if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH) == 0)
1534 hmacsha512_generate(dst_key_t *key, int pseudorandom_ok,
1535 void (*callback)(int))
1540 unsigned char data[ISC_SHA512_BLOCK_LENGTH];
1544 bytes = (key->key_size + 7) / 8;
1545 if (bytes > ISC_SHA512_BLOCK_LENGTH) {
1546 bytes = ISC_SHA512_BLOCK_LENGTH;
1547 key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
1550 memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
1551 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
1553 if (ret != ISC_R_SUCCESS)
1556 isc_buffer_init(&b, data, bytes);
1557 isc_buffer_add(&b, bytes);
1558 ret = hmacsha512_fromdns(key, &b);
1559 memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
1564 static isc_boolean_t
1565 hmacsha512_isprivate(const dst_key_t *key) {
1571 hmacsha512_destroy(dst_key_t *key) {
1572 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
1574 memset(hkey, 0, sizeof(dst_hmacsha512_key_t));
1575 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t));
1576 key->keydata.hmacsha512 = NULL;
1580 hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
1581 dst_hmacsha512_key_t *hkey;
1584 REQUIRE(key->keydata.hmacsha512 != NULL);
1586 hkey = key->keydata.hmacsha512;
1588 bytes = (key->key_size + 7) / 8;
1589 if (isc_buffer_availablelength(data) < bytes)
1590 return (ISC_R_NOSPACE);
1591 isc_buffer_putmem(data, hkey->key, bytes);
1593 return (ISC_R_SUCCESS);
1597 hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
1598 dst_hmacsha512_key_t *hkey;
1601 isc_sha512_t sha512ctx;
1603 isc_buffer_remainingregion(data, &r);
1605 return (ISC_R_SUCCESS);
1607 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
1609 return (ISC_R_NOMEMORY);
1611 memset(hkey->key, 0, sizeof(hkey->key));
1613 if (r.length > ISC_SHA512_BLOCK_LENGTH) {
1614 isc_sha512_init(&sha512ctx);
1615 isc_sha512_update(&sha512ctx, r.base, r.length);
1616 isc_sha512_final(hkey->key, &sha512ctx);
1617 keylen = ISC_SHA512_DIGESTLENGTH;
1620 memcpy(hkey->key, r.base, r.length);
1624 key->key_size = keylen * 8;
1625 key->keydata.hmacsha512 = hkey;
1627 return (ISC_R_SUCCESS);
1631 hmacsha512_tofile(const dst_key_t *key, const char *directory) {
1633 dst_hmacsha512_key_t *hkey;
1635 int bytes = (key->key_size + 7) / 8;
1636 unsigned char buf[2];
1638 if (key->keydata.hmacsha512 == NULL)
1639 return (DST_R_NULLKEY);
1641 hkey = key->keydata.hmacsha512;
1643 priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
1644 priv.elements[cnt].length = bytes;
1645 priv.elements[cnt++].data = hkey->key;
1647 buf[0] = (key->key_bits >> 8) & 0xffU;
1648 buf[1] = key->key_bits & 0xffU;
1649 priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
1650 priv.elements[cnt].data = buf;
1651 priv.elements[cnt++].length = 2;
1653 priv.nelements = cnt;
1654 return (dst__privstruct_writefile(key, &priv, directory));
1658 hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
1660 isc_result_t result, tresult;
1662 isc_mem_t *mctx = key->mctx;
1666 /* read private key file */
1667 result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
1669 if (result != ISC_R_SUCCESS)
1673 for (i = 0; i < priv.nelements; i++) {
1674 switch (priv.elements[i].tag) {
1675 case TAG_HMACSHA512_KEY:
1676 isc_buffer_init(&b, priv.elements[i].data,
1677 priv.elements[i].length);
1678 isc_buffer_add(&b, priv.elements[i].length);
1679 tresult = hmacsha512_fromdns(key, &b);
1680 if (tresult != ISC_R_SUCCESS)
1683 case TAG_HMACSHA512_BITS:
1684 tresult = getkeybits(key, &priv.elements[i]);
1685 if (tresult != ISC_R_SUCCESS)
1689 result = DST_R_INVALIDPRIVATEKEY;
1693 dst__privstruct_free(&priv, mctx);
1694 memset(&priv, 0, sizeof(priv));
1698 static dst_func_t hmacsha512_functions = {
1699 hmacsha512_createctx,
1700 hmacsha512_destroyctx,
1704 NULL, /* computesecret */
1706 NULL, /* paramcompare */
1707 hmacsha512_generate,
1708 hmacsha512_isprivate,
1715 NULL, /* fromlabel */
1721 dst__hmacsha512_init(dst_func_t **funcp) {
1722 REQUIRE(funcp != NULL);
1724 *funcp = &hmacsha512_functions;
1725 return (ISC_R_SUCCESS);