1 /* $NetBSD: hmac_link.c,v 1.8 2015/09/03 07:33:34 christos Exp $ */
4 * Portions Copyright (C) 2004-2014 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.19 2011/01/11 23:47:13 tbox Exp
41 #include <isc/buffer.h>
42 #include <isc/hmacmd5.h>
43 #include <isc/hmacsha.h>
48 #include <isc/string.h>
51 #include <dst/result.h>
53 #include "dst_internal.h"
54 #include "dst_parse.h"
56 static isc_result_t
hmacmd5_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
58 struct dst_hmacmd5_key
{
59 unsigned char key
[ISC_MD5_BLOCK_LENGTH
];
63 getkeybits(dst_key_t
*key
, struct dst_private_element
*element
) {
65 if (element
->length
!= 2)
66 return (DST_R_INVALIDPRIVATEKEY
);
68 key
->key_bits
= (element
->data
[0] << 8) + element
->data
[1];
70 return (ISC_R_SUCCESS
);
74 hmacmd5_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
75 isc_hmacmd5_t
*hmacmd5ctx
;
76 dst_hmacmd5_key_t
*hkey
= key
->keydata
.hmacmd5
;
78 hmacmd5ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacmd5_t
));
79 if (hmacmd5ctx
== NULL
)
80 return (ISC_R_NOMEMORY
);
81 isc_hmacmd5_init(hmacmd5ctx
, hkey
->key
, ISC_MD5_BLOCK_LENGTH
);
82 dctx
->ctxdata
.hmacmd5ctx
= hmacmd5ctx
;
83 return (ISC_R_SUCCESS
);
87 hmacmd5_destroyctx(dst_context_t
*dctx
) {
88 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
90 if (hmacmd5ctx
!= NULL
) {
91 isc_hmacmd5_invalidate(hmacmd5ctx
);
92 isc_mem_put(dctx
->mctx
, hmacmd5ctx
, sizeof(isc_hmacmd5_t
));
93 dctx
->ctxdata
.hmacmd5ctx
= NULL
;
98 hmacmd5_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
99 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
101 isc_hmacmd5_update(hmacmd5ctx
, data
->base
, data
->length
);
102 return (ISC_R_SUCCESS
);
106 hmacmd5_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
107 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
108 unsigned char *digest
;
110 if (isc_buffer_availablelength(sig
) < ISC_MD5_DIGESTLENGTH
)
111 return (ISC_R_NOSPACE
);
112 digest
= isc_buffer_used(sig
);
113 isc_hmacmd5_sign(hmacmd5ctx
, digest
);
114 isc_buffer_add(sig
, ISC_MD5_DIGESTLENGTH
);
116 return (ISC_R_SUCCESS
);
120 hmacmd5_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
121 isc_hmacmd5_t
*hmacmd5ctx
= dctx
->ctxdata
.hmacmd5ctx
;
123 if (sig
->length
> ISC_MD5_DIGESTLENGTH
)
124 return (DST_R_VERIFYFAILURE
);
126 if (isc_hmacmd5_verify2(hmacmd5ctx
, sig
->base
, sig
->length
))
127 return (ISC_R_SUCCESS
);
129 return (DST_R_VERIFYFAILURE
);
133 hmacmd5_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
134 dst_hmacmd5_key_t
*hkey1
, *hkey2
;
136 hkey1
= key1
->keydata
.hmacmd5
;
137 hkey2
= key2
->keydata
.hmacmd5
;
139 if (hkey1
== NULL
&& hkey2
== NULL
)
141 else if (hkey1
== NULL
|| hkey2
== NULL
)
144 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_MD5_BLOCK_LENGTH
))
151 hmacmd5_generate(dst_key_t
*key
, int pseudorandom_ok
, void (*callback
)(int)) {
155 unsigned char data
[ISC_MD5_BLOCK_LENGTH
];
159 bytes
= (key
->key_size
+ 7) / 8;
160 if (bytes
> ISC_MD5_BLOCK_LENGTH
) {
161 bytes
= ISC_MD5_BLOCK_LENGTH
;
162 key
->key_size
= ISC_MD5_BLOCK_LENGTH
* 8;
165 memset(data
, 0, ISC_MD5_BLOCK_LENGTH
);
166 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
168 if (ret
!= ISC_R_SUCCESS
)
171 isc_buffer_init(&b
, data
, bytes
);
172 isc_buffer_add(&b
, bytes
);
173 ret
= hmacmd5_fromdns(key
, &b
);
174 memset(data
, 0, ISC_MD5_BLOCK_LENGTH
);
180 hmacmd5_isprivate(const dst_key_t
*key
) {
186 hmacmd5_destroy(dst_key_t
*key
) {
187 dst_hmacmd5_key_t
*hkey
= key
->keydata
.hmacmd5
;
189 memset(hkey
, 0, sizeof(dst_hmacmd5_key_t
));
190 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacmd5_key_t
));
191 key
->keydata
.hmacmd5
= NULL
;
195 hmacmd5_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
196 dst_hmacmd5_key_t
*hkey
;
199 REQUIRE(key
->keydata
.hmacmd5
!= NULL
);
201 hkey
= key
->keydata
.hmacmd5
;
203 bytes
= (key
->key_size
+ 7) / 8;
204 if (isc_buffer_availablelength(data
) < bytes
)
205 return (ISC_R_NOSPACE
);
206 isc_buffer_putmem(data
, hkey
->key
, bytes
);
208 return (ISC_R_SUCCESS
);
212 hmacmd5_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
213 dst_hmacmd5_key_t
*hkey
;
218 isc_buffer_remainingregion(data
, &r
);
220 return (ISC_R_SUCCESS
);
222 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacmd5_key_t
));
224 return (ISC_R_NOMEMORY
);
226 memset(hkey
->key
, 0, sizeof(hkey
->key
));
228 if (r
.length
> ISC_MD5_BLOCK_LENGTH
) {
229 isc_md5_init(&md5ctx
);
230 isc_md5_update(&md5ctx
, r
.base
, r
.length
);
231 isc_md5_final(&md5ctx
, hkey
->key
);
232 keylen
= ISC_MD5_DIGESTLENGTH
;
234 memmove(hkey
->key
, r
.base
, r
.length
);
238 key
->key_size
= keylen
* 8;
239 key
->keydata
.hmacmd5
= hkey
;
241 isc_buffer_forward(data
, r
.length
);
243 return (ISC_R_SUCCESS
);
247 hmacmd5_tofile(const dst_key_t
*key
, const char *directory
) {
249 dst_hmacmd5_key_t
*hkey
;
251 int bytes
= (key
->key_size
+ 7) / 8;
252 unsigned char buf
[2];
254 if (key
->keydata
.hmacmd5
== NULL
)
255 return (DST_R_NULLKEY
);
258 return (DST_R_EXTERNALKEY
);
260 hkey
= key
->keydata
.hmacmd5
;
262 priv
.elements
[cnt
].tag
= TAG_HMACMD5_KEY
;
263 priv
.elements
[cnt
].length
= bytes
;
264 priv
.elements
[cnt
++].data
= hkey
->key
;
266 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
267 buf
[1] = key
->key_bits
& 0xffU
;
268 priv
.elements
[cnt
].tag
= TAG_HMACMD5_BITS
;
269 priv
.elements
[cnt
].data
= buf
;
270 priv
.elements
[cnt
++].length
= 2;
272 priv
.nelements
= cnt
;
273 return (dst__privstruct_writefile(key
, &priv
, directory
));
277 hmacmd5_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
279 isc_result_t result
, tresult
;
281 isc_mem_t
*mctx
= key
->mctx
;
285 /* read private key file */
286 result
= dst__privstruct_parse(key
, DST_ALG_HMACMD5
, lexer
, mctx
,
288 if (result
!= ISC_R_SUCCESS
)
292 result
= DST_R_EXTERNALKEY
;
295 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
296 switch (priv
.elements
[i
].tag
) {
297 case TAG_HMACMD5_KEY
:
298 isc_buffer_init(&b
, priv
.elements
[i
].data
,
299 priv
.elements
[i
].length
);
300 isc_buffer_add(&b
, priv
.elements
[i
].length
);
301 tresult
= hmacmd5_fromdns(key
, &b
);
302 if (tresult
!= ISC_R_SUCCESS
)
305 case TAG_HMACMD5_BITS
:
306 tresult
= getkeybits(key
, &priv
.elements
[i
]);
307 if (tresult
!= ISC_R_SUCCESS
)
311 result
= DST_R_INVALIDPRIVATEKEY
;
315 dst__privstruct_free(&priv
, mctx
);
316 memset(&priv
, 0, sizeof(priv
));
320 static dst_func_t hmacmd5_functions
= {
322 NULL
, /*%< createctx2 */
327 NULL
, /*%< verify2 */
328 NULL
, /*%< computesecret */
330 NULL
, /*%< paramcompare */
338 NULL
, /*%< cleanup */
339 NULL
, /*%< fromlabel */
341 NULL
, /*%< restore */
345 dst__hmacmd5_init(dst_func_t
**funcp
) {
346 REQUIRE(funcp
!= NULL
);
348 *funcp
= &hmacmd5_functions
;
349 return (ISC_R_SUCCESS
);
352 static isc_result_t
hmacsha1_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
354 struct dst_hmacsha1_key
{
355 unsigned char key
[ISC_SHA1_BLOCK_LENGTH
];
359 hmacsha1_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
360 isc_hmacsha1_t
*hmacsha1ctx
;
361 dst_hmacsha1_key_t
*hkey
= key
->keydata
.hmacsha1
;
363 hmacsha1ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha1_t
));
364 if (hmacsha1ctx
== NULL
)
365 return (ISC_R_NOMEMORY
);
366 isc_hmacsha1_init(hmacsha1ctx
, hkey
->key
, ISC_SHA1_BLOCK_LENGTH
);
367 dctx
->ctxdata
.hmacsha1ctx
= hmacsha1ctx
;
368 return (ISC_R_SUCCESS
);
372 hmacsha1_destroyctx(dst_context_t
*dctx
) {
373 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
375 if (hmacsha1ctx
!= NULL
) {
376 isc_hmacsha1_invalidate(hmacsha1ctx
);
377 isc_mem_put(dctx
->mctx
, hmacsha1ctx
, sizeof(isc_hmacsha1_t
));
378 dctx
->ctxdata
.hmacsha1ctx
= NULL
;
383 hmacsha1_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
384 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
386 isc_hmacsha1_update(hmacsha1ctx
, data
->base
, data
->length
);
387 return (ISC_R_SUCCESS
);
391 hmacsha1_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
392 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
393 unsigned char *digest
;
395 if (isc_buffer_availablelength(sig
) < ISC_SHA1_DIGESTLENGTH
)
396 return (ISC_R_NOSPACE
);
397 digest
= isc_buffer_used(sig
);
398 isc_hmacsha1_sign(hmacsha1ctx
, digest
, ISC_SHA1_DIGESTLENGTH
);
399 isc_buffer_add(sig
, ISC_SHA1_DIGESTLENGTH
);
401 return (ISC_R_SUCCESS
);
405 hmacsha1_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
406 isc_hmacsha1_t
*hmacsha1ctx
= dctx
->ctxdata
.hmacsha1ctx
;
408 if (sig
->length
> ISC_SHA1_DIGESTLENGTH
|| sig
->length
== 0)
409 return (DST_R_VERIFYFAILURE
);
411 if (isc_hmacsha1_verify(hmacsha1ctx
, sig
->base
, sig
->length
))
412 return (ISC_R_SUCCESS
);
414 return (DST_R_VERIFYFAILURE
);
418 hmacsha1_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
419 dst_hmacsha1_key_t
*hkey1
, *hkey2
;
421 hkey1
= key1
->keydata
.hmacsha1
;
422 hkey2
= key2
->keydata
.hmacsha1
;
424 if (hkey1
== NULL
&& hkey2
== NULL
)
426 else if (hkey1
== NULL
|| hkey2
== NULL
)
429 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA1_BLOCK_LENGTH
))
436 hmacsha1_generate(dst_key_t
*key
, int pseudorandom_ok
, void (*callback
)(int)) {
440 unsigned char data
[ISC_SHA1_BLOCK_LENGTH
];
444 bytes
= (key
->key_size
+ 7) / 8;
445 if (bytes
> ISC_SHA1_BLOCK_LENGTH
) {
446 bytes
= ISC_SHA1_BLOCK_LENGTH
;
447 key
->key_size
= ISC_SHA1_BLOCK_LENGTH
* 8;
450 memset(data
, 0, ISC_SHA1_BLOCK_LENGTH
);
451 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
453 if (ret
!= ISC_R_SUCCESS
)
456 isc_buffer_init(&b
, data
, bytes
);
457 isc_buffer_add(&b
, bytes
);
458 ret
= hmacsha1_fromdns(key
, &b
);
459 memset(data
, 0, ISC_SHA1_BLOCK_LENGTH
);
465 hmacsha1_isprivate(const dst_key_t
*key
) {
471 hmacsha1_destroy(dst_key_t
*key
) {
472 dst_hmacsha1_key_t
*hkey
= key
->keydata
.hmacsha1
;
474 memset(hkey
, 0, sizeof(dst_hmacsha1_key_t
));
475 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha1_key_t
));
476 key
->keydata
.hmacsha1
= NULL
;
480 hmacsha1_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
481 dst_hmacsha1_key_t
*hkey
;
484 REQUIRE(key
->keydata
.hmacsha1
!= NULL
);
486 hkey
= key
->keydata
.hmacsha1
;
488 bytes
= (key
->key_size
+ 7) / 8;
489 if (isc_buffer_availablelength(data
) < bytes
)
490 return (ISC_R_NOSPACE
);
491 isc_buffer_putmem(data
, hkey
->key
, bytes
);
493 return (ISC_R_SUCCESS
);
497 hmacsha1_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
498 dst_hmacsha1_key_t
*hkey
;
503 isc_buffer_remainingregion(data
, &r
);
505 return (ISC_R_SUCCESS
);
507 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha1_key_t
));
509 return (ISC_R_NOMEMORY
);
511 memset(hkey
->key
, 0, sizeof(hkey
->key
));
513 if (r
.length
> ISC_SHA1_BLOCK_LENGTH
) {
514 isc_sha1_init(&sha1ctx
);
515 isc_sha1_update(&sha1ctx
, r
.base
, r
.length
);
516 isc_sha1_final(&sha1ctx
, hkey
->key
);
517 keylen
= ISC_SHA1_DIGESTLENGTH
;
519 memmove(hkey
->key
, r
.base
, r
.length
);
523 key
->key_size
= keylen
* 8;
524 key
->keydata
.hmacsha1
= hkey
;
526 isc_buffer_forward(data
, r
.length
);
528 return (ISC_R_SUCCESS
);
532 hmacsha1_tofile(const dst_key_t
*key
, const char *directory
) {
534 dst_hmacsha1_key_t
*hkey
;
536 int bytes
= (key
->key_size
+ 7) / 8;
537 unsigned char buf
[2];
539 if (key
->keydata
.hmacsha1
== NULL
)
540 return (DST_R_NULLKEY
);
543 return (DST_R_EXTERNALKEY
);
545 hkey
= key
->keydata
.hmacsha1
;
547 priv
.elements
[cnt
].tag
= TAG_HMACSHA1_KEY
;
548 priv
.elements
[cnt
].length
= bytes
;
549 priv
.elements
[cnt
++].data
= hkey
->key
;
551 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
552 buf
[1] = key
->key_bits
& 0xffU
;
553 priv
.elements
[cnt
].tag
= TAG_HMACSHA1_BITS
;
554 priv
.elements
[cnt
].data
= buf
;
555 priv
.elements
[cnt
++].length
= 2;
557 priv
.nelements
= cnt
;
558 return (dst__privstruct_writefile(key
, &priv
, directory
));
562 hmacsha1_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
564 isc_result_t result
, tresult
;
566 isc_mem_t
*mctx
= key
->mctx
;
570 /* read private key file */
571 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA1
, lexer
, mctx
,
573 if (result
!= ISC_R_SUCCESS
)
577 result
= DST_R_EXTERNALKEY
;
580 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
581 switch (priv
.elements
[i
].tag
) {
582 case TAG_HMACSHA1_KEY
:
583 isc_buffer_init(&b
, priv
.elements
[i
].data
,
584 priv
.elements
[i
].length
);
585 isc_buffer_add(&b
, priv
.elements
[i
].length
);
586 tresult
= hmacsha1_fromdns(key
, &b
);
587 if (tresult
!= ISC_R_SUCCESS
)
590 case TAG_HMACSHA1_BITS
:
591 tresult
= getkeybits(key
, &priv
.elements
[i
]);
592 if (tresult
!= ISC_R_SUCCESS
)
596 result
= DST_R_INVALIDPRIVATEKEY
;
600 dst__privstruct_free(&priv
, mctx
);
601 memset(&priv
, 0, sizeof(priv
));
605 static dst_func_t hmacsha1_functions
= {
607 NULL
, /*%< createctx2 */
613 NULL
, /* computesecret */
615 NULL
, /* paramcompare */
624 NULL
, /* fromlabel */
630 dst__hmacsha1_init(dst_func_t
**funcp
) {
631 REQUIRE(funcp
!= NULL
);
633 *funcp
= &hmacsha1_functions
;
634 return (ISC_R_SUCCESS
);
637 static isc_result_t
hmacsha224_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
639 struct dst_hmacsha224_key
{
640 unsigned char key
[ISC_SHA224_BLOCK_LENGTH
];
644 hmacsha224_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
645 isc_hmacsha224_t
*hmacsha224ctx
;
646 dst_hmacsha224_key_t
*hkey
= key
->keydata
.hmacsha224
;
648 hmacsha224ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha224_t
));
649 if (hmacsha224ctx
== NULL
)
650 return (ISC_R_NOMEMORY
);
651 isc_hmacsha224_init(hmacsha224ctx
, hkey
->key
, ISC_SHA224_BLOCK_LENGTH
);
652 dctx
->ctxdata
.hmacsha224ctx
= hmacsha224ctx
;
653 return (ISC_R_SUCCESS
);
657 hmacsha224_destroyctx(dst_context_t
*dctx
) {
658 isc_hmacsha224_t
*hmacsha224ctx
= dctx
->ctxdata
.hmacsha224ctx
;
660 if (hmacsha224ctx
!= NULL
) {
661 isc_hmacsha224_invalidate(hmacsha224ctx
);
662 isc_mem_put(dctx
->mctx
, hmacsha224ctx
, sizeof(isc_hmacsha224_t
));
663 dctx
->ctxdata
.hmacsha224ctx
= NULL
;
668 hmacsha224_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
669 isc_hmacsha224_t
*hmacsha224ctx
= dctx
->ctxdata
.hmacsha224ctx
;
671 isc_hmacsha224_update(hmacsha224ctx
, data
->base
, data
->length
);
672 return (ISC_R_SUCCESS
);
676 hmacsha224_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
677 isc_hmacsha224_t
*hmacsha224ctx
= dctx
->ctxdata
.hmacsha224ctx
;
678 unsigned char *digest
;
680 if (isc_buffer_availablelength(sig
) < ISC_SHA224_DIGESTLENGTH
)
681 return (ISC_R_NOSPACE
);
682 digest
= isc_buffer_used(sig
);
683 isc_hmacsha224_sign(hmacsha224ctx
, digest
, ISC_SHA224_DIGESTLENGTH
);
684 isc_buffer_add(sig
, ISC_SHA224_DIGESTLENGTH
);
686 return (ISC_R_SUCCESS
);
690 hmacsha224_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
691 isc_hmacsha224_t
*hmacsha224ctx
= dctx
->ctxdata
.hmacsha224ctx
;
693 if (sig
->length
> ISC_SHA224_DIGESTLENGTH
|| sig
->length
== 0)
694 return (DST_R_VERIFYFAILURE
);
696 if (isc_hmacsha224_verify(hmacsha224ctx
, sig
->base
, sig
->length
))
697 return (ISC_R_SUCCESS
);
699 return (DST_R_VERIFYFAILURE
);
703 hmacsha224_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
704 dst_hmacsha224_key_t
*hkey1
, *hkey2
;
706 hkey1
= key1
->keydata
.hmacsha224
;
707 hkey2
= key2
->keydata
.hmacsha224
;
709 if (hkey1
== NULL
&& hkey2
== NULL
)
711 else if (hkey1
== NULL
|| hkey2
== NULL
)
714 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA224_BLOCK_LENGTH
))
721 hmacsha224_generate(dst_key_t
*key
, int pseudorandom_ok
,
722 void (*callback
)(int))
727 unsigned char data
[ISC_SHA224_BLOCK_LENGTH
];
731 bytes
= (key
->key_size
+ 7) / 8;
732 if (bytes
> ISC_SHA224_BLOCK_LENGTH
) {
733 bytes
= ISC_SHA224_BLOCK_LENGTH
;
734 key
->key_size
= ISC_SHA224_BLOCK_LENGTH
* 8;
737 memset(data
, 0, ISC_SHA224_BLOCK_LENGTH
);
738 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
740 if (ret
!= ISC_R_SUCCESS
)
743 isc_buffer_init(&b
, data
, bytes
);
744 isc_buffer_add(&b
, bytes
);
745 ret
= hmacsha224_fromdns(key
, &b
);
746 memset(data
, 0, ISC_SHA224_BLOCK_LENGTH
);
752 hmacsha224_isprivate(const dst_key_t
*key
) {
758 hmacsha224_destroy(dst_key_t
*key
) {
759 dst_hmacsha224_key_t
*hkey
= key
->keydata
.hmacsha224
;
761 memset(hkey
, 0, sizeof(dst_hmacsha224_key_t
));
762 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha224_key_t
));
763 key
->keydata
.hmacsha224
= NULL
;
767 hmacsha224_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
768 dst_hmacsha224_key_t
*hkey
;
771 REQUIRE(key
->keydata
.hmacsha224
!= NULL
);
773 hkey
= key
->keydata
.hmacsha224
;
775 bytes
= (key
->key_size
+ 7) / 8;
776 if (isc_buffer_availablelength(data
) < bytes
)
777 return (ISC_R_NOSPACE
);
778 isc_buffer_putmem(data
, hkey
->key
, bytes
);
780 return (ISC_R_SUCCESS
);
784 hmacsha224_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
785 dst_hmacsha224_key_t
*hkey
;
788 isc_sha224_t sha224ctx
;
790 isc_buffer_remainingregion(data
, &r
);
792 return (ISC_R_SUCCESS
);
794 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha224_key_t
));
796 return (ISC_R_NOMEMORY
);
798 memset(hkey
->key
, 0, sizeof(hkey
->key
));
800 if (r
.length
> ISC_SHA224_BLOCK_LENGTH
) {
801 isc_sha224_init(&sha224ctx
);
802 isc_sha224_update(&sha224ctx
, r
.base
, r
.length
);
803 isc_sha224_final(hkey
->key
, &sha224ctx
);
804 keylen
= ISC_SHA224_DIGESTLENGTH
;
806 memmove(hkey
->key
, r
.base
, r
.length
);
810 key
->key_size
= keylen
* 8;
811 key
->keydata
.hmacsha224
= hkey
;
813 isc_buffer_forward(data
, r
.length
);
815 return (ISC_R_SUCCESS
);
819 hmacsha224_tofile(const dst_key_t
*key
, const char *directory
) {
821 dst_hmacsha224_key_t
*hkey
;
823 int bytes
= (key
->key_size
+ 7) / 8;
824 unsigned char buf
[2];
826 if (key
->keydata
.hmacsha224
== NULL
)
827 return (DST_R_NULLKEY
);
830 return (DST_R_EXTERNALKEY
);
832 hkey
= key
->keydata
.hmacsha224
;
834 priv
.elements
[cnt
].tag
= TAG_HMACSHA224_KEY
;
835 priv
.elements
[cnt
].length
= bytes
;
836 priv
.elements
[cnt
++].data
= hkey
->key
;
838 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
839 buf
[1] = key
->key_bits
& 0xffU
;
840 priv
.elements
[cnt
].tag
= TAG_HMACSHA224_BITS
;
841 priv
.elements
[cnt
].data
= buf
;
842 priv
.elements
[cnt
++].length
= 2;
844 priv
.nelements
= cnt
;
845 return (dst__privstruct_writefile(key
, &priv
, directory
));
849 hmacsha224_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
851 isc_result_t result
, tresult
;
853 isc_mem_t
*mctx
= key
->mctx
;
857 /* read private key file */
858 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA224
, lexer
, mctx
,
860 if (result
!= ISC_R_SUCCESS
)
864 result
= DST_R_EXTERNALKEY
;
867 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
868 switch (priv
.elements
[i
].tag
) {
869 case TAG_HMACSHA224_KEY
:
870 isc_buffer_init(&b
, priv
.elements
[i
].data
,
871 priv
.elements
[i
].length
);
872 isc_buffer_add(&b
, priv
.elements
[i
].length
);
873 tresult
= hmacsha224_fromdns(key
, &b
);
874 if (tresult
!= ISC_R_SUCCESS
)
877 case TAG_HMACSHA224_BITS
:
878 tresult
= getkeybits(key
, &priv
.elements
[i
]);
879 if (tresult
!= ISC_R_SUCCESS
)
883 result
= DST_R_INVALIDPRIVATEKEY
;
887 dst__privstruct_free(&priv
, mctx
);
888 memset(&priv
, 0, sizeof(priv
));
892 static dst_func_t hmacsha224_functions
= {
893 hmacsha224_createctx
,
894 NULL
, /*%< createctx2 */
895 hmacsha224_destroyctx
,
900 NULL
, /* computesecret */
902 NULL
, /* paramcompare */
904 hmacsha224_isprivate
,
911 NULL
, /* fromlabel */
917 dst__hmacsha224_init(dst_func_t
**funcp
) {
918 REQUIRE(funcp
!= NULL
);
920 *funcp
= &hmacsha224_functions
;
921 return (ISC_R_SUCCESS
);
924 static isc_result_t
hmacsha256_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
926 struct dst_hmacsha256_key
{
927 unsigned char key
[ISC_SHA256_BLOCK_LENGTH
];
931 hmacsha256_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
932 isc_hmacsha256_t
*hmacsha256ctx
;
933 dst_hmacsha256_key_t
*hkey
= key
->keydata
.hmacsha256
;
935 hmacsha256ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha256_t
));
936 if (hmacsha256ctx
== NULL
)
937 return (ISC_R_NOMEMORY
);
938 isc_hmacsha256_init(hmacsha256ctx
, hkey
->key
, ISC_SHA256_BLOCK_LENGTH
);
939 dctx
->ctxdata
.hmacsha256ctx
= hmacsha256ctx
;
940 return (ISC_R_SUCCESS
);
944 hmacsha256_destroyctx(dst_context_t
*dctx
) {
945 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
947 if (hmacsha256ctx
!= NULL
) {
948 isc_hmacsha256_invalidate(hmacsha256ctx
);
949 isc_mem_put(dctx
->mctx
, hmacsha256ctx
, sizeof(isc_hmacsha256_t
));
950 dctx
->ctxdata
.hmacsha256ctx
= NULL
;
955 hmacsha256_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
956 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
958 isc_hmacsha256_update(hmacsha256ctx
, data
->base
, data
->length
);
959 return (ISC_R_SUCCESS
);
963 hmacsha256_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
964 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
965 unsigned char *digest
;
967 if (isc_buffer_availablelength(sig
) < ISC_SHA256_DIGESTLENGTH
)
968 return (ISC_R_NOSPACE
);
969 digest
= isc_buffer_used(sig
);
970 isc_hmacsha256_sign(hmacsha256ctx
, digest
, ISC_SHA256_DIGESTLENGTH
);
971 isc_buffer_add(sig
, ISC_SHA256_DIGESTLENGTH
);
973 return (ISC_R_SUCCESS
);
977 hmacsha256_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
978 isc_hmacsha256_t
*hmacsha256ctx
= dctx
->ctxdata
.hmacsha256ctx
;
980 if (sig
->length
> ISC_SHA256_DIGESTLENGTH
|| sig
->length
== 0)
981 return (DST_R_VERIFYFAILURE
);
983 if (isc_hmacsha256_verify(hmacsha256ctx
, sig
->base
, sig
->length
))
984 return (ISC_R_SUCCESS
);
986 return (DST_R_VERIFYFAILURE
);
990 hmacsha256_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
991 dst_hmacsha256_key_t
*hkey1
, *hkey2
;
993 hkey1
= key1
->keydata
.hmacsha256
;
994 hkey2
= key2
->keydata
.hmacsha256
;
996 if (hkey1
== NULL
&& hkey2
== NULL
)
998 else if (hkey1
== NULL
|| hkey2
== NULL
)
1001 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA256_BLOCK_LENGTH
))
1008 hmacsha256_generate(dst_key_t
*key
, int pseudorandom_ok
,
1009 void (*callback
)(int))
1014 unsigned char data
[ISC_SHA256_BLOCK_LENGTH
];
1018 bytes
= (key
->key_size
+ 7) / 8;
1019 if (bytes
> ISC_SHA256_BLOCK_LENGTH
) {
1020 bytes
= ISC_SHA256_BLOCK_LENGTH
;
1021 key
->key_size
= ISC_SHA256_BLOCK_LENGTH
* 8;
1024 memset(data
, 0, ISC_SHA256_BLOCK_LENGTH
);
1025 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
1027 if (ret
!= ISC_R_SUCCESS
)
1030 isc_buffer_init(&b
, data
, bytes
);
1031 isc_buffer_add(&b
, bytes
);
1032 ret
= hmacsha256_fromdns(key
, &b
);
1033 memset(data
, 0, ISC_SHA256_BLOCK_LENGTH
);
1038 static isc_boolean_t
1039 hmacsha256_isprivate(const dst_key_t
*key
) {
1045 hmacsha256_destroy(dst_key_t
*key
) {
1046 dst_hmacsha256_key_t
*hkey
= key
->keydata
.hmacsha256
;
1048 memset(hkey
, 0, sizeof(dst_hmacsha256_key_t
));
1049 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha256_key_t
));
1050 key
->keydata
.hmacsha256
= NULL
;
1054 hmacsha256_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1055 dst_hmacsha256_key_t
*hkey
;
1058 REQUIRE(key
->keydata
.hmacsha256
!= NULL
);
1060 hkey
= key
->keydata
.hmacsha256
;
1062 bytes
= (key
->key_size
+ 7) / 8;
1063 if (isc_buffer_availablelength(data
) < bytes
)
1064 return (ISC_R_NOSPACE
);
1065 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1067 return (ISC_R_SUCCESS
);
1071 hmacsha256_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1072 dst_hmacsha256_key_t
*hkey
;
1075 isc_sha256_t sha256ctx
;
1077 isc_buffer_remainingregion(data
, &r
);
1079 return (ISC_R_SUCCESS
);
1081 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha256_key_t
));
1083 return (ISC_R_NOMEMORY
);
1085 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1087 if (r
.length
> ISC_SHA256_BLOCK_LENGTH
) {
1088 isc_sha256_init(&sha256ctx
);
1089 isc_sha256_update(&sha256ctx
, r
.base
, r
.length
);
1090 isc_sha256_final(hkey
->key
, &sha256ctx
);
1091 keylen
= ISC_SHA256_DIGESTLENGTH
;
1093 memmove(hkey
->key
, r
.base
, r
.length
);
1097 key
->key_size
= keylen
* 8;
1098 key
->keydata
.hmacsha256
= hkey
;
1100 isc_buffer_forward(data
, r
.length
);
1102 return (ISC_R_SUCCESS
);
1106 hmacsha256_tofile(const dst_key_t
*key
, const char *directory
) {
1108 dst_hmacsha256_key_t
*hkey
;
1110 int bytes
= (key
->key_size
+ 7) / 8;
1111 unsigned char buf
[2];
1113 if (key
->keydata
.hmacsha256
== NULL
)
1114 return (DST_R_NULLKEY
);
1117 return (DST_R_EXTERNALKEY
);
1119 hkey
= key
->keydata
.hmacsha256
;
1121 priv
.elements
[cnt
].tag
= TAG_HMACSHA256_KEY
;
1122 priv
.elements
[cnt
].length
= bytes
;
1123 priv
.elements
[cnt
++].data
= hkey
->key
;
1125 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1126 buf
[1] = key
->key_bits
& 0xffU
;
1127 priv
.elements
[cnt
].tag
= TAG_HMACSHA256_BITS
;
1128 priv
.elements
[cnt
].data
= buf
;
1129 priv
.elements
[cnt
++].length
= 2;
1131 priv
.nelements
= cnt
;
1132 return (dst__privstruct_writefile(key
, &priv
, directory
));
1136 hmacsha256_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1138 isc_result_t result
, tresult
;
1140 isc_mem_t
*mctx
= key
->mctx
;
1144 /* read private key file */
1145 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA256
, lexer
, mctx
,
1147 if (result
!= ISC_R_SUCCESS
)
1151 result
= DST_R_EXTERNALKEY
;
1154 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
1155 switch (priv
.elements
[i
].tag
) {
1156 case TAG_HMACSHA256_KEY
:
1157 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1158 priv
.elements
[i
].length
);
1159 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1160 tresult
= hmacsha256_fromdns(key
, &b
);
1161 if (tresult
!= ISC_R_SUCCESS
)
1164 case TAG_HMACSHA256_BITS
:
1165 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1166 if (tresult
!= ISC_R_SUCCESS
)
1170 result
= DST_R_INVALIDPRIVATEKEY
;
1174 dst__privstruct_free(&priv
, mctx
);
1175 memset(&priv
, 0, sizeof(priv
));
1179 static dst_func_t hmacsha256_functions
= {
1180 hmacsha256_createctx
,
1181 NULL
, /*%< createctx2 */
1182 hmacsha256_destroyctx
,
1187 NULL
, /* computesecret */
1189 NULL
, /* paramcompare */
1190 hmacsha256_generate
,
1191 hmacsha256_isprivate
,
1198 NULL
, /* fromlabel */
1204 dst__hmacsha256_init(dst_func_t
**funcp
) {
1205 REQUIRE(funcp
!= NULL
);
1207 *funcp
= &hmacsha256_functions
;
1208 return (ISC_R_SUCCESS
);
1211 static isc_result_t
hmacsha384_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
1213 struct dst_hmacsha384_key
{
1214 unsigned char key
[ISC_SHA384_BLOCK_LENGTH
];
1218 hmacsha384_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
1219 isc_hmacsha384_t
*hmacsha384ctx
;
1220 dst_hmacsha384_key_t
*hkey
= key
->keydata
.hmacsha384
;
1222 hmacsha384ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha384_t
));
1223 if (hmacsha384ctx
== NULL
)
1224 return (ISC_R_NOMEMORY
);
1225 isc_hmacsha384_init(hmacsha384ctx
, hkey
->key
, ISC_SHA384_BLOCK_LENGTH
);
1226 dctx
->ctxdata
.hmacsha384ctx
= hmacsha384ctx
;
1227 return (ISC_R_SUCCESS
);
1231 hmacsha384_destroyctx(dst_context_t
*dctx
) {
1232 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1234 if (hmacsha384ctx
!= NULL
) {
1235 isc_hmacsha384_invalidate(hmacsha384ctx
);
1236 isc_mem_put(dctx
->mctx
, hmacsha384ctx
, sizeof(isc_hmacsha384_t
));
1237 dctx
->ctxdata
.hmacsha384ctx
= NULL
;
1242 hmacsha384_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
1243 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1245 isc_hmacsha384_update(hmacsha384ctx
, data
->base
, data
->length
);
1246 return (ISC_R_SUCCESS
);
1250 hmacsha384_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
1251 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1252 unsigned char *digest
;
1254 if (isc_buffer_availablelength(sig
) < ISC_SHA384_DIGESTLENGTH
)
1255 return (ISC_R_NOSPACE
);
1256 digest
= isc_buffer_used(sig
);
1257 isc_hmacsha384_sign(hmacsha384ctx
, digest
, ISC_SHA384_DIGESTLENGTH
);
1258 isc_buffer_add(sig
, ISC_SHA384_DIGESTLENGTH
);
1260 return (ISC_R_SUCCESS
);
1264 hmacsha384_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
1265 isc_hmacsha384_t
*hmacsha384ctx
= dctx
->ctxdata
.hmacsha384ctx
;
1267 if (sig
->length
> ISC_SHA384_DIGESTLENGTH
|| sig
->length
== 0)
1268 return (DST_R_VERIFYFAILURE
);
1270 if (isc_hmacsha384_verify(hmacsha384ctx
, sig
->base
, sig
->length
))
1271 return (ISC_R_SUCCESS
);
1273 return (DST_R_VERIFYFAILURE
);
1276 static isc_boolean_t
1277 hmacsha384_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
1278 dst_hmacsha384_key_t
*hkey1
, *hkey2
;
1280 hkey1
= key1
->keydata
.hmacsha384
;
1281 hkey2
= key2
->keydata
.hmacsha384
;
1283 if (hkey1
== NULL
&& hkey2
== NULL
)
1285 else if (hkey1
== NULL
|| hkey2
== NULL
)
1288 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA384_BLOCK_LENGTH
))
1295 hmacsha384_generate(dst_key_t
*key
, int pseudorandom_ok
,
1296 void (*callback
)(int))
1301 unsigned char data
[ISC_SHA384_BLOCK_LENGTH
];
1305 bytes
= (key
->key_size
+ 7) / 8;
1306 if (bytes
> ISC_SHA384_BLOCK_LENGTH
) {
1307 bytes
= ISC_SHA384_BLOCK_LENGTH
;
1308 key
->key_size
= ISC_SHA384_BLOCK_LENGTH
* 8;
1311 memset(data
, 0, ISC_SHA384_BLOCK_LENGTH
);
1312 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
1314 if (ret
!= ISC_R_SUCCESS
)
1317 isc_buffer_init(&b
, data
, bytes
);
1318 isc_buffer_add(&b
, bytes
);
1319 ret
= hmacsha384_fromdns(key
, &b
);
1320 memset(data
, 0, ISC_SHA384_BLOCK_LENGTH
);
1325 static isc_boolean_t
1326 hmacsha384_isprivate(const dst_key_t
*key
) {
1332 hmacsha384_destroy(dst_key_t
*key
) {
1333 dst_hmacsha384_key_t
*hkey
= key
->keydata
.hmacsha384
;
1335 memset(hkey
, 0, sizeof(dst_hmacsha384_key_t
));
1336 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha384_key_t
));
1337 key
->keydata
.hmacsha384
= NULL
;
1341 hmacsha384_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1342 dst_hmacsha384_key_t
*hkey
;
1345 REQUIRE(key
->keydata
.hmacsha384
!= NULL
);
1347 hkey
= key
->keydata
.hmacsha384
;
1349 bytes
= (key
->key_size
+ 7) / 8;
1350 if (isc_buffer_availablelength(data
) < bytes
)
1351 return (ISC_R_NOSPACE
);
1352 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1354 return (ISC_R_SUCCESS
);
1358 hmacsha384_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1359 dst_hmacsha384_key_t
*hkey
;
1362 isc_sha384_t sha384ctx
;
1364 isc_buffer_remainingregion(data
, &r
);
1366 return (ISC_R_SUCCESS
);
1368 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha384_key_t
));
1370 return (ISC_R_NOMEMORY
);
1372 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1374 if (r
.length
> ISC_SHA384_BLOCK_LENGTH
) {
1375 isc_sha384_init(&sha384ctx
);
1376 isc_sha384_update(&sha384ctx
, r
.base
, r
.length
);
1377 isc_sha384_final(hkey
->key
, &sha384ctx
);
1378 keylen
= ISC_SHA384_DIGESTLENGTH
;
1380 memmove(hkey
->key
, r
.base
, r
.length
);
1384 key
->key_size
= keylen
* 8;
1385 key
->keydata
.hmacsha384
= hkey
;
1387 isc_buffer_forward(data
, r
.length
);
1389 return (ISC_R_SUCCESS
);
1393 hmacsha384_tofile(const dst_key_t
*key
, const char *directory
) {
1395 dst_hmacsha384_key_t
*hkey
;
1397 int bytes
= (key
->key_size
+ 7) / 8;
1398 unsigned char buf
[2];
1400 if (key
->keydata
.hmacsha384
== NULL
)
1401 return (DST_R_NULLKEY
);
1404 return (DST_R_EXTERNALKEY
);
1406 hkey
= key
->keydata
.hmacsha384
;
1408 priv
.elements
[cnt
].tag
= TAG_HMACSHA384_KEY
;
1409 priv
.elements
[cnt
].length
= bytes
;
1410 priv
.elements
[cnt
++].data
= hkey
->key
;
1412 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1413 buf
[1] = key
->key_bits
& 0xffU
;
1414 priv
.elements
[cnt
].tag
= TAG_HMACSHA384_BITS
;
1415 priv
.elements
[cnt
].data
= buf
;
1416 priv
.elements
[cnt
++].length
= 2;
1418 priv
.nelements
= cnt
;
1419 return (dst__privstruct_writefile(key
, &priv
, directory
));
1423 hmacsha384_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1425 isc_result_t result
, tresult
;
1427 isc_mem_t
*mctx
= key
->mctx
;
1431 /* read private key file */
1432 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA384
, lexer
, mctx
,
1434 if (result
!= ISC_R_SUCCESS
)
1438 result
= DST_R_EXTERNALKEY
;
1441 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
1442 switch (priv
.elements
[i
].tag
) {
1443 case TAG_HMACSHA384_KEY
:
1444 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1445 priv
.elements
[i
].length
);
1446 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1447 tresult
= hmacsha384_fromdns(key
, &b
);
1448 if (tresult
!= ISC_R_SUCCESS
)
1451 case TAG_HMACSHA384_BITS
:
1452 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1453 if (tresult
!= ISC_R_SUCCESS
)
1457 result
= DST_R_INVALIDPRIVATEKEY
;
1461 dst__privstruct_free(&priv
, mctx
);
1462 memset(&priv
, 0, sizeof(priv
));
1466 static dst_func_t hmacsha384_functions
= {
1467 hmacsha384_createctx
,
1468 NULL
, /*%< createctx2 */
1469 hmacsha384_destroyctx
,
1474 NULL
, /* computesecret */
1476 NULL
, /* paramcompare */
1477 hmacsha384_generate
,
1478 hmacsha384_isprivate
,
1485 NULL
, /* fromlabel */
1491 dst__hmacsha384_init(dst_func_t
**funcp
) {
1492 REQUIRE(funcp
!= NULL
);
1494 *funcp
= &hmacsha384_functions
;
1495 return (ISC_R_SUCCESS
);
1498 static isc_result_t
hmacsha512_fromdns(dst_key_t
*key
, isc_buffer_t
*data
);
1500 struct dst_hmacsha512_key
{
1501 unsigned char key
[ISC_SHA512_BLOCK_LENGTH
];
1505 hmacsha512_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
1506 isc_hmacsha512_t
*hmacsha512ctx
;
1507 dst_hmacsha512_key_t
*hkey
= key
->keydata
.hmacsha512
;
1509 hmacsha512ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_hmacsha512_t
));
1510 if (hmacsha512ctx
== NULL
)
1511 return (ISC_R_NOMEMORY
);
1512 isc_hmacsha512_init(hmacsha512ctx
, hkey
->key
, ISC_SHA512_BLOCK_LENGTH
);
1513 dctx
->ctxdata
.hmacsha512ctx
= hmacsha512ctx
;
1514 return (ISC_R_SUCCESS
);
1518 hmacsha512_destroyctx(dst_context_t
*dctx
) {
1519 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1521 if (hmacsha512ctx
!= NULL
) {
1522 isc_hmacsha512_invalidate(hmacsha512ctx
);
1523 isc_mem_put(dctx
->mctx
, hmacsha512ctx
, sizeof(isc_hmacsha512_t
));
1524 dctx
->ctxdata
.hmacsha512ctx
= NULL
;
1529 hmacsha512_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
1530 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1532 isc_hmacsha512_update(hmacsha512ctx
, data
->base
, data
->length
);
1533 return (ISC_R_SUCCESS
);
1537 hmacsha512_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
1538 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1539 unsigned char *digest
;
1541 if (isc_buffer_availablelength(sig
) < ISC_SHA512_DIGESTLENGTH
)
1542 return (ISC_R_NOSPACE
);
1543 digest
= isc_buffer_used(sig
);
1544 isc_hmacsha512_sign(hmacsha512ctx
, digest
, ISC_SHA512_DIGESTLENGTH
);
1545 isc_buffer_add(sig
, ISC_SHA512_DIGESTLENGTH
);
1547 return (ISC_R_SUCCESS
);
1551 hmacsha512_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
1552 isc_hmacsha512_t
*hmacsha512ctx
= dctx
->ctxdata
.hmacsha512ctx
;
1554 if (sig
->length
> ISC_SHA512_DIGESTLENGTH
|| sig
->length
== 0)
1555 return (DST_R_VERIFYFAILURE
);
1557 if (isc_hmacsha512_verify(hmacsha512ctx
, sig
->base
, sig
->length
))
1558 return (ISC_R_SUCCESS
);
1560 return (DST_R_VERIFYFAILURE
);
1563 static isc_boolean_t
1564 hmacsha512_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
1565 dst_hmacsha512_key_t
*hkey1
, *hkey2
;
1567 hkey1
= key1
->keydata
.hmacsha512
;
1568 hkey2
= key2
->keydata
.hmacsha512
;
1570 if (hkey1
== NULL
&& hkey2
== NULL
)
1572 else if (hkey1
== NULL
|| hkey2
== NULL
)
1575 if (isc_safe_memcmp(hkey1
->key
, hkey2
->key
, ISC_SHA512_BLOCK_LENGTH
))
1582 hmacsha512_generate(dst_key_t
*key
, int pseudorandom_ok
,
1583 void (*callback
)(int))
1588 unsigned char data
[ISC_SHA512_BLOCK_LENGTH
];
1592 bytes
= (key
->key_size
+ 7) / 8;
1593 if (bytes
> ISC_SHA512_BLOCK_LENGTH
) {
1594 bytes
= ISC_SHA512_BLOCK_LENGTH
;
1595 key
->key_size
= ISC_SHA512_BLOCK_LENGTH
* 8;
1598 memset(data
, 0, ISC_SHA512_BLOCK_LENGTH
);
1599 ret
= dst__entropy_getdata(data
, bytes
, ISC_TF(pseudorandom_ok
!= 0));
1601 if (ret
!= ISC_R_SUCCESS
)
1604 isc_buffer_init(&b
, data
, bytes
);
1605 isc_buffer_add(&b
, bytes
);
1606 ret
= hmacsha512_fromdns(key
, &b
);
1607 memset(data
, 0, ISC_SHA512_BLOCK_LENGTH
);
1612 static isc_boolean_t
1613 hmacsha512_isprivate(const dst_key_t
*key
) {
1619 hmacsha512_destroy(dst_key_t
*key
) {
1620 dst_hmacsha512_key_t
*hkey
= key
->keydata
.hmacsha512
;
1622 memset(hkey
, 0, sizeof(dst_hmacsha512_key_t
));
1623 isc_mem_put(key
->mctx
, hkey
, sizeof(dst_hmacsha512_key_t
));
1624 key
->keydata
.hmacsha512
= NULL
;
1628 hmacsha512_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
1629 dst_hmacsha512_key_t
*hkey
;
1632 REQUIRE(key
->keydata
.hmacsha512
!= NULL
);
1634 hkey
= key
->keydata
.hmacsha512
;
1636 bytes
= (key
->key_size
+ 7) / 8;
1637 if (isc_buffer_availablelength(data
) < bytes
)
1638 return (ISC_R_NOSPACE
);
1639 isc_buffer_putmem(data
, hkey
->key
, bytes
);
1641 return (ISC_R_SUCCESS
);
1645 hmacsha512_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
1646 dst_hmacsha512_key_t
*hkey
;
1649 isc_sha512_t sha512ctx
;
1651 isc_buffer_remainingregion(data
, &r
);
1653 return (ISC_R_SUCCESS
);
1655 hkey
= isc_mem_get(key
->mctx
, sizeof(dst_hmacsha512_key_t
));
1657 return (ISC_R_NOMEMORY
);
1659 memset(hkey
->key
, 0, sizeof(hkey
->key
));
1661 if (r
.length
> ISC_SHA512_BLOCK_LENGTH
) {
1662 isc_sha512_init(&sha512ctx
);
1663 isc_sha512_update(&sha512ctx
, r
.base
, r
.length
);
1664 isc_sha512_final(hkey
->key
, &sha512ctx
);
1665 keylen
= ISC_SHA512_DIGESTLENGTH
;
1667 memmove(hkey
->key
, r
.base
, r
.length
);
1671 key
->key_size
= keylen
* 8;
1672 key
->keydata
.hmacsha512
= hkey
;
1674 isc_buffer_forward(data
, r
.length
);
1676 return (ISC_R_SUCCESS
);
1680 hmacsha512_tofile(const dst_key_t
*key
, const char *directory
) {
1682 dst_hmacsha512_key_t
*hkey
;
1684 int bytes
= (key
->key_size
+ 7) / 8;
1685 unsigned char buf
[2];
1687 if (key
->keydata
.hmacsha512
== NULL
)
1688 return (DST_R_NULLKEY
);
1691 return (DST_R_EXTERNALKEY
);
1693 hkey
= key
->keydata
.hmacsha512
;
1695 priv
.elements
[cnt
].tag
= TAG_HMACSHA512_KEY
;
1696 priv
.elements
[cnt
].length
= bytes
;
1697 priv
.elements
[cnt
++].data
= hkey
->key
;
1699 buf
[0] = (key
->key_bits
>> 8) & 0xffU
;
1700 buf
[1] = key
->key_bits
& 0xffU
;
1701 priv
.elements
[cnt
].tag
= TAG_HMACSHA512_BITS
;
1702 priv
.elements
[cnt
].data
= buf
;
1703 priv
.elements
[cnt
++].length
= 2;
1705 priv
.nelements
= cnt
;
1706 return (dst__privstruct_writefile(key
, &priv
, directory
));
1710 hmacsha512_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1712 isc_result_t result
, tresult
;
1714 isc_mem_t
*mctx
= key
->mctx
;
1718 /* read private key file */
1719 result
= dst__privstruct_parse(key
, DST_ALG_HMACSHA512
, lexer
, mctx
,
1721 if (result
!= ISC_R_SUCCESS
)
1725 result
= DST_R_EXTERNALKEY
;
1728 for (i
= 0; i
< priv
.nelements
&& result
== ISC_R_SUCCESS
; i
++) {
1729 switch (priv
.elements
[i
].tag
) {
1730 case TAG_HMACSHA512_KEY
:
1731 isc_buffer_init(&b
, priv
.elements
[i
].data
,
1732 priv
.elements
[i
].length
);
1733 isc_buffer_add(&b
, priv
.elements
[i
].length
);
1734 tresult
= hmacsha512_fromdns(key
, &b
);
1735 if (tresult
!= ISC_R_SUCCESS
)
1738 case TAG_HMACSHA512_BITS
:
1739 tresult
= getkeybits(key
, &priv
.elements
[i
]);
1740 if (tresult
!= ISC_R_SUCCESS
)
1744 result
= DST_R_INVALIDPRIVATEKEY
;
1748 dst__privstruct_free(&priv
, mctx
);
1749 memset(&priv
, 0, sizeof(priv
));
1753 static dst_func_t hmacsha512_functions
= {
1754 hmacsha512_createctx
,
1755 NULL
, /*%< createctx2 */
1756 hmacsha512_destroyctx
,
1761 NULL
, /* computesecret */
1763 NULL
, /* paramcompare */
1764 hmacsha512_generate
,
1765 hmacsha512_isprivate
,
1772 NULL
, /* fromlabel */
1778 dst__hmacsha512_init(dst_func_t
**funcp
) {
1779 REQUIRE(funcp
!= NULL
);
1781 *funcp
= &hmacsha512_functions
;
1782 return (ISC_R_SUCCESS
);