]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/bind9/lib/isc/hmacsha.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / bind9 / lib / isc / hmacsha.c
1 /*
2  * Copyright (C) 2005-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id: hmacsha.c,v 1.10 2009-02-06 23:47:42 tbox Exp $ */
18
19 /*
20  * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
21  * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
22  * draft-ietf-dnsext-tsig-sha-01.txt.
23  */
24
25 #include "config.h"
26
27 #include <isc/assertions.h>
28 #include <isc/hmacsha.h>
29 #include <isc/platform.h>
30 #include <isc/sha1.h>
31 #include <isc/sha2.h>
32 #include <isc/string.h>
33 #include <isc/types.h>
34 #include <isc/util.h>
35
36 #ifdef ISC_PLATFORM_OPENSSLHASH
37
38 void
39 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
40                   unsigned int len)
41 {
42         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
43 }
44
45 void
46 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
47         HMAC_CTX_cleanup(ctx);
48 }
49
50 void
51 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
52                    unsigned int len)
53 {
54         HMAC_Update(ctx, buf, (int) len);
55 }
56
57 void
58 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
59         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
60
61         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
62
63         HMAC_Final(ctx, newdigest, NULL);
64         HMAC_CTX_cleanup(ctx);
65         memcpy(digest, newdigest, len);
66         memset(newdigest, 0, sizeof(newdigest));
67 }
68
69 void
70 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
71                     unsigned int len)
72 {
73         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
74 }
75
76 void
77 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
78         HMAC_CTX_cleanup(ctx);
79 }
80
81 void
82 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
83                    unsigned int len)
84 {
85         HMAC_Update(ctx, buf, (int) len);
86 }
87
88 void
89 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
90         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
91
92         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
93
94         HMAC_Final(ctx, newdigest, NULL);
95         HMAC_CTX_cleanup(ctx);
96         memcpy(digest, newdigest, len);
97         memset(newdigest, 0, sizeof(newdigest));
98 }
99
100 void
101 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
102                     unsigned int len)
103 {
104         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
105 }
106
107 void
108 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
109         HMAC_CTX_cleanup(ctx);
110 }
111
112 void
113 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
114                    unsigned int len)
115 {
116         HMAC_Update(ctx, buf, (int) len);
117 }
118
119 void
120 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
121         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
122
123         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
124
125         HMAC_Final(ctx, newdigest, NULL);
126         HMAC_CTX_cleanup(ctx);
127         memcpy(digest, newdigest, len);
128         memset(newdigest, 0, sizeof(newdigest));
129 }
130
131 void
132 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
133                     unsigned int len)
134 {
135         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
136 }
137
138 void
139 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
140         HMAC_CTX_cleanup(ctx);
141 }
142
143 void
144 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
145                    unsigned int len)
146 {
147         HMAC_Update(ctx, buf, (int) len);
148 }
149
150 void
151 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
152         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
153
154         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
155
156         HMAC_Final(ctx, newdigest, NULL);
157         HMAC_CTX_cleanup(ctx);
158         memcpy(digest, newdigest, len);
159         memset(newdigest, 0, sizeof(newdigest));
160 }
161
162 void
163 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
164                     unsigned int len)
165 {
166         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
167 }
168
169 void
170 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
171         HMAC_CTX_cleanup(ctx);
172 }
173
174 void
175 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
176                    unsigned int len)
177 {
178         HMAC_Update(ctx, buf, (int) len);
179 }
180
181 void
182 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
183         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
184
185         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
186
187         HMAC_Final(ctx, newdigest, NULL);
188         HMAC_CTX_cleanup(ctx);
189         memcpy(digest, newdigest, len);
190         memset(newdigest, 0, sizeof(newdigest));
191 }
192
193 #else
194
195 #define IPAD 0x36
196 #define OPAD 0x5C
197
198 /*
199  * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
200  */
201 void
202 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
203                   unsigned int len)
204 {
205         unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
206         unsigned int i;
207
208         memset(ctx->key, 0, sizeof(ctx->key));
209         if (len > sizeof(ctx->key)) {
210                 isc_sha1_t sha1ctx;
211                 isc_sha1_init(&sha1ctx);
212                 isc_sha1_update(&sha1ctx, key, len);
213                 isc_sha1_final(&sha1ctx, ctx->key);
214         } else
215                 memcpy(ctx->key, key, len);
216
217         isc_sha1_init(&ctx->sha1ctx);
218         memset(ipad, IPAD, sizeof(ipad));
219         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
220                 ipad[i] ^= ctx->key[i];
221         isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
222 }
223
224 void
225 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
226         isc_sha1_invalidate(&ctx->sha1ctx);
227         memset(ctx->key, 0, sizeof(ctx->key));
228         memset(ctx, 0, sizeof(ctx));
229 }
230
231 /*
232  * Update context to reflect the concatenation of another buffer full
233  * of bytes.
234  */
235 void
236 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
237                    unsigned int len)
238 {
239         isc_sha1_update(&ctx->sha1ctx, buf, len);
240 }
241
242 /*
243  * Compute signature - finalize SHA1 operation and reapply SHA1.
244  */
245 void
246 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
247         unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
248         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
249         unsigned int i;
250
251         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
252         isc_sha1_final(&ctx->sha1ctx, newdigest);
253
254         memset(opad, OPAD, sizeof(opad));
255         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
256                 opad[i] ^= ctx->key[i];
257
258         isc_sha1_init(&ctx->sha1ctx);
259         isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
260         isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
261         isc_sha1_final(&ctx->sha1ctx, newdigest);
262         isc_hmacsha1_invalidate(ctx);
263         memcpy(digest, newdigest, len);
264         memset(newdigest, 0, sizeof(newdigest));
265 }
266
267 /*
268  * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
269  */
270 void
271 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
272                     unsigned int len)
273 {
274         unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
275         unsigned int i;
276
277         memset(ctx->key, 0, sizeof(ctx->key));
278         if (len > sizeof(ctx->key)) {
279                 isc_sha224_t sha224ctx;
280                 isc_sha224_init(&sha224ctx);
281                 isc_sha224_update(&sha224ctx, key, len);
282                 isc_sha224_final(ctx->key, &sha224ctx);
283         } else
284                 memcpy(ctx->key, key, len);
285
286         isc_sha224_init(&ctx->sha224ctx);
287         memset(ipad, IPAD, sizeof(ipad));
288         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
289                 ipad[i] ^= ctx->key[i];
290         isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
291 }
292
293 void
294 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
295         memset(ctx->key, 0, sizeof(ctx->key));
296         memset(ctx, 0, sizeof(ctx));
297 }
298
299 /*
300  * Update context to reflect the concatenation of another buffer full
301  * of bytes.
302  */
303 void
304 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
305                    unsigned int len)
306 {
307         isc_sha224_update(&ctx->sha224ctx, buf, len);
308 }
309
310 /*
311  * Compute signature - finalize SHA224 operation and reapply SHA224.
312  */
313 void
314 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
315         unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
316         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
317         unsigned int i;
318
319         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
320         isc_sha224_final(newdigest, &ctx->sha224ctx);
321
322         memset(opad, OPAD, sizeof(opad));
323         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
324                 opad[i] ^= ctx->key[i];
325
326         isc_sha224_init(&ctx->sha224ctx);
327         isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
328         isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
329         isc_sha224_final(newdigest, &ctx->sha224ctx);
330         memcpy(digest, newdigest, len);
331         memset(newdigest, 0, sizeof(newdigest));
332 }
333
334 /*
335  * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
336  */
337 void
338 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
339                     unsigned int len)
340 {
341         unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
342         unsigned int i;
343
344         memset(ctx->key, 0, sizeof(ctx->key));
345         if (len > sizeof(ctx->key)) {
346                 isc_sha256_t sha256ctx;
347                 isc_sha256_init(&sha256ctx);
348                 isc_sha256_update(&sha256ctx, key, len);
349                 isc_sha256_final(ctx->key, &sha256ctx);
350         } else
351                 memcpy(ctx->key, key, len);
352
353         isc_sha256_init(&ctx->sha256ctx);
354         memset(ipad, IPAD, sizeof(ipad));
355         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
356                 ipad[i] ^= ctx->key[i];
357         isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
358 }
359
360 void
361 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
362         memset(ctx->key, 0, sizeof(ctx->key));
363         memset(ctx, 0, sizeof(ctx));
364 }
365
366 /*
367  * Update context to reflect the concatenation of another buffer full
368  * of bytes.
369  */
370 void
371 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
372                    unsigned int len)
373 {
374         isc_sha256_update(&ctx->sha256ctx, buf, len);
375 }
376
377 /*
378  * Compute signature - finalize SHA256 operation and reapply SHA256.
379  */
380 void
381 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
382         unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
383         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
384         unsigned int i;
385
386         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
387         isc_sha256_final(newdigest, &ctx->sha256ctx);
388
389         memset(opad, OPAD, sizeof(opad));
390         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
391                 opad[i] ^= ctx->key[i];
392
393         isc_sha256_init(&ctx->sha256ctx);
394         isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
395         isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
396         isc_sha256_final(newdigest, &ctx->sha256ctx);
397         memcpy(digest, newdigest, len);
398         memset(newdigest, 0, sizeof(newdigest));
399 }
400
401 /*
402  * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
403  */
404 void
405 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
406                     unsigned int len)
407 {
408         unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
409         unsigned int i;
410
411         memset(ctx->key, 0, sizeof(ctx->key));
412         if (len > sizeof(ctx->key)) {
413                 isc_sha384_t sha384ctx;
414                 isc_sha384_init(&sha384ctx);
415                 isc_sha384_update(&sha384ctx, key, len);
416                 isc_sha384_final(ctx->key, &sha384ctx);
417         } else
418                 memcpy(ctx->key, key, len);
419
420         isc_sha384_init(&ctx->sha384ctx);
421         memset(ipad, IPAD, sizeof(ipad));
422         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
423                 ipad[i] ^= ctx->key[i];
424         isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
425 }
426
427 void
428 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
429         memset(ctx->key, 0, sizeof(ctx->key));
430         memset(ctx, 0, sizeof(ctx));
431 }
432
433 /*
434  * Update context to reflect the concatenation of another buffer full
435  * of bytes.
436  */
437 void
438 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
439                    unsigned int len)
440 {
441         isc_sha384_update(&ctx->sha384ctx, buf, len);
442 }
443
444 /*
445  * Compute signature - finalize SHA384 operation and reapply SHA384.
446  */
447 void
448 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
449         unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
450         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
451         unsigned int i;
452
453         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
454         isc_sha384_final(newdigest, &ctx->sha384ctx);
455
456         memset(opad, OPAD, sizeof(opad));
457         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
458                 opad[i] ^= ctx->key[i];
459
460         isc_sha384_init(&ctx->sha384ctx);
461         isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
462         isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
463         isc_sha384_final(newdigest, &ctx->sha384ctx);
464         memcpy(digest, newdigest, len);
465         memset(newdigest, 0, sizeof(newdigest));
466 }
467
468 /*
469  * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
470  */
471 void
472 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
473                     unsigned int len)
474 {
475         unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
476         unsigned int i;
477
478         memset(ctx->key, 0, sizeof(ctx->key));
479         if (len > sizeof(ctx->key)) {
480                 isc_sha512_t sha512ctx;
481                 isc_sha512_init(&sha512ctx);
482                 isc_sha512_update(&sha512ctx, key, len);
483                 isc_sha512_final(ctx->key, &sha512ctx);
484         } else
485                 memcpy(ctx->key, key, len);
486
487         isc_sha512_init(&ctx->sha512ctx);
488         memset(ipad, IPAD, sizeof(ipad));
489         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
490                 ipad[i] ^= ctx->key[i];
491         isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
492 }
493
494 void
495 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
496         memset(ctx->key, 0, sizeof(ctx->key));
497         memset(ctx, 0, sizeof(ctx));
498 }
499
500 /*
501  * Update context to reflect the concatenation of another buffer full
502  * of bytes.
503  */
504 void
505 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
506                    unsigned int len)
507 {
508         isc_sha512_update(&ctx->sha512ctx, buf, len);
509 }
510
511 /*
512  * Compute signature - finalize SHA512 operation and reapply SHA512.
513  */
514 void
515 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
516         unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
517         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
518         unsigned int i;
519
520         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
521         isc_sha512_final(newdigest, &ctx->sha512ctx);
522
523         memset(opad, OPAD, sizeof(opad));
524         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
525                 opad[i] ^= ctx->key[i];
526
527         isc_sha512_init(&ctx->sha512ctx);
528         isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
529         isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
530         isc_sha512_final(newdigest, &ctx->sha512ctx);
531         memcpy(digest, newdigest, len);
532         memset(newdigest, 0, sizeof(newdigest));
533 }
534 #endif /* !ISC_PLATFORM_OPENSSLHASH */
535
536 /*
537  * Verify signature - finalize SHA1 operation and reapply SHA1, then
538  * compare to the supplied digest.
539  */
540 isc_boolean_t
541 isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
542         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
543
544         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
545         isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
546         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
547 }
548
549 /*
550  * Verify signature - finalize SHA224 operation and reapply SHA224, then
551  * compare to the supplied digest.
552  */
553 isc_boolean_t
554 isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
555         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
556
557         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
558         isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
559         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
560 }
561
562 /*
563  * Verify signature - finalize SHA256 operation and reapply SHA256, then
564  * compare to the supplied digest.
565  */
566 isc_boolean_t
567 isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
568         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
569
570         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
571         isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
572         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
573 }
574
575 /*
576  * Verify signature - finalize SHA384 operation and reapply SHA384, then
577  * compare to the supplied digest.
578  */
579 isc_boolean_t
580 isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
581         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
582
583         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
584         isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
585         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
586 }
587
588 /*
589  * Verify signature - finalize SHA512 operation and reapply SHA512, then
590  * compare to the supplied digest.
591  */
592 isc_boolean_t
593 isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
594         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
595
596         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
597         isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
598         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
599 }