4 * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright (C) 1999-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
14 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
17 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
21 * Permission to use, copy, modify, and/or distribute this software for any
22 * purpose with or without fee is hereby granted, provided that the above
23 * copyright notice and this permission notice appear in all copies.
25 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
26 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
28 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
31 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 * Principal Author: Brian Wellington
36 * Id: hmac_link.c,v 1.15 2009/10/24 09:46:19 fdupont Exp
41 #include <isc/buffer.h>
42 #include <isc/hmacmd5.h>
43 #include <isc/hmacsha.h>
47 #include <isc/string.h>
50 #include <dst/result.h>
52 #include "dst_internal.h"
53 #include "dst_parse.h"
56 #define HMAC_IPAD 0x36
57 #define HMAC_OPAD 0x5c
59 static isc_result_t
hmacmd5_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
61 struct dst_hmacmd5_key
{
62 unsigned char key
[HMAC_LEN
];
66 getkeybits(dst_key_t
*key
, struct dst_private_element
*element
) {
68 if (element
->length
!= 2)
69 return (DST_R_INVALIDPRIVATEKEY
);
71 key
->key_bits
= (element
->data
[0] << 8) + element
->data
[1];
73 return (ISC_R_SUCCESS
);
77 hmacmd5_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
78 isc_hmacmd5_t
*hmacmd5ctx
;
79 dst_hmacmd5_key_t
*hkey
= key
->keydata
.hmacmd5
;
81 hmacmd5ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacmd5_t
));
82 if (hmacmd5ctx
== NULL
)
83 return (ISC_R_NOMEMORY
);
84 isc_hmacmd5_init(hmacmd5ctx
, hkey
->key
, HMAC_LEN
);
85 dctx
->ctxdata
.hmacmd5ctx
= hmacmd5ctx
;
86 return (ISC_R_SUCCESS
);
90 hmacmd5_destroyctx(dst_context_t
*dctx
) {
91 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
93 if (hmacmd5ctx
!= NULL
) {
94 isc_hmacmd5_invalidate(hmacmd5ctx
);
95 isc_mem_put(dctx
->mctx
, hmacmd5ctx
, sizeof(isc_hmacmd5_t
));
96 dctx
->ctxdata
.hmacmd5ctx
= NULL
;
101 hmacmd5_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
102 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
104 isc_hmacmd5_update(hmacmd5ctx
, data
->base
, data
->length
);
105 return (ISC_R_SUCCESS
);
109 hmacmd5_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
110 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
111 unsigned char *digest
;
113 if (isc_buffer_availablelength(sig
) < ISC_MD5_DIGESTLENGTH
)
114 return (ISC_R_NOSPACE
);
115 digest
= isc_buffer_used(sig
);
116 isc_hmacmd5_sign(hmacmd5ctx
, digest
);
117 isc_buffer_add(sig
, ISC_MD5_DIGESTLENGTH
);
119 return (ISC_R_SUCCESS
);
123 hmacmd5_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
124 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
126 if (sig
->length
> ISC_MD5_DIGESTLENGTH
)
127 return (DST_R_VERIFYFAILURE
);
129 if (isc_hmacmd5_verify2(hmacmd5ctx
, sig
->base
, sig
->length
))
130 return (ISC_R_SUCCESS
);
132 return (DST_R_VERIFYFAILURE
);
136 hmacmd5_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
137 dst_hmacmd5_key_t
*hkey1
, *hkey2
;
139 hkey1
= key1
->keydata
.hmacmd5
;
140 hkey2
= key2
->keydata
.hmacmd5
;
142 if (hkey1
== NULL
&& hkey2
== NULL
)
144 else if (hkey1
== NULL
|| hkey2
== NULL
)
147 if (memcmp(hkey1
->key
, hkey2
->key
, HMAC_LEN
) == 0)
154 hmacmd5_generate(dst_key_t
*key
, int pseudorandom_ok
, void (*callback
)(int)) {
158 unsigned char data
[HMAC_LEN
];
162 bytes
= (key
->key_size
+ 7) / 8;
163 if (bytes
> HMAC_LEN
) {
165 key
->key_size
= HMAC_LEN
* 8;
168 memset(data
, 0, HMAC_LEN
);
169 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
171 if (ret
!= ISC_R_SUCCESS
)
174 isc_buffer_init(&b
, data
, bytes
);
175 isc_buffer_add(&b
, bytes
);
176 ret
= hmacmd5_fromdns(key
, &b
);
177 memset(data
, 0, HMAC_LEN
);
183 hmacmd5_isprivate(const dst_key_t
*key
) {
189 hmacmd5_destroy(dst_key_t
*key
) {
190 dst_hmacmd5_key_t
*hkey
= key
->keydata
.hmacmd5
;
191 memset(hkey
, 0, sizeof(dst_hmacmd5_key_t
));
192 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacmd5_key_t
));
193 key
->keydata
.hmacmd5
= NULL
;
197 hmacmd5_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
198 dst_hmacmd5_key_t
*hkey
;
201 REQUIRE(key
->keydata
.hmacmd5
!= NULL
);
203 hkey
= key
->keydata
.hmacmd5
;
205 bytes
= (key
->key_size
+ 7) / 8;
206 if (isc_buffer_availablelength(data
) < bytes
)
207 return (ISC_R_NOSPACE
);
208 isc_buffer_putmem(data
, hkey
->key
, bytes
);
210 return (ISC_R_SUCCESS
);
214 hmacmd5_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
215 dst_hmacmd5_key_t
*hkey
;
220 isc_buffer_remainingregion(data
, &r
);
222 return (ISC_R_SUCCESS
);
224 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacmd5_key_t
));
226 return (ISC_R_NOMEMORY
);
228 memset(hkey
->key
, 0, sizeof(hkey
->key
));
230 if (r
.length
> HMAC_LEN
) {
231 isc_md5_init(&md5ctx
);
232 isc_md5_update(&md5ctx
, r
.base
, r
.length
);
233 isc_md5_final(&md5ctx
, hkey
->key
);
234 keylen
= ISC_MD5_DIGESTLENGTH
;
237 memcpy(hkey
->key
, r
.base
, r
.length
);
241 key
->key_size
= keylen
* 8;
242 key
->keydata
.hmacmd5
= hkey
;
244 return (ISC_R_SUCCESS
);
248 hmacmd5_tofile(const dst_key_t
*key
, const char *directory
) {
250 dst_hmacmd5_key_t
*hkey
;
252 int bytes
= (key
->key_size
+ 7) / 8;
253 unsigned char buf
[2];
255 if (key
->keydata
.hmacmd5
== NULL
)
256 return (DST_R_NULLKEY
);
258 hkey
= key
->keydata
.hmacmd5
;
260 priv
.elements
[cnt
].tag
= TAG_HMACMD5_KEY
;
261 priv
.elements
[cnt
].length
= bytes
;
262 priv
.elements
[cnt
++].data
= hkey
->key
;
264 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
265 buf
[1] = key
->key_bits
& 0xffU
;
266 priv
.elements
[cnt
].tag
= TAG_HMACMD5_BITS
;
267 priv
.elements
[cnt
].data
= buf
;
268 priv
.elements
[cnt
++].length
= 2;
270 priv
.nelements
= cnt
;
271 return (dst__privstruct_writefile(key
, &priv
, directory
));
275 hmacmd5_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
277 isc_result_t result
, tresult
;
279 isc_mem_t
*mctx
= key
->mctx
;
283 /* read private key file */
284 result
= dst__privstruct_parse(key
, DST_ALG_HMACMD5
, lexer
, mctx
,
286 if (result
!= ISC_R_SUCCESS
)
290 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
291 switch (priv
.elements
[i
].tag
) {
292 case TAG_HMACMD5_KEY
:
293 isc_buffer_init(&b
, priv
.elements
[i
].data
,
294 priv
.elements
[i
].length
);
295 isc_buffer_add(&b
, priv
.elements
[i
].length
);
296 tresult
= hmacmd5_fromdns(key
, &b
);
297 if (tresult
!= ISC_R_SUCCESS
)
300 case TAG_HMACMD5_BITS
:
301 tresult
= getkeybits(key
, &priv
.elements
[i
]);
302 if (tresult
!= ISC_R_SUCCESS
)
306 result
= DST_R_INVALIDPRIVATEKEY
;
310 dst__privstruct_free(&priv
, mctx
);
311 memset(&priv
, 0, sizeof(priv
));
315 static dst_func_t hmacmd5_functions
= {
321 NULL
, /*%< computesecret */
323 NULL
, /*%< paramcompare */
331 NULL
, /*%< cleanup */
332 NULL
, /*%< fromlabel */
336 dst__hmacmd5_init(dst_func_t
**funcp
) {
337 REQUIRE(funcp
!= NULL
);
339 *funcp
= &hmacmd5_functions
;
340 return (ISC_R_SUCCESS
);
343 static isc_result_t
hmacsha1_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
345 struct dst_hmacsha1_key
{
346 unsigned char key
[ISC_SHA1_DIGESTLENGTH
];
350 hmacsha1_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
351 isc_hmacsha1_t
*hmacsha1ctx
;
352 dst_hmacsha1_key_t
*hkey
= key
->keydata
.hmacsha1
;
354 hmacsha1ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha1_t
));
355 if (hmacsha1ctx
== NULL
)
356 return (ISC_R_NOMEMORY
);
357 isc_hmacsha1_init(hmacsha1ctx
, hkey
->key
, ISC_SHA1_DIGESTLENGTH
);
358 dctx
->ctxdata
.hmacsha1ctx
= hmacsha1ctx
;
359 return (ISC_R_SUCCESS
);
363 hmacsha1_destroyctx(dst_context_t
*dctx
) {
364 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
366 if (hmacsha1ctx
!= NULL
) {
367 isc_hmacsha1_invalidate(hmacsha1ctx
);
368 isc_mem_put(dctx
->mctx
, hmacsha1ctx
, sizeof(isc_hmacsha1_t
));
369 dctx
->ctxdata
.hmacsha1ctx
= NULL
;
374 hmacsha1_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
375 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
377 isc_hmacsha1_update(hmacsha1ctx
, data
->base
, data
->length
);
378 return (ISC_R_SUCCESS
);
382 hmacsha1_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
383 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
384 unsigned char *digest
;
386 if (isc_buffer_availablelength(sig
) < ISC_SHA1_DIGESTLENGTH
)
387 return (ISC_R_NOSPACE
);
388 digest
= isc_buffer_used(sig
);
389 isc_hmacsha1_sign(hmacsha1ctx
, digest
, ISC_SHA1_DIGESTLENGTH
);
390 isc_buffer_add(sig
, ISC_SHA1_DIGESTLENGTH
);
392 return (ISC_R_SUCCESS
);
396 hmacsha1_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
397 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
399 if (sig
->length
> ISC_SHA1_DIGESTLENGTH
|| sig
->length
== 0)
400 return (DST_R_VERIFYFAILURE
);
402 if (isc_hmacsha1_verify(hmacsha1ctx
, sig
->base
, sig
->length
))
403 return (ISC_R_SUCCESS
);
405 return (DST_R_VERIFYFAILURE
);
409 hmacsha1_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
410 dst_hmacsha1_key_t
*hkey1
, *hkey2
;
412 hkey1
= key1
->keydata
.hmacsha1
;
413 hkey2
= key2
->keydata
.hmacsha1
;
415 if (hkey1
== NULL
&& hkey2
== NULL
)
417 else if (hkey1
== NULL
|| hkey2
== NULL
)
420 if (memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA1_DIGESTLENGTH
) == 0)
427 hmacsha1_generate(dst_key_t
*key
, int pseudorandom_ok
, void (*callback
)(int)) {
431 unsigned char data
[HMAC_LEN
];
435 bytes
= (key
->key_size
+ 7) / 8;
436 if (bytes
> HMAC_LEN
) {
438 key
->key_size
= HMAC_LEN
* 8;
441 memset(data
, 0, HMAC_LEN
);
442 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
444 if (ret
!= ISC_R_SUCCESS
)
447 isc_buffer_init(&b
, data
, bytes
);
448 isc_buffer_add(&b
, bytes
);
449 ret
= hmacsha1_fromdns(key
, &b
);
450 memset(data
, 0, ISC_SHA1_DIGESTLENGTH
);
456 hmacsha1_isprivate(const dst_key_t
*key
) {
462 hmacsha1_destroy(dst_key_t
*key
) {
463 dst_hmacsha1_key_t
*hkey
= key
->keydata
.hmacsha1
;
464 memset(hkey
, 0, sizeof(dst_hmacsha1_key_t
));
465 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha1_key_t
));
466 key
->keydata
.hmacsha1
= NULL
;
470 hmacsha1_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
471 dst_hmacsha1_key_t
*hkey
;
474 REQUIRE(key
->keydata
.hmacsha1
!= NULL
);
476 hkey
= key
->keydata
.hmacsha1
;
478 bytes
= (key
->key_size
+ 7) / 8;
479 if (isc_buffer_availablelength(data
) < bytes
)
480 return (ISC_R_NOSPACE
);
481 isc_buffer_putmem(data
, hkey
->key
, bytes
);
483 return (ISC_R_SUCCESS
);
487 hmacsha1_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
488 dst_hmacsha1_key_t
*hkey
;
493 isc_buffer_remainingregion(data
, &r
);
495 return (ISC_R_SUCCESS
);
497 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha1_key_t
));
499 return (ISC_R_NOMEMORY
);
501 memset(hkey
->key
, 0, sizeof(hkey
->key
));
503 if (r
.length
> ISC_SHA1_DIGESTLENGTH
) {
504 isc_sha1_init(&sha1ctx
);
505 isc_sha1_update(&sha1ctx
, r
.base
, r
.length
);
506 isc_sha1_final(&sha1ctx
, hkey
->key
);
507 keylen
= ISC_SHA1_DIGESTLENGTH
;
510 memcpy(hkey
->key
, r
.base
, r
.length
);
514 key
->key_size
= keylen
* 8;
515 key
->keydata
.hmacsha1
= hkey
;
517 return (ISC_R_SUCCESS
);
521 hmacsha1_tofile(const dst_key_t
*key
, const char *directory
) {
523 dst_hmacsha1_key_t
*hkey
;
525 int bytes
= (key
->key_size
+ 7) / 8;
526 unsigned char buf
[2];
528 if (key
->keydata
.hmacsha1
== NULL
)
529 return (DST_R_NULLKEY
);
531 hkey
= key
->keydata
.hmacsha1
;
533 priv
.elements
[cnt
].tag
= TAG_HMACSHA1_KEY
;
534 priv
.elements
[cnt
].length
= bytes
;
535 priv
.elements
[cnt
++].data
= hkey
->key
;
537 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
538 buf
[1] = key
->key_bits
& 0xffU
;
539 priv
.elements
[cnt
].tag
= TAG_HMACSHA1_BITS
;
540 priv
.elements
[cnt
].data
= buf
;
541 priv
.elements
[cnt
++].length
= 2;
543 priv
.nelements
= cnt
;
544 return (dst__privstruct_writefile(key
, &priv
, directory
));
548 hmacsha1_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
550 isc_result_t result
, tresult
;
552 isc_mem_t
*mctx
= key
->mctx
;
556 /* read private key file */
557 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA1
, lexer
, mctx
,
559 if (result
!= ISC_R_SUCCESS
)
563 for (i
= 0; i
< priv
.nelements
; i
++) {
564 switch (priv
.elements
[i
].tag
) {
565 case TAG_HMACSHA1_KEY
:
566 isc_buffer_init(&b
, priv
.elements
[i
].data
,
567 priv
.elements
[i
].length
);
568 isc_buffer_add(&b
, priv
.elements
[i
].length
);
569 tresult
= hmacsha1_fromdns(key
, &b
);
570 if (tresult
!= ISC_R_SUCCESS
)
573 case TAG_HMACSHA1_BITS
:
574 tresult
= getkeybits(key
, &priv
.elements
[i
]);
575 if (tresult
!= ISC_R_SUCCESS
)
579 result
= DST_R_INVALIDPRIVATEKEY
;
583 dst__privstruct_free(&priv
, mctx
);
584 memset(&priv
, 0, sizeof(priv
));
588 static dst_func_t hmacsha1_functions
= {
594 NULL
, /* computesecret */
596 NULL
, /* paramcompare */
605 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_DIGESTLENGTH
];
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_DIGESTLENGTH
);
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_DIGESTLENGTH
) == 0)
700 hmacsha224_generate(dst_key_t
*key
, int pseudorandom_ok
,
701 void (*callback
)(int))
706 unsigned char data
[HMAC_LEN
];
710 bytes
= (key
->key_size
+ 7) / 8;
711 if (bytes
> HMAC_LEN
) {
713 key
->key_size
= HMAC_LEN
* 8;
716 memset(data
, 0, HMAC_LEN
);
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_DIGESTLENGTH
);
731 hmacsha224_isprivate(const dst_key_t
*key
) {
737 hmacsha224_destroy(dst_key_t
*key
) {
738 dst_hmacsha224_key_t
*hkey
= key
->keydata
.hmacsha224
;
739 memset(hkey
, 0, sizeof(dst_hmacsha224_key_t
));
740 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha224_key_t
));
741 key
->keydata
.hmacsha224
= NULL
;
745 hmacsha224_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
746 dst_hmacsha224_key_t
*hkey
;
749 REQUIRE(key
->keydata
.hmacsha224
!= NULL
);
751 hkey
= key
->keydata
.hmacsha224
;
753 bytes
= (key
->key_size
+ 7) / 8;
754 if (isc_buffer_availablelength(data
) < bytes
)
755 return (ISC_R_NOSPACE
);
756 isc_buffer_putmem(data
, hkey
->key
, bytes
);
758 return (ISC_R_SUCCESS
);
762 hmacsha224_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
763 dst_hmacsha224_key_t
*hkey
;
766 isc_sha224_t sha224ctx
;
768 isc_buffer_remainingregion(data
, &r
);
770 return (ISC_R_SUCCESS
);
772 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha224_key_t
));
774 return (ISC_R_NOMEMORY
);
776 memset(hkey
->key
, 0, sizeof(hkey
->key
));
778 if (r
.length
> ISC_SHA224_DIGESTLENGTH
) {
779 isc_sha224_init(&sha224ctx
);
780 isc_sha224_update(&sha224ctx
, r
.base
, r
.length
);
781 isc_sha224_final(hkey
->key
, &sha224ctx
);
782 keylen
= ISC_SHA224_DIGESTLENGTH
;
785 memcpy(hkey
->key
, r
.base
, r
.length
);
789 key
->key_size
= keylen
* 8;
790 key
->keydata
.hmacsha224
= hkey
;
792 return (ISC_R_SUCCESS
);
796 hmacsha224_tofile(const dst_key_t
*key
, const char *directory
) {
798 dst_hmacsha224_key_t
*hkey
;
800 int bytes
= (key
->key_size
+ 7) / 8;
801 unsigned char buf
[2];
803 if (key
->keydata
.hmacsha224
== NULL
)
804 return (DST_R_NULLKEY
);
806 hkey
= key
->keydata
.hmacsha224
;
808 priv
.elements
[cnt
].tag
= TAG_HMACSHA224_KEY
;
809 priv
.elements
[cnt
].length
= bytes
;
810 priv
.elements
[cnt
++].data
= hkey
->key
;
812 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
813 buf
[1] = key
->key_bits
& 0xffU
;
814 priv
.elements
[cnt
].tag
= TAG_HMACSHA224_BITS
;
815 priv
.elements
[cnt
].data
= buf
;
816 priv
.elements
[cnt
++].length
= 2;
818 priv
.nelements
= cnt
;
819 return (dst__privstruct_writefile(key
, &priv
, directory
));
823 hmacsha224_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
825 isc_result_t result
, tresult
;
827 isc_mem_t
*mctx
= key
->mctx
;
831 /* read private key file */
832 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA224
, lexer
, mctx
,
834 if (result
!= ISC_R_SUCCESS
)
838 for (i
= 0; i
< priv
.nelements
; i
++) {
839 switch (priv
.elements
[i
].tag
) {
840 case TAG_HMACSHA224_KEY
:
841 isc_buffer_init(&b
, priv
.elements
[i
].data
,
842 priv
.elements
[i
].length
);
843 isc_buffer_add(&b
, priv
.elements
[i
].length
);
844 tresult
= hmacsha224_fromdns(key
, &b
);
845 if (tresult
!= ISC_R_SUCCESS
)
848 case TAG_HMACSHA224_BITS
:
849 tresult
= getkeybits(key
, &priv
.elements
[i
]);
850 if (tresult
!= ISC_R_SUCCESS
)
854 result
= DST_R_INVALIDPRIVATEKEY
;
858 dst__privstruct_free(&priv
, mctx
);
859 memset(&priv
, 0, sizeof(priv
));
863 static dst_func_t hmacsha224_functions
= {
864 hmacsha224_createctx
,
865 hmacsha224_destroyctx
,
869 NULL
, /* computesecret */
871 NULL
, /* paramcompare */
873 hmacsha224_isprivate
,
880 NULL
, /* fromlabel */
884 dst__hmacsha224_init(dst_func_t
**funcp
) {
885 REQUIRE(funcp
!= NULL
);
887 *funcp
= &hmacsha224_functions
;
888 return (ISC_R_SUCCESS
);
891 static isc_result_t
hmacsha256_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
893 struct dst_hmacsha256_key
{
894 unsigned char key
[ISC_SHA256_DIGESTLENGTH
];
898 hmacsha256_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
899 isc_hmacsha256_t
*hmacsha256ctx
;
900 dst_hmacsha256_key_t
*hkey
= key
->keydata
.hmacsha256
;
902 hmacsha256ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha256_t
));
903 if (hmacsha256ctx
== NULL
)
904 return (ISC_R_NOMEMORY
);
905 isc_hmacsha256_init(hmacsha256ctx
, hkey
->key
, ISC_SHA256_DIGESTLENGTH
);
906 dctx
->ctxdata
.hmacsha256ctx
= hmacsha256ctx
;
907 return (ISC_R_SUCCESS
);
911 hmacsha256_destroyctx(dst_context_t
*dctx
) {
912 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
914 if (hmacsha256ctx
!= NULL
) {
915 isc_hmacsha256_invalidate(hmacsha256ctx
);
916 isc_mem_put(dctx
->mctx
, hmacsha256ctx
, sizeof(isc_hmacsha256_t
));
917 dctx
->ctxdata
.hmacsha256ctx
= NULL
;
922 hmacsha256_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
923 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
925 isc_hmacsha256_update(hmacsha256ctx
, data
->base
, data
->length
);
926 return (ISC_R_SUCCESS
);
930 hmacsha256_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
931 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
932 unsigned char *digest
;
934 if (isc_buffer_availablelength(sig
) < ISC_SHA256_DIGESTLENGTH
)
935 return (ISC_R_NOSPACE
);
936 digest
= isc_buffer_used(sig
);
937 isc_hmacsha256_sign(hmacsha256ctx
, digest
, ISC_SHA256_DIGESTLENGTH
);
938 isc_buffer_add(sig
, ISC_SHA256_DIGESTLENGTH
);
940 return (ISC_R_SUCCESS
);
944 hmacsha256_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
945 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
947 if (sig
->length
> ISC_SHA256_DIGESTLENGTH
|| sig
->length
== 0)
948 return (DST_R_VERIFYFAILURE
);
950 if (isc_hmacsha256_verify(hmacsha256ctx
, sig
->base
, sig
->length
))
951 return (ISC_R_SUCCESS
);
953 return (DST_R_VERIFYFAILURE
);
957 hmacsha256_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
958 dst_hmacsha256_key_t
*hkey1
, *hkey2
;
960 hkey1
= key1
->keydata
.hmacsha256
;
961 hkey2
= key2
->keydata
.hmacsha256
;
963 if (hkey1
== NULL
&& hkey2
== NULL
)
965 else if (hkey1
== NULL
|| hkey2
== NULL
)
968 if (memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA256_DIGESTLENGTH
) == 0)
975 hmacsha256_generate(dst_key_t
*key
, int pseudorandom_ok
,
976 void (*callback
)(int))
981 unsigned char data
[HMAC_LEN
];
985 bytes
= (key
->key_size
+ 7) / 8;
986 if (bytes
> HMAC_LEN
) {
988 key
->key_size
= HMAC_LEN
* 8;
991 memset(data
, 0, HMAC_LEN
);
992 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
994 if (ret
!= ISC_R_SUCCESS
)
997 isc_buffer_init(&b
, data
, bytes
);
998 isc_buffer_add(&b
, bytes
);
999 ret
= hmacsha256_fromdns(key
, &b
);
1000 memset(data
, 0, ISC_SHA256_DIGESTLENGTH
);
1005 static isc_boolean_t
1006 hmacsha256_isprivate(const dst_key_t
*key
) {
1012 hmacsha256_destroy(dst_key_t
*key
) {
1013 dst_hmacsha256_key_t
*hkey
= key
->keydata
.hmacsha256
;
1014 memset(hkey
, 0, sizeof(dst_hmacsha256_key_t
));
1015 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha256_key_t
));
1016 key
->keydata
.hmacsha256
= NULL
;
1020 hmacsha256_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1021 dst_hmacsha256_key_t
*hkey
;
1024 REQUIRE(key
->keydata
.hmacsha256
!= NULL
);
1026 hkey
= key
->keydata
.hmacsha256
;
1028 bytes
= (key
->key_size
+ 7) / 8;
1029 if (isc_buffer_availablelength(data
) < bytes
)
1030 return (ISC_R_NOSPACE
);
1031 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1033 return (ISC_R_SUCCESS
);
1037 hmacsha256_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1038 dst_hmacsha256_key_t
*hkey
;
1041 isc_sha256_t sha256ctx
;
1043 isc_buffer_remainingregion(data
, &r
);
1045 return (ISC_R_SUCCESS
);
1047 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha256_key_t
));
1049 return (ISC_R_NOMEMORY
);
1051 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1053 if (r
.length
> ISC_SHA256_DIGESTLENGTH
) {
1054 isc_sha256_init(&sha256ctx
);
1055 isc_sha256_update(&sha256ctx
, r
.base
, r
.length
);
1056 isc_sha256_final(hkey
->key
, &sha256ctx
);
1057 keylen
= ISC_SHA256_DIGESTLENGTH
;
1060 memcpy(hkey
->key
, r
.base
, r
.length
);
1064 key
->key_size
= keylen
* 8;
1065 key
->keydata
.hmacsha256
= hkey
;
1067 return (ISC_R_SUCCESS
);
1071 hmacsha256_tofile(const dst_key_t
*key
, const char *directory
) {
1073 dst_hmacsha256_key_t
*hkey
;
1075 int bytes
= (key
->key_size
+ 7) / 8;
1076 unsigned char buf
[2];
1078 if (key
->keydata
.hmacsha256
== NULL
)
1079 return (DST_R_NULLKEY
);
1081 hkey
= key
->keydata
.hmacsha256
;
1083 priv
.elements
[cnt
].tag
= TAG_HMACSHA256_KEY
;
1084 priv
.elements
[cnt
].length
= bytes
;
1085 priv
.elements
[cnt
++].data
= hkey
->key
;
1087 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1088 buf
[1] = key
->key_bits
& 0xffU
;
1089 priv
.elements
[cnt
].tag
= TAG_HMACSHA256_BITS
;
1090 priv
.elements
[cnt
].data
= buf
;
1091 priv
.elements
[cnt
++].length
= 2;
1093 priv
.nelements
= cnt
;
1094 return (dst__privstruct_writefile(key
, &priv
, directory
));
1098 hmacsha256_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1100 isc_result_t result
, tresult
;
1102 isc_mem_t
*mctx
= key
->mctx
;
1106 /* read private key file */
1107 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA256
, lexer
, mctx
,
1109 if (result
!= ISC_R_SUCCESS
)
1113 for (i
= 0; i
< priv
.nelements
; i
++) {
1114 switch (priv
.elements
[i
].tag
) {
1115 case TAG_HMACSHA256_KEY
:
1116 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1117 priv
.elements
[i
].length
);
1118 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1119 tresult
= hmacsha256_fromdns(key
, &b
);
1120 if (tresult
!= ISC_R_SUCCESS
)
1123 case TAG_HMACSHA256_BITS
:
1124 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1125 if (tresult
!= ISC_R_SUCCESS
)
1129 result
= DST_R_INVALIDPRIVATEKEY
;
1133 dst__privstruct_free(&priv
, mctx
);
1134 memset(&priv
, 0, sizeof(priv
));
1138 static dst_func_t hmacsha256_functions
= {
1139 hmacsha256_createctx
,
1140 hmacsha256_destroyctx
,
1144 NULL
, /* computesecret */
1146 NULL
, /* paramcompare */
1147 hmacsha256_generate
,
1148 hmacsha256_isprivate
,
1155 NULL
, /* fromlabel */
1159 dst__hmacsha256_init(dst_func_t
**funcp
) {
1160 REQUIRE(funcp
!= NULL
);
1162 *funcp
= &hmacsha256_functions
;
1163 return (ISC_R_SUCCESS
);
1166 static isc_result_t
hmacsha384_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
1168 struct dst_hmacsha384_key
{
1169 unsigned char key
[ISC_SHA384_DIGESTLENGTH
];
1173 hmacsha384_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
1174 isc_hmacsha384_t
*hmacsha384ctx
;
1175 dst_hmacsha384_key_t
*hkey
= key
->keydata
.hmacsha384
;
1177 hmacsha384ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha384_t
));
1178 if (hmacsha384ctx
== NULL
)
1179 return (ISC_R_NOMEMORY
);
1180 isc_hmacsha384_init(hmacsha384ctx
, hkey
->key
, ISC_SHA384_DIGESTLENGTH
);
1181 dctx
->ctxdata
.hmacsha384ctx
= hmacsha384ctx
;
1182 return (ISC_R_SUCCESS
);
1186 hmacsha384_destroyctx(dst_context_t
*dctx
) {
1187 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1189 if (hmacsha384ctx
!= NULL
) {
1190 isc_hmacsha384_invalidate(hmacsha384ctx
);
1191 isc_mem_put(dctx
->mctx
, hmacsha384ctx
, sizeof(isc_hmacsha384_t
));
1192 dctx
->ctxdata
.hmacsha384ctx
= NULL
;
1197 hmacsha384_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
1198 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1200 isc_hmacsha384_update(hmacsha384ctx
, data
->base
, data
->length
);
1201 return (ISC_R_SUCCESS
);
1205 hmacsha384_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
1206 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1207 unsigned char *digest
;
1209 if (isc_buffer_availablelength(sig
) < ISC_SHA384_DIGESTLENGTH
)
1210 return (ISC_R_NOSPACE
);
1211 digest
= isc_buffer_used(sig
);
1212 isc_hmacsha384_sign(hmacsha384ctx
, digest
, ISC_SHA384_DIGESTLENGTH
);
1213 isc_buffer_add(sig
, ISC_SHA384_DIGESTLENGTH
);
1215 return (ISC_R_SUCCESS
);
1219 hmacsha384_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
1220 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1222 if (sig
->length
> ISC_SHA384_DIGESTLENGTH
|| sig
->length
== 0)
1223 return (DST_R_VERIFYFAILURE
);
1225 if (isc_hmacsha384_verify(hmacsha384ctx
, sig
->base
, sig
->length
))
1226 return (ISC_R_SUCCESS
);
1228 return (DST_R_VERIFYFAILURE
);
1231 static isc_boolean_t
1232 hmacsha384_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
1233 dst_hmacsha384_key_t
*hkey1
, *hkey2
;
1235 hkey1
= key1
->keydata
.hmacsha384
;
1236 hkey2
= key2
->keydata
.hmacsha384
;
1238 if (hkey1
== NULL
&& hkey2
== NULL
)
1240 else if (hkey1
== NULL
|| hkey2
== NULL
)
1243 if (memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA384_DIGESTLENGTH
) == 0)
1250 hmacsha384_generate(dst_key_t
*key
, int pseudorandom_ok
,
1251 void (*callback
)(int))
1256 unsigned char data
[HMAC_LEN
];
1260 bytes
= (key
->key_size
+ 7) / 8;
1261 if (bytes
> HMAC_LEN
) {
1263 key
->key_size
= HMAC_LEN
* 8;
1266 memset(data
, 0, HMAC_LEN
);
1267 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
1269 if (ret
!= ISC_R_SUCCESS
)
1272 isc_buffer_init(&b
, data
, bytes
);
1273 isc_buffer_add(&b
, bytes
);
1274 ret
= hmacsha384_fromdns(key
, &b
);
1275 memset(data
, 0, ISC_SHA384_DIGESTLENGTH
);
1280 static isc_boolean_t
1281 hmacsha384_isprivate(const dst_key_t
*key
) {
1287 hmacsha384_destroy(dst_key_t
*key
) {
1288 dst_hmacsha384_key_t
*hkey
= key
->keydata
.hmacsha384
;
1289 memset(hkey
, 0, sizeof(dst_hmacsha384_key_t
));
1290 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha384_key_t
));
1291 key
->keydata
.hmacsha384
= NULL
;
1295 hmacsha384_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1296 dst_hmacsha384_key_t
*hkey
;
1299 REQUIRE(key
->keydata
.hmacsha384
!= NULL
);
1301 hkey
= key
->keydata
.hmacsha384
;
1303 bytes
= (key
->key_size
+ 7) / 8;
1304 if (isc_buffer_availablelength(data
) < bytes
)
1305 return (ISC_R_NOSPACE
);
1306 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1308 return (ISC_R_SUCCESS
);
1312 hmacsha384_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1313 dst_hmacsha384_key_t
*hkey
;
1316 isc_sha384_t sha384ctx
;
1318 isc_buffer_remainingregion(data
, &r
);
1320 return (ISC_R_SUCCESS
);
1322 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha384_key_t
));
1324 return (ISC_R_NOMEMORY
);
1326 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1328 if (r
.length
> ISC_SHA384_DIGESTLENGTH
) {
1329 isc_sha384_init(&sha384ctx
);
1330 isc_sha384_update(&sha384ctx
, r
.base
, r
.length
);
1331 isc_sha384_final(hkey
->key
, &sha384ctx
);
1332 keylen
= ISC_SHA384_DIGESTLENGTH
;
1335 memcpy(hkey
->key
, r
.base
, r
.length
);
1339 key
->key_size
= keylen
* 8;
1340 key
->keydata
.hmacsha384
= hkey
;
1342 return (ISC_R_SUCCESS
);
1346 hmacsha384_tofile(const dst_key_t
*key
, const char *directory
) {
1348 dst_hmacsha384_key_t
*hkey
;
1350 int bytes
= (key
->key_size
+ 7) / 8;
1351 unsigned char buf
[2];
1353 if (key
->keydata
.hmacsha384
== NULL
)
1354 return (DST_R_NULLKEY
);
1356 hkey
= key
->keydata
.hmacsha384
;
1358 priv
.elements
[cnt
].tag
= TAG_HMACSHA384_KEY
;
1359 priv
.elements
[cnt
].length
= bytes
;
1360 priv
.elements
[cnt
++].data
= hkey
->key
;
1362 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1363 buf
[1] = key
->key_bits
& 0xffU
;
1364 priv
.elements
[cnt
].tag
= TAG_HMACSHA384_BITS
;
1365 priv
.elements
[cnt
].data
= buf
;
1366 priv
.elements
[cnt
++].length
= 2;
1368 priv
.nelements
= cnt
;
1369 return (dst__privstruct_writefile(key
, &priv
, directory
));
1373 hmacsha384_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1375 isc_result_t result
, tresult
;
1377 isc_mem_t
*mctx
= key
->mctx
;
1381 /* read private key file */
1382 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA384
, lexer
, mctx
,
1384 if (result
!= ISC_R_SUCCESS
)
1388 for (i
= 0; i
< priv
.nelements
; i
++) {
1389 switch (priv
.elements
[i
].tag
) {
1390 case TAG_HMACSHA384_KEY
:
1391 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1392 priv
.elements
[i
].length
);
1393 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1394 tresult
= hmacsha384_fromdns(key
, &b
);
1395 if (tresult
!= ISC_R_SUCCESS
)
1398 case TAG_HMACSHA384_BITS
:
1399 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1400 if (tresult
!= ISC_R_SUCCESS
)
1404 result
= DST_R_INVALIDPRIVATEKEY
;
1408 dst__privstruct_free(&priv
, mctx
);
1409 memset(&priv
, 0, sizeof(priv
));
1413 static dst_func_t hmacsha384_functions
= {
1414 hmacsha384_createctx
,
1415 hmacsha384_destroyctx
,
1419 NULL
, /* computesecret */
1421 NULL
, /* paramcompare */
1422 hmacsha384_generate
,
1423 hmacsha384_isprivate
,
1430 NULL
, /* fromlabel */
1434 dst__hmacsha384_init(dst_func_t
**funcp
) {
1435 REQUIRE(funcp
!= NULL
);
1437 *funcp
= &hmacsha384_functions
;
1438 return (ISC_R_SUCCESS
);
1441 static isc_result_t
hmacsha512_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
1443 struct dst_hmacsha512_key
{
1444 unsigned char key
[ISC_SHA512_DIGESTLENGTH
];
1448 hmacsha512_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
1449 isc_hmacsha512_t
*hmacsha512ctx
;
1450 dst_hmacsha512_key_t
*hkey
= key
->keydata
.hmacsha512
;
1452 hmacsha512ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha512_t
));
1453 if (hmacsha512ctx
== NULL
)
1454 return (ISC_R_NOMEMORY
);
1455 isc_hmacsha512_init(hmacsha512ctx
, hkey
->key
, ISC_SHA512_DIGESTLENGTH
);
1456 dctx
->ctxdata
.hmacsha512ctx
= hmacsha512ctx
;
1457 return (ISC_R_SUCCESS
);
1461 hmacsha512_destroyctx(dst_context_t
*dctx
) {
1462 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1464 if (hmacsha512ctx
!= NULL
) {
1465 isc_hmacsha512_invalidate(hmacsha512ctx
);
1466 isc_mem_put(dctx
->mctx
, hmacsha512ctx
, sizeof(isc_hmacsha512_t
));
1467 dctx
->ctxdata
.hmacsha512ctx
= NULL
;
1472 hmacsha512_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
1473 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1475 isc_hmacsha512_update(hmacsha512ctx
, data
->base
, data
->length
);
1476 return (ISC_R_SUCCESS
);
1480 hmacsha512_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
1481 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1482 unsigned char *digest
;
1484 if (isc_buffer_availablelength(sig
) < ISC_SHA512_DIGESTLENGTH
)
1485 return (ISC_R_NOSPACE
);
1486 digest
= isc_buffer_used(sig
);
1487 isc_hmacsha512_sign(hmacsha512ctx
, digest
, ISC_SHA512_DIGESTLENGTH
);
1488 isc_buffer_add(sig
, ISC_SHA512_DIGESTLENGTH
);
1490 return (ISC_R_SUCCESS
);
1494 hmacsha512_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
1495 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1497 if (sig
->length
> ISC_SHA512_DIGESTLENGTH
|| sig
->length
== 0)
1498 return (DST_R_VERIFYFAILURE
);
1500 if (isc_hmacsha512_verify(hmacsha512ctx
, sig
->base
, sig
->length
))
1501 return (ISC_R_SUCCESS
);
1503 return (DST_R_VERIFYFAILURE
);
1506 static isc_boolean_t
1507 hmacsha512_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
1508 dst_hmacsha512_key_t
*hkey1
, *hkey2
;
1510 hkey1
= key1
->keydata
.hmacsha512
;
1511 hkey2
= key2
->keydata
.hmacsha512
;
1513 if (hkey1
== NULL
&& hkey2
== NULL
)
1515 else if (hkey1
== NULL
|| hkey2
== NULL
)
1518 if (memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA512_DIGESTLENGTH
) == 0)
1525 hmacsha512_generate(dst_key_t
*key
, int pseudorandom_ok
,
1526 void (*callback
)(int))
1531 unsigned char data
[HMAC_LEN
];
1535 bytes
= (key
->key_size
+ 7) / 8;
1536 if (bytes
> HMAC_LEN
) {
1538 key
->key_size
= HMAC_LEN
* 8;
1541 memset(data
, 0, HMAC_LEN
);
1542 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
1544 if (ret
!= ISC_R_SUCCESS
)
1547 isc_buffer_init(&b
, data
, bytes
);
1548 isc_buffer_add(&b
, bytes
);
1549 ret
= hmacsha512_fromdns(key
, &b
);
1550 memset(data
, 0, ISC_SHA512_DIGESTLENGTH
);
1555 static isc_boolean_t
1556 hmacsha512_isprivate(const dst_key_t
*key
) {
1562 hmacsha512_destroy(dst_key_t
*key
) {
1563 dst_hmacsha512_key_t
*hkey
= key
->keydata
.hmacsha512
;
1564 memset(hkey
, 0, sizeof(dst_hmacsha512_key_t
));
1565 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha512_key_t
));
1566 key
->keydata
.hmacsha512
= NULL
;
1570 hmacsha512_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1571 dst_hmacsha512_key_t
*hkey
;
1574 REQUIRE(key
->keydata
.hmacsha512
!= NULL
);
1576 hkey
= key
->keydata
.hmacsha512
;
1578 bytes
= (key
->key_size
+ 7) / 8;
1579 if (isc_buffer_availablelength(data
) < bytes
)
1580 return (ISC_R_NOSPACE
);
1581 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1583 return (ISC_R_SUCCESS
);
1587 hmacsha512_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1588 dst_hmacsha512_key_t
*hkey
;
1591 isc_sha512_t sha512ctx
;
1593 isc_buffer_remainingregion(data
, &r
);
1595 return (ISC_R_SUCCESS
);
1597 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha512_key_t
));
1599 return (ISC_R_NOMEMORY
);
1601 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1603 if (r
.length
> ISC_SHA512_DIGESTLENGTH
) {
1604 isc_sha512_init(&sha512ctx
);
1605 isc_sha512_update(&sha512ctx
, r
.base
, r
.length
);
1606 isc_sha512_final(hkey
->key
, &sha512ctx
);
1607 keylen
= ISC_SHA512_DIGESTLENGTH
;
1610 memcpy(hkey
->key
, r
.base
, r
.length
);
1614 key
->key_size
= keylen
* 8;
1615 key
->keydata
.hmacsha512
= hkey
;
1617 return (ISC_R_SUCCESS
);
1621 hmacsha512_tofile(const dst_key_t
*key
, const char *directory
) {
1623 dst_hmacsha512_key_t
*hkey
;
1625 int bytes
= (key
->key_size
+ 7) / 8;
1626 unsigned char buf
[2];
1628 if (key
->keydata
.hmacsha512
== NULL
)
1629 return (DST_R_NULLKEY
);
1631 hkey
= key
->keydata
.hmacsha512
;
1633 priv
.elements
[cnt
].tag
= TAG_HMACSHA512_KEY
;
1634 priv
.elements
[cnt
].length
= bytes
;
1635 priv
.elements
[cnt
++].data
= hkey
->key
;
1637 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1638 buf
[1] = key
->key_bits
& 0xffU
;
1639 priv
.elements
[cnt
].tag
= TAG_HMACSHA512_BITS
;
1640 priv
.elements
[cnt
].data
= buf
;
1641 priv
.elements
[cnt
++].length
= 2;
1643 priv
.nelements
= cnt
;
1644 return (dst__privstruct_writefile(key
, &priv
, directory
));
1648 hmacsha512_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1650 isc_result_t result
, tresult
;
1652 isc_mem_t
*mctx
= key
->mctx
;
1656 /* read private key file */
1657 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA512
, lexer
, mctx
,
1659 if (result
!= ISC_R_SUCCESS
)
1663 for (i
= 0; i
< priv
.nelements
; i
++) {
1664 switch (priv
.elements
[i
].tag
) {
1665 case TAG_HMACSHA512_KEY
:
1666 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1667 priv
.elements
[i
].length
);
1668 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1669 tresult
= hmacsha512_fromdns(key
, &b
);
1670 if (tresult
!= ISC_R_SUCCESS
)
1673 case TAG_HMACSHA512_BITS
:
1674 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1675 if (tresult
!= ISC_R_SUCCESS
)
1679 result
= DST_R_INVALIDPRIVATEKEY
;
1683 dst__privstruct_free(&priv
, mctx
);
1684 memset(&priv
, 0, sizeof(priv
));
1688 static dst_func_t hmacsha512_functions
= {
1689 hmacsha512_createctx
,
1690 hmacsha512_destroyctx
,
1694 NULL
, /* computesecret */
1696 NULL
, /* paramcompare */
1697 hmacsha512_generate
,
1698 hmacsha512_isprivate
,
1705 NULL
, /* fromlabel */
1709 dst__hmacsha512_init(dst_func_t
**funcp
) {
1710 REQUIRE(funcp
!= NULL
);
1712 *funcp
= &hmacsha512_functions
;
1713 return (ISC_R_SUCCESS
);