xref: /minix3/external/bsd/bind/dist/lib/isc/hmacsha.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: hmacsha.c,v 1.9 2015/07/08 17:28:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2005-2007, 2009, 2011-2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek /*
22*00b67f09SDavid van Moolenbroek  * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
23*00b67f09SDavid van Moolenbroek  * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
24*00b67f09SDavid van Moolenbroek  * draft-ietf-dnsext-tsig-sha-01.txt.
25*00b67f09SDavid van Moolenbroek  */
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include "config.h"
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
30*00b67f09SDavid van Moolenbroek #include <isc/hmacsha.h>
31*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
32*00b67f09SDavid van Moolenbroek #include <isc/safe.h>
33*00b67f09SDavid van Moolenbroek #include <isc/sha1.h>
34*00b67f09SDavid van Moolenbroek #include <isc/sha2.h>
35*00b67f09SDavid van Moolenbroek #include <isc/string.h>
36*00b67f09SDavid van Moolenbroek #include <isc/types.h>
37*00b67f09SDavid van Moolenbroek #include <isc/util.h>
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #if PKCS11CRYPTO
40*00b67f09SDavid van Moolenbroek #include <pk11/internal.h>
41*00b67f09SDavid van Moolenbroek #include <pk11/pk11.h>
42*00b67f09SDavid van Moolenbroek #endif
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
45*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_init(isc_hmacsha1_t * ctx,const unsigned char * key,unsigned int len)46*00b67f09SDavid van Moolenbroek isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
47*00b67f09SDavid van Moolenbroek 		  unsigned int len)
48*00b67f09SDavid van Moolenbroek {
49*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
50*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
51*00b67f09SDavid van Moolenbroek 				(int) len, EVP_sha1()) == 1);
52*00b67f09SDavid van Moolenbroek #else
53*00b67f09SDavid van Moolenbroek 	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
54*00b67f09SDavid van Moolenbroek #endif
55*00b67f09SDavid van Moolenbroek }
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_invalidate(isc_hmacsha1_t * ctx)58*00b67f09SDavid van Moolenbroek isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
59*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
60*00b67f09SDavid van Moolenbroek }
61*00b67f09SDavid van Moolenbroek 
62*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_update(isc_hmacsha1_t * ctx,const unsigned char * buf,unsigned int len)63*00b67f09SDavid van Moolenbroek isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
64*00b67f09SDavid van Moolenbroek 		   unsigned int len)
65*00b67f09SDavid van Moolenbroek {
66*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
67*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
68*00b67f09SDavid van Moolenbroek #else
69*00b67f09SDavid van Moolenbroek 	HMAC_Update(ctx, buf, (int) len);
70*00b67f09SDavid van Moolenbroek #endif
71*00b67f09SDavid van Moolenbroek }
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_sign(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)74*00b67f09SDavid van Moolenbroek isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
75*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
80*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
81*00b67f09SDavid van Moolenbroek #else
82*00b67f09SDavid van Moolenbroek 	HMAC_Final(ctx, newdigest, NULL);
83*00b67f09SDavid van Moolenbroek #endif
84*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
85*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
86*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
87*00b67f09SDavid van Moolenbroek }
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_init(isc_hmacsha224_t * ctx,const unsigned char * key,unsigned int len)90*00b67f09SDavid van Moolenbroek isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
91*00b67f09SDavid van Moolenbroek 		    unsigned int len)
92*00b67f09SDavid van Moolenbroek {
93*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
94*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
95*00b67f09SDavid van Moolenbroek 				(int) len, EVP_sha224()) == 1);
96*00b67f09SDavid van Moolenbroek #else
97*00b67f09SDavid van Moolenbroek 	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
98*00b67f09SDavid van Moolenbroek #endif
99*00b67f09SDavid van Moolenbroek }
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_invalidate(isc_hmacsha224_t * ctx)102*00b67f09SDavid van Moolenbroek isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
103*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
104*00b67f09SDavid van Moolenbroek }
105*00b67f09SDavid van Moolenbroek 
106*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_update(isc_hmacsha224_t * ctx,const unsigned char * buf,unsigned int len)107*00b67f09SDavid van Moolenbroek isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
108*00b67f09SDavid van Moolenbroek 		   unsigned int len)
109*00b67f09SDavid van Moolenbroek {
110*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
111*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
112*00b67f09SDavid van Moolenbroek #else
113*00b67f09SDavid van Moolenbroek 	HMAC_Update(ctx, buf, (int) len);
114*00b67f09SDavid van Moolenbroek #endif
115*00b67f09SDavid van Moolenbroek }
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_sign(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)118*00b67f09SDavid van Moolenbroek isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
119*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
124*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
125*00b67f09SDavid van Moolenbroek #else
126*00b67f09SDavid van Moolenbroek 	HMAC_Final(ctx, newdigest, NULL);
127*00b67f09SDavid van Moolenbroek #endif
128*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
129*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
130*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
131*00b67f09SDavid van Moolenbroek }
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_init(isc_hmacsha256_t * ctx,const unsigned char * key,unsigned int len)134*00b67f09SDavid van Moolenbroek isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
135*00b67f09SDavid van Moolenbroek 		    unsigned int len)
136*00b67f09SDavid van Moolenbroek {
137*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
138*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
139*00b67f09SDavid van Moolenbroek 				(int) len, EVP_sha256()) == 1);
140*00b67f09SDavid van Moolenbroek #else
141*00b67f09SDavid van Moolenbroek 	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
142*00b67f09SDavid van Moolenbroek #endif
143*00b67f09SDavid van Moolenbroek }
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_invalidate(isc_hmacsha256_t * ctx)146*00b67f09SDavid van Moolenbroek isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
147*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
148*00b67f09SDavid van Moolenbroek }
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_update(isc_hmacsha256_t * ctx,const unsigned char * buf,unsigned int len)151*00b67f09SDavid van Moolenbroek isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
152*00b67f09SDavid van Moolenbroek 		   unsigned int len)
153*00b67f09SDavid van Moolenbroek {
154*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
155*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
156*00b67f09SDavid van Moolenbroek #else
157*00b67f09SDavid van Moolenbroek 	HMAC_Update(ctx, buf, (int) len);
158*00b67f09SDavid van Moolenbroek #endif
159*00b67f09SDavid van Moolenbroek }
160*00b67f09SDavid van Moolenbroek 
161*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_sign(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)162*00b67f09SDavid van Moolenbroek isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
163*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
168*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
169*00b67f09SDavid van Moolenbroek #else
170*00b67f09SDavid van Moolenbroek 	HMAC_Final(ctx, newdigest, NULL);
171*00b67f09SDavid van Moolenbroek #endif
172*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
173*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
174*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
175*00b67f09SDavid van Moolenbroek }
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_init(isc_hmacsha384_t * ctx,const unsigned char * key,unsigned int len)178*00b67f09SDavid van Moolenbroek isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
179*00b67f09SDavid van Moolenbroek 		    unsigned int len)
180*00b67f09SDavid van Moolenbroek {
181*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
182*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
183*00b67f09SDavid van Moolenbroek 				(int) len, EVP_sha384()) == 1);
184*00b67f09SDavid van Moolenbroek #else
185*00b67f09SDavid van Moolenbroek 	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
186*00b67f09SDavid van Moolenbroek #endif
187*00b67f09SDavid van Moolenbroek }
188*00b67f09SDavid van Moolenbroek 
189*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_invalidate(isc_hmacsha384_t * ctx)190*00b67f09SDavid van Moolenbroek isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
191*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
192*00b67f09SDavid van Moolenbroek }
193*00b67f09SDavid van Moolenbroek 
194*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_update(isc_hmacsha384_t * ctx,const unsigned char * buf,unsigned int len)195*00b67f09SDavid van Moolenbroek isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
196*00b67f09SDavid van Moolenbroek 		   unsigned int len)
197*00b67f09SDavid van Moolenbroek {
198*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
199*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
200*00b67f09SDavid van Moolenbroek #else
201*00b67f09SDavid van Moolenbroek 	HMAC_Update(ctx, buf, (int) len);
202*00b67f09SDavid van Moolenbroek #endif
203*00b67f09SDavid van Moolenbroek }
204*00b67f09SDavid van Moolenbroek 
205*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_sign(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)206*00b67f09SDavid van Moolenbroek isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
207*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
208*00b67f09SDavid van Moolenbroek 
209*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
210*00b67f09SDavid van Moolenbroek 
211*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
212*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
213*00b67f09SDavid van Moolenbroek #else
214*00b67f09SDavid van Moolenbroek 	HMAC_Final(ctx, newdigest, NULL);
215*00b67f09SDavid van Moolenbroek #endif
216*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
217*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
218*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
219*00b67f09SDavid van Moolenbroek }
220*00b67f09SDavid van Moolenbroek 
221*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_init(isc_hmacsha512_t * ctx,const unsigned char * key,unsigned int len)222*00b67f09SDavid van Moolenbroek isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
223*00b67f09SDavid van Moolenbroek 		    unsigned int len)
224*00b67f09SDavid van Moolenbroek {
225*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
226*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
227*00b67f09SDavid van Moolenbroek 				(int) len, EVP_sha512()) == 1);
228*00b67f09SDavid van Moolenbroek #else
229*00b67f09SDavid van Moolenbroek 	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
230*00b67f09SDavid van Moolenbroek #endif
231*00b67f09SDavid van Moolenbroek }
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_invalidate(isc_hmacsha512_t * ctx)234*00b67f09SDavid van Moolenbroek isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
235*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
236*00b67f09SDavid van Moolenbroek }
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_update(isc_hmacsha512_t * ctx,const unsigned char * buf,unsigned int len)239*00b67f09SDavid van Moolenbroek isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
240*00b67f09SDavid van Moolenbroek 		   unsigned int len)
241*00b67f09SDavid van Moolenbroek {
242*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
243*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
244*00b67f09SDavid van Moolenbroek #else
245*00b67f09SDavid van Moolenbroek 	HMAC_Update(ctx, buf, (int) len);
246*00b67f09SDavid van Moolenbroek #endif
247*00b67f09SDavid van Moolenbroek }
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_sign(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)250*00b67f09SDavid van Moolenbroek isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
251*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
254*00b67f09SDavid van Moolenbroek 
255*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
256*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
257*00b67f09SDavid van Moolenbroek #else
258*00b67f09SDavid van Moolenbroek 	HMAC_Final(ctx, newdigest, NULL);
259*00b67f09SDavid van Moolenbroek #endif
260*00b67f09SDavid van Moolenbroek 	HMAC_CTX_cleanup(ctx);
261*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
262*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
263*00b67f09SDavid van Moolenbroek }
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
266*00b67f09SDavid van Moolenbroek 
267*00b67f09SDavid van Moolenbroek static CK_BBOOL truevalue = TRUE;
268*00b67f09SDavid van Moolenbroek static CK_BBOOL falsevalue = FALSE;
269*00b67f09SDavid van Moolenbroek 
270*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_init(isc_hmacsha1_t * ctx,const unsigned char * key,unsigned int len)271*00b67f09SDavid van Moolenbroek isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
272*00b67f09SDavid van Moolenbroek 		 unsigned int len)
273*00b67f09SDavid van Moolenbroek {
274*00b67f09SDavid van Moolenbroek 	CK_RV rv;
275*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA_1_HMAC, NULL, 0 };
276*00b67f09SDavid van Moolenbroek 	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
277*00b67f09SDavid van Moolenbroek 	CK_KEY_TYPE keyType = CKK_SHA_1_HMAC;
278*00b67f09SDavid van Moolenbroek 	CK_ATTRIBUTE keyTemplate[] =
279*00b67f09SDavid van Moolenbroek 	{
280*00b67f09SDavid van Moolenbroek 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
281*00b67f09SDavid van Moolenbroek 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
282*00b67f09SDavid van Moolenbroek 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
283*00b67f09SDavid van Moolenbroek 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
284*00b67f09SDavid van Moolenbroek 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
285*00b67f09SDavid van Moolenbroek 		{ CKA_VALUE, NULL, (CK_ULONG) len }
286*00b67f09SDavid van Moolenbroek 	};
287*00b67f09SDavid van Moolenbroek 
288*00b67f09SDavid van Moolenbroek 	DE_CONST(key, keyTemplate[5].pValue);
289*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
290*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
291*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
292*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_CreateObject,
293*00b67f09SDavid van Moolenbroek 			(ctx->session, keyTemplate,
294*00b67f09SDavid van Moolenbroek 			 (CK_ULONG) 6, &ctx->object));
295*00b67f09SDavid van Moolenbroek 	INSIST(ctx->object != CK_INVALID_HANDLE);
296*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
297*00b67f09SDavid van Moolenbroek }
298*00b67f09SDavid van Moolenbroek 
299*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_invalidate(isc_hmacsha1_t * ctx)300*00b67f09SDavid van Moolenbroek isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
301*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH];
302*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA1_DIGESTLENGTH;
303*00b67f09SDavid van Moolenbroek 
304*00b67f09SDavid van Moolenbroek 	if (ctx->handle == NULL)
305*00b67f09SDavid van Moolenbroek 		return;
306*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_SignFinal(ctx->session, garbage, &len);
307*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
308*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
309*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
310*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
311*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
312*00b67f09SDavid van Moolenbroek }
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_update(isc_hmacsha1_t * ctx,const unsigned char * buf,unsigned int len)315*00b67f09SDavid van Moolenbroek isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
316*00b67f09SDavid van Moolenbroek 		   unsigned int len)
317*00b67f09SDavid van Moolenbroek {
318*00b67f09SDavid van Moolenbroek 	CK_RV rv;
319*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
320*00b67f09SDavid van Moolenbroek 
321*00b67f09SDavid van Moolenbroek 	DE_CONST(buf, pPart);
322*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignUpdate,
323*00b67f09SDavid van Moolenbroek 			(ctx->session, pPart, (CK_ULONG) len));
324*00b67f09SDavid van Moolenbroek }
325*00b67f09SDavid van Moolenbroek 
326*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_sign(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)327*00b67f09SDavid van Moolenbroek isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
328*00b67f09SDavid van Moolenbroek 	CK_RV rv;
329*00b67f09SDavid van Moolenbroek 	CK_BYTE newdigest[ISC_SHA1_DIGESTLENGTH];
330*00b67f09SDavid van Moolenbroek 	CK_ULONG psl = ISC_SHA1_DIGESTLENGTH;
331*00b67f09SDavid van Moolenbroek 
332*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
333*00b67f09SDavid van Moolenbroek 
334*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
335*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
336*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
337*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
338*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
339*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
340*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
341*00b67f09SDavid van Moolenbroek }
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_init(isc_hmacsha224_t * ctx,const unsigned char * key,unsigned int len)344*00b67f09SDavid van Moolenbroek isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
345*00b67f09SDavid van Moolenbroek 		    unsigned int len)
346*00b67f09SDavid van Moolenbroek {
347*00b67f09SDavid van Moolenbroek 	CK_RV rv;
348*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA224_HMAC, NULL, 0 };
349*00b67f09SDavid van Moolenbroek 	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
350*00b67f09SDavid van Moolenbroek 	CK_KEY_TYPE keyType = CKK_SHA224_HMAC;
351*00b67f09SDavid van Moolenbroek 	CK_ATTRIBUTE keyTemplate[] =
352*00b67f09SDavid van Moolenbroek 	{
353*00b67f09SDavid van Moolenbroek 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
354*00b67f09SDavid van Moolenbroek 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
355*00b67f09SDavid van Moolenbroek 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
356*00b67f09SDavid van Moolenbroek 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
357*00b67f09SDavid van Moolenbroek 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
358*00b67f09SDavid van Moolenbroek 		{ CKA_VALUE, NULL, (CK_ULONG) len }
359*00b67f09SDavid van Moolenbroek 	};
360*00b67f09SDavid van Moolenbroek 
361*00b67f09SDavid van Moolenbroek 	DE_CONST(key, keyTemplate[5].pValue);
362*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
363*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
364*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
365*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_CreateObject,
366*00b67f09SDavid van Moolenbroek 			(ctx->session, keyTemplate,
367*00b67f09SDavid van Moolenbroek 			 (CK_ULONG) 6, &ctx->object));
368*00b67f09SDavid van Moolenbroek 	INSIST(ctx->object != CK_INVALID_HANDLE);
369*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
370*00b67f09SDavid van Moolenbroek }
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_invalidate(isc_hmacsha224_t * ctx)373*00b67f09SDavid van Moolenbroek isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
374*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH];
375*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA224_DIGESTLENGTH;
376*00b67f09SDavid van Moolenbroek 
377*00b67f09SDavid van Moolenbroek 	if (ctx->handle == NULL)
378*00b67f09SDavid van Moolenbroek 		return;
379*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_SignFinal(ctx->session, garbage, &len);
380*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
381*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
382*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
383*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
384*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
385*00b67f09SDavid van Moolenbroek }
386*00b67f09SDavid van Moolenbroek 
387*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_update(isc_hmacsha224_t * ctx,const unsigned char * buf,unsigned int len)388*00b67f09SDavid van Moolenbroek isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
389*00b67f09SDavid van Moolenbroek 		      unsigned int len)
390*00b67f09SDavid van Moolenbroek {
391*00b67f09SDavid van Moolenbroek 	CK_RV rv;
392*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
393*00b67f09SDavid van Moolenbroek 
394*00b67f09SDavid van Moolenbroek 	DE_CONST(buf, pPart);
395*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignUpdate,
396*00b67f09SDavid van Moolenbroek 			(ctx->session, pPart, (CK_ULONG) len));
397*00b67f09SDavid van Moolenbroek }
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_sign(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)400*00b67f09SDavid van Moolenbroek isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
401*00b67f09SDavid van Moolenbroek 	CK_RV rv;
402*00b67f09SDavid van Moolenbroek 	CK_BYTE newdigest[ISC_SHA224_DIGESTLENGTH];
403*00b67f09SDavid van Moolenbroek 	CK_ULONG psl = ISC_SHA224_DIGESTLENGTH;
404*00b67f09SDavid van Moolenbroek 
405*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
406*00b67f09SDavid van Moolenbroek 
407*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
408*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
409*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
410*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
411*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
412*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
413*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
414*00b67f09SDavid van Moolenbroek }
415*00b67f09SDavid van Moolenbroek 
416*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_init(isc_hmacsha256_t * ctx,const unsigned char * key,unsigned int len)417*00b67f09SDavid van Moolenbroek isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
418*00b67f09SDavid van Moolenbroek 		    unsigned int len)
419*00b67f09SDavid van Moolenbroek {
420*00b67f09SDavid van Moolenbroek 	CK_RV rv;
421*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA256_HMAC, NULL, 0 };
422*00b67f09SDavid van Moolenbroek 	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
423*00b67f09SDavid van Moolenbroek 	CK_KEY_TYPE keyType = CKK_SHA256_HMAC;
424*00b67f09SDavid van Moolenbroek 	CK_ATTRIBUTE keyTemplate[] =
425*00b67f09SDavid van Moolenbroek 	{
426*00b67f09SDavid van Moolenbroek 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
427*00b67f09SDavid van Moolenbroek 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
428*00b67f09SDavid van Moolenbroek 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
429*00b67f09SDavid van Moolenbroek 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
430*00b67f09SDavid van Moolenbroek 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
431*00b67f09SDavid van Moolenbroek 		{ CKA_VALUE, NULL, (CK_ULONG) len }
432*00b67f09SDavid van Moolenbroek 	};
433*00b67f09SDavid van Moolenbroek 
434*00b67f09SDavid van Moolenbroek 	DE_CONST(key, keyTemplate[5].pValue);
435*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
436*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
437*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
438*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_CreateObject,
439*00b67f09SDavid van Moolenbroek 			(ctx->session, keyTemplate,
440*00b67f09SDavid van Moolenbroek 			 (CK_ULONG) 6, &ctx->object));
441*00b67f09SDavid van Moolenbroek 	INSIST(ctx->object != CK_INVALID_HANDLE);
442*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
443*00b67f09SDavid van Moolenbroek }
444*00b67f09SDavid van Moolenbroek 
445*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_invalidate(isc_hmacsha256_t * ctx)446*00b67f09SDavid van Moolenbroek isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
447*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH];
448*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA256_DIGESTLENGTH;
449*00b67f09SDavid van Moolenbroek 
450*00b67f09SDavid van Moolenbroek 	if (ctx->handle == NULL)
451*00b67f09SDavid van Moolenbroek 		return;
452*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_SignFinal(ctx->session, garbage, &len);
453*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
454*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
455*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
456*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
457*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
458*00b67f09SDavid van Moolenbroek }
459*00b67f09SDavid van Moolenbroek 
460*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_update(isc_hmacsha256_t * ctx,const unsigned char * buf,unsigned int len)461*00b67f09SDavid van Moolenbroek isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
462*00b67f09SDavid van Moolenbroek 		      unsigned int len)
463*00b67f09SDavid van Moolenbroek {
464*00b67f09SDavid van Moolenbroek 	CK_RV rv;
465*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
466*00b67f09SDavid van Moolenbroek 
467*00b67f09SDavid van Moolenbroek 	DE_CONST(buf, pPart);
468*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignUpdate,
469*00b67f09SDavid van Moolenbroek 			(ctx->session, pPart, (CK_ULONG) len));
470*00b67f09SDavid van Moolenbroek }
471*00b67f09SDavid van Moolenbroek 
472*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_sign(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)473*00b67f09SDavid van Moolenbroek isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
474*00b67f09SDavid van Moolenbroek 	CK_RV rv;
475*00b67f09SDavid van Moolenbroek 	CK_BYTE newdigest[ISC_SHA256_DIGESTLENGTH];
476*00b67f09SDavid van Moolenbroek 	CK_ULONG psl = ISC_SHA256_DIGESTLENGTH;
477*00b67f09SDavid van Moolenbroek 
478*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
479*00b67f09SDavid van Moolenbroek 
480*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
481*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
482*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
483*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
484*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
485*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
486*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
487*00b67f09SDavid van Moolenbroek }
488*00b67f09SDavid van Moolenbroek 
489*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_init(isc_hmacsha384_t * ctx,const unsigned char * key,unsigned int len)490*00b67f09SDavid van Moolenbroek isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
491*00b67f09SDavid van Moolenbroek 		    unsigned int len)
492*00b67f09SDavid van Moolenbroek {
493*00b67f09SDavid van Moolenbroek 	CK_RV rv;
494*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA384_HMAC, NULL, 0 };
495*00b67f09SDavid van Moolenbroek 	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
496*00b67f09SDavid van Moolenbroek 	CK_KEY_TYPE keyType = CKK_SHA384_HMAC;
497*00b67f09SDavid van Moolenbroek 	CK_ATTRIBUTE keyTemplate[] =
498*00b67f09SDavid van Moolenbroek 	{
499*00b67f09SDavid van Moolenbroek 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
500*00b67f09SDavid van Moolenbroek 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
501*00b67f09SDavid van Moolenbroek 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
502*00b67f09SDavid van Moolenbroek 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
503*00b67f09SDavid van Moolenbroek 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
504*00b67f09SDavid van Moolenbroek 		{ CKA_VALUE, NULL, (CK_ULONG) len }
505*00b67f09SDavid van Moolenbroek 	};
506*00b67f09SDavid van Moolenbroek 
507*00b67f09SDavid van Moolenbroek 	DE_CONST(key, keyTemplate[5].pValue);
508*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
509*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
510*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
511*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_CreateObject,
512*00b67f09SDavid van Moolenbroek 			(ctx->session, keyTemplate,
513*00b67f09SDavid van Moolenbroek 			 (CK_ULONG) 6, &ctx->object));
514*00b67f09SDavid van Moolenbroek 	INSIST(ctx->object != CK_INVALID_HANDLE);
515*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
516*00b67f09SDavid van Moolenbroek }
517*00b67f09SDavid van Moolenbroek 
518*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_invalidate(isc_hmacsha384_t * ctx)519*00b67f09SDavid van Moolenbroek isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
520*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH];
521*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA384_DIGESTLENGTH;
522*00b67f09SDavid van Moolenbroek 
523*00b67f09SDavid van Moolenbroek 	if (ctx->handle == NULL)
524*00b67f09SDavid van Moolenbroek 		return;
525*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_SignFinal(ctx->session, garbage, &len);
526*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
527*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
528*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
529*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
530*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
531*00b67f09SDavid van Moolenbroek }
532*00b67f09SDavid van Moolenbroek 
533*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_update(isc_hmacsha384_t * ctx,const unsigned char * buf,unsigned int len)534*00b67f09SDavid van Moolenbroek isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
535*00b67f09SDavid van Moolenbroek 		      unsigned int len)
536*00b67f09SDavid van Moolenbroek {
537*00b67f09SDavid van Moolenbroek 	CK_RV rv;
538*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
539*00b67f09SDavid van Moolenbroek 
540*00b67f09SDavid van Moolenbroek 	DE_CONST(buf, pPart);
541*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignUpdate,
542*00b67f09SDavid van Moolenbroek 			(ctx->session, pPart, (CK_ULONG) len));
543*00b67f09SDavid van Moolenbroek }
544*00b67f09SDavid van Moolenbroek 
545*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_sign(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)546*00b67f09SDavid van Moolenbroek isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
547*00b67f09SDavid van Moolenbroek 	CK_RV rv;
548*00b67f09SDavid van Moolenbroek 	CK_BYTE newdigest[ISC_SHA384_DIGESTLENGTH];
549*00b67f09SDavid van Moolenbroek 	CK_ULONG psl = ISC_SHA384_DIGESTLENGTH;
550*00b67f09SDavid van Moolenbroek 
551*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
552*00b67f09SDavid van Moolenbroek 
553*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
554*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
555*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
556*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
557*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
558*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
559*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
560*00b67f09SDavid van Moolenbroek }
561*00b67f09SDavid van Moolenbroek 
562*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_init(isc_hmacsha512_t * ctx,const unsigned char * key,unsigned int len)563*00b67f09SDavid van Moolenbroek isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
564*00b67f09SDavid van Moolenbroek 		    unsigned int len)
565*00b67f09SDavid van Moolenbroek {
566*00b67f09SDavid van Moolenbroek 	CK_RV rv;
567*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA512_HMAC, NULL, 0 };
568*00b67f09SDavid van Moolenbroek 	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
569*00b67f09SDavid van Moolenbroek 	CK_KEY_TYPE keyType = CKK_SHA512_HMAC;
570*00b67f09SDavid van Moolenbroek 	CK_ATTRIBUTE keyTemplate[] =
571*00b67f09SDavid van Moolenbroek 	{
572*00b67f09SDavid van Moolenbroek 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
573*00b67f09SDavid van Moolenbroek 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
574*00b67f09SDavid van Moolenbroek 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
575*00b67f09SDavid van Moolenbroek 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
576*00b67f09SDavid van Moolenbroek 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
577*00b67f09SDavid van Moolenbroek 		{ CKA_VALUE, NULL, (CK_ULONG) len }
578*00b67f09SDavid van Moolenbroek 	};
579*00b67f09SDavid van Moolenbroek 
580*00b67f09SDavid van Moolenbroek 	DE_CONST(key, keyTemplate[5].pValue);
581*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
582*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
583*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
584*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_CreateObject,
585*00b67f09SDavid van Moolenbroek 			(ctx->session, keyTemplate,
586*00b67f09SDavid van Moolenbroek 			 (CK_ULONG) 6, &ctx->object));
587*00b67f09SDavid van Moolenbroek 	INSIST(ctx->object != CK_INVALID_HANDLE);
588*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
589*00b67f09SDavid van Moolenbroek }
590*00b67f09SDavid van Moolenbroek 
591*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_invalidate(isc_hmacsha512_t * ctx)592*00b67f09SDavid van Moolenbroek isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
593*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
594*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
595*00b67f09SDavid van Moolenbroek 
596*00b67f09SDavid van Moolenbroek 	if (ctx->handle == NULL)
597*00b67f09SDavid van Moolenbroek 		return;
598*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_SignFinal(ctx->session, garbage, &len);
599*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
600*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
601*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
602*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
603*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
604*00b67f09SDavid van Moolenbroek }
605*00b67f09SDavid van Moolenbroek 
606*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_update(isc_hmacsha512_t * ctx,const unsigned char * buf,unsigned int len)607*00b67f09SDavid van Moolenbroek isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
608*00b67f09SDavid van Moolenbroek 		      unsigned int len)
609*00b67f09SDavid van Moolenbroek {
610*00b67f09SDavid van Moolenbroek 	CK_RV rv;
611*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
612*00b67f09SDavid van Moolenbroek 
613*00b67f09SDavid van Moolenbroek 	DE_CONST(buf, pPart);
614*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignUpdate,
615*00b67f09SDavid van Moolenbroek 			(ctx->session, pPart, (CK_ULONG) len));
616*00b67f09SDavid van Moolenbroek }
617*00b67f09SDavid van Moolenbroek 
618*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_sign(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)619*00b67f09SDavid van Moolenbroek isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
620*00b67f09SDavid van Moolenbroek 	CK_RV rv;
621*00b67f09SDavid van Moolenbroek 	CK_BYTE newdigest[ISC_SHA512_DIGESTLENGTH];
622*00b67f09SDavid van Moolenbroek 	CK_ULONG psl = ISC_SHA512_DIGESTLENGTH;
623*00b67f09SDavid van Moolenbroek 
624*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
625*00b67f09SDavid van Moolenbroek 
626*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
627*00b67f09SDavid van Moolenbroek 	if (ctx->object != CK_INVALID_HANDLE)
628*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DestroyObject(ctx->session, ctx->object);
629*00b67f09SDavid van Moolenbroek 	ctx->object = CK_INVALID_HANDLE;
630*00b67f09SDavid van Moolenbroek 	pk11_return_session(ctx);
631*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
632*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
633*00b67f09SDavid van Moolenbroek }
634*00b67f09SDavid van Moolenbroek 
635*00b67f09SDavid van Moolenbroek #else
636*00b67f09SDavid van Moolenbroek 
637*00b67f09SDavid van Moolenbroek #define IPAD 0x36
638*00b67f09SDavid van Moolenbroek #define OPAD 0x5C
639*00b67f09SDavid van Moolenbroek 
640*00b67f09SDavid van Moolenbroek /*
641*00b67f09SDavid van Moolenbroek  * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
642*00b67f09SDavid van Moolenbroek  */
643*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_init(isc_hmacsha1_t * ctx,const unsigned char * key,unsigned int len)644*00b67f09SDavid van Moolenbroek isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
645*00b67f09SDavid van Moolenbroek 		  unsigned int len)
646*00b67f09SDavid van Moolenbroek {
647*00b67f09SDavid van Moolenbroek 	unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
648*00b67f09SDavid van Moolenbroek 	unsigned int i;
649*00b67f09SDavid van Moolenbroek 
650*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
651*00b67f09SDavid van Moolenbroek 	if (len > sizeof(ctx->key)) {
652*00b67f09SDavid van Moolenbroek 		isc_sha1_t sha1ctx;
653*00b67f09SDavid van Moolenbroek 		isc_sha1_init(&sha1ctx);
654*00b67f09SDavid van Moolenbroek 		isc_sha1_update(&sha1ctx, key, len);
655*00b67f09SDavid van Moolenbroek 		isc_sha1_final(&sha1ctx, ctx->key);
656*00b67f09SDavid van Moolenbroek 	} else
657*00b67f09SDavid van Moolenbroek 		memmove(ctx->key, key, len);
658*00b67f09SDavid van Moolenbroek 
659*00b67f09SDavid van Moolenbroek 	isc_sha1_init(&ctx->sha1ctx);
660*00b67f09SDavid van Moolenbroek 	memset(ipad, IPAD, sizeof(ipad));
661*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
662*00b67f09SDavid van Moolenbroek 		ipad[i] ^= ctx->key[i];
663*00b67f09SDavid van Moolenbroek 	isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
664*00b67f09SDavid van Moolenbroek }
665*00b67f09SDavid van Moolenbroek 
666*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_invalidate(isc_hmacsha1_t * ctx)667*00b67f09SDavid van Moolenbroek isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
668*00b67f09SDavid van Moolenbroek 	isc_sha1_invalidate(&ctx->sha1ctx);
669*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
670*00b67f09SDavid van Moolenbroek 	memset(ctx, 0, sizeof(*ctx));
671*00b67f09SDavid van Moolenbroek }
672*00b67f09SDavid van Moolenbroek 
673*00b67f09SDavid van Moolenbroek /*
674*00b67f09SDavid van Moolenbroek  * Update context to reflect the concatenation of another buffer full
675*00b67f09SDavid van Moolenbroek  * of bytes.
676*00b67f09SDavid van Moolenbroek  */
677*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_update(isc_hmacsha1_t * ctx,const unsigned char * buf,unsigned int len)678*00b67f09SDavid van Moolenbroek isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
679*00b67f09SDavid van Moolenbroek 		   unsigned int len)
680*00b67f09SDavid van Moolenbroek {
681*00b67f09SDavid van Moolenbroek 	isc_sha1_update(&ctx->sha1ctx, buf, len);
682*00b67f09SDavid van Moolenbroek }
683*00b67f09SDavid van Moolenbroek 
684*00b67f09SDavid van Moolenbroek /*
685*00b67f09SDavid van Moolenbroek  * Compute signature - finalize SHA1 operation and reapply SHA1.
686*00b67f09SDavid van Moolenbroek  */
687*00b67f09SDavid van Moolenbroek void
isc_hmacsha1_sign(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)688*00b67f09SDavid van Moolenbroek isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
689*00b67f09SDavid van Moolenbroek 	unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
690*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
691*00b67f09SDavid van Moolenbroek 	unsigned int i;
692*00b67f09SDavid van Moolenbroek 
693*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
694*00b67f09SDavid van Moolenbroek 	isc_sha1_final(&ctx->sha1ctx, newdigest);
695*00b67f09SDavid van Moolenbroek 
696*00b67f09SDavid van Moolenbroek 	memset(opad, OPAD, sizeof(opad));
697*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
698*00b67f09SDavid van Moolenbroek 		opad[i] ^= ctx->key[i];
699*00b67f09SDavid van Moolenbroek 
700*00b67f09SDavid van Moolenbroek 	isc_sha1_init(&ctx->sha1ctx);
701*00b67f09SDavid van Moolenbroek 	isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
702*00b67f09SDavid van Moolenbroek 	isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
703*00b67f09SDavid van Moolenbroek 	isc_sha1_final(&ctx->sha1ctx, newdigest);
704*00b67f09SDavid van Moolenbroek 	isc_hmacsha1_invalidate(ctx);
705*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
706*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
707*00b67f09SDavid van Moolenbroek }
708*00b67f09SDavid van Moolenbroek 
709*00b67f09SDavid van Moolenbroek /*
710*00b67f09SDavid van Moolenbroek  * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
711*00b67f09SDavid van Moolenbroek  */
712*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_init(isc_hmacsha224_t * ctx,const unsigned char * key,unsigned int len)713*00b67f09SDavid van Moolenbroek isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
714*00b67f09SDavid van Moolenbroek 		    unsigned int len)
715*00b67f09SDavid van Moolenbroek {
716*00b67f09SDavid van Moolenbroek 	unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
717*00b67f09SDavid van Moolenbroek 	unsigned int i;
718*00b67f09SDavid van Moolenbroek 
719*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
720*00b67f09SDavid van Moolenbroek 	if (len > sizeof(ctx->key)) {
721*00b67f09SDavid van Moolenbroek 		isc_sha224_t sha224ctx;
722*00b67f09SDavid van Moolenbroek 		isc_sha224_init(&sha224ctx);
723*00b67f09SDavid van Moolenbroek 		isc_sha224_update(&sha224ctx, key, len);
724*00b67f09SDavid van Moolenbroek 		isc_sha224_final(ctx->key, &sha224ctx);
725*00b67f09SDavid van Moolenbroek 	} else
726*00b67f09SDavid van Moolenbroek 		memmove(ctx->key, key, len);
727*00b67f09SDavid van Moolenbroek 
728*00b67f09SDavid van Moolenbroek 	isc_sha224_init(&ctx->sha224ctx);
729*00b67f09SDavid van Moolenbroek 	memset(ipad, IPAD, sizeof(ipad));
730*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
731*00b67f09SDavid van Moolenbroek 		ipad[i] ^= ctx->key[i];
732*00b67f09SDavid van Moolenbroek 	isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
733*00b67f09SDavid van Moolenbroek }
734*00b67f09SDavid van Moolenbroek 
735*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_invalidate(isc_hmacsha224_t * ctx)736*00b67f09SDavid van Moolenbroek isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
737*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
738*00b67f09SDavid van Moolenbroek 	memset(ctx, 0, sizeof(*ctx));
739*00b67f09SDavid van Moolenbroek }
740*00b67f09SDavid van Moolenbroek 
741*00b67f09SDavid van Moolenbroek /*
742*00b67f09SDavid van Moolenbroek  * Update context to reflect the concatenation of another buffer full
743*00b67f09SDavid van Moolenbroek  * of bytes.
744*00b67f09SDavid van Moolenbroek  */
745*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_update(isc_hmacsha224_t * ctx,const unsigned char * buf,unsigned int len)746*00b67f09SDavid van Moolenbroek isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
747*00b67f09SDavid van Moolenbroek 		   unsigned int len)
748*00b67f09SDavid van Moolenbroek {
749*00b67f09SDavid van Moolenbroek 	isc_sha224_update(&ctx->sha224ctx, buf, len);
750*00b67f09SDavid van Moolenbroek }
751*00b67f09SDavid van Moolenbroek 
752*00b67f09SDavid van Moolenbroek /*
753*00b67f09SDavid van Moolenbroek  * Compute signature - finalize SHA224 operation and reapply SHA224.
754*00b67f09SDavid van Moolenbroek  */
755*00b67f09SDavid van Moolenbroek void
isc_hmacsha224_sign(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)756*00b67f09SDavid van Moolenbroek isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
757*00b67f09SDavid van Moolenbroek 	unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
758*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
759*00b67f09SDavid van Moolenbroek 	unsigned int i;
760*00b67f09SDavid van Moolenbroek 
761*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
762*00b67f09SDavid van Moolenbroek 	isc_sha224_final(newdigest, &ctx->sha224ctx);
763*00b67f09SDavid van Moolenbroek 
764*00b67f09SDavid van Moolenbroek 	memset(opad, OPAD, sizeof(opad));
765*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
766*00b67f09SDavid van Moolenbroek 		opad[i] ^= ctx->key[i];
767*00b67f09SDavid van Moolenbroek 
768*00b67f09SDavid van Moolenbroek 	isc_sha224_init(&ctx->sha224ctx);
769*00b67f09SDavid van Moolenbroek 	isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
770*00b67f09SDavid van Moolenbroek 	isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
771*00b67f09SDavid van Moolenbroek 	isc_sha224_final(newdigest, &ctx->sha224ctx);
772*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
773*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
774*00b67f09SDavid van Moolenbroek }
775*00b67f09SDavid van Moolenbroek 
776*00b67f09SDavid van Moolenbroek /*
777*00b67f09SDavid van Moolenbroek  * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
778*00b67f09SDavid van Moolenbroek  */
779*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_init(isc_hmacsha256_t * ctx,const unsigned char * key,unsigned int len)780*00b67f09SDavid van Moolenbroek isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
781*00b67f09SDavid van Moolenbroek 		    unsigned int len)
782*00b67f09SDavid van Moolenbroek {
783*00b67f09SDavid van Moolenbroek 	unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
784*00b67f09SDavid van Moolenbroek 	unsigned int i;
785*00b67f09SDavid van Moolenbroek 
786*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
787*00b67f09SDavid van Moolenbroek 	if (len > sizeof(ctx->key)) {
788*00b67f09SDavid van Moolenbroek 		isc_sha256_t sha256ctx;
789*00b67f09SDavid van Moolenbroek 		isc_sha256_init(&sha256ctx);
790*00b67f09SDavid van Moolenbroek 		isc_sha256_update(&sha256ctx, key, len);
791*00b67f09SDavid van Moolenbroek 		isc_sha256_final(ctx->key, &sha256ctx);
792*00b67f09SDavid van Moolenbroek 	} else
793*00b67f09SDavid van Moolenbroek 		memmove(ctx->key, key, len);
794*00b67f09SDavid van Moolenbroek 
795*00b67f09SDavid van Moolenbroek 	isc_sha256_init(&ctx->sha256ctx);
796*00b67f09SDavid van Moolenbroek 	memset(ipad, IPAD, sizeof(ipad));
797*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
798*00b67f09SDavid van Moolenbroek 		ipad[i] ^= ctx->key[i];
799*00b67f09SDavid van Moolenbroek 	isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
800*00b67f09SDavid van Moolenbroek }
801*00b67f09SDavid van Moolenbroek 
802*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_invalidate(isc_hmacsha256_t * ctx)803*00b67f09SDavid van Moolenbroek isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
804*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
805*00b67f09SDavid van Moolenbroek 	memset(ctx, 0, sizeof(*ctx));
806*00b67f09SDavid van Moolenbroek }
807*00b67f09SDavid van Moolenbroek 
808*00b67f09SDavid van Moolenbroek /*
809*00b67f09SDavid van Moolenbroek  * Update context to reflect the concatenation of another buffer full
810*00b67f09SDavid van Moolenbroek  * of bytes.
811*00b67f09SDavid van Moolenbroek  */
812*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_update(isc_hmacsha256_t * ctx,const unsigned char * buf,unsigned int len)813*00b67f09SDavid van Moolenbroek isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
814*00b67f09SDavid van Moolenbroek 		   unsigned int len)
815*00b67f09SDavid van Moolenbroek {
816*00b67f09SDavid van Moolenbroek 	isc_sha256_update(&ctx->sha256ctx, buf, len);
817*00b67f09SDavid van Moolenbroek }
818*00b67f09SDavid van Moolenbroek 
819*00b67f09SDavid van Moolenbroek /*
820*00b67f09SDavid van Moolenbroek  * Compute signature - finalize SHA256 operation and reapply SHA256.
821*00b67f09SDavid van Moolenbroek  */
822*00b67f09SDavid van Moolenbroek void
isc_hmacsha256_sign(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)823*00b67f09SDavid van Moolenbroek isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
824*00b67f09SDavid van Moolenbroek 	unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
825*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
826*00b67f09SDavid van Moolenbroek 	unsigned int i;
827*00b67f09SDavid van Moolenbroek 
828*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
829*00b67f09SDavid van Moolenbroek 	isc_sha256_final(newdigest, &ctx->sha256ctx);
830*00b67f09SDavid van Moolenbroek 
831*00b67f09SDavid van Moolenbroek 	memset(opad, OPAD, sizeof(opad));
832*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
833*00b67f09SDavid van Moolenbroek 		opad[i] ^= ctx->key[i];
834*00b67f09SDavid van Moolenbroek 
835*00b67f09SDavid van Moolenbroek 	isc_sha256_init(&ctx->sha256ctx);
836*00b67f09SDavid van Moolenbroek 	isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
837*00b67f09SDavid van Moolenbroek 	isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
838*00b67f09SDavid van Moolenbroek 	isc_sha256_final(newdigest, &ctx->sha256ctx);
839*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
840*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
841*00b67f09SDavid van Moolenbroek }
842*00b67f09SDavid van Moolenbroek 
843*00b67f09SDavid van Moolenbroek /*
844*00b67f09SDavid van Moolenbroek  * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
845*00b67f09SDavid van Moolenbroek  */
846*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_init(isc_hmacsha384_t * ctx,const unsigned char * key,unsigned int len)847*00b67f09SDavid van Moolenbroek isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
848*00b67f09SDavid van Moolenbroek 		    unsigned int len)
849*00b67f09SDavid van Moolenbroek {
850*00b67f09SDavid van Moolenbroek 	unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
851*00b67f09SDavid van Moolenbroek 	unsigned int i;
852*00b67f09SDavid van Moolenbroek 
853*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
854*00b67f09SDavid van Moolenbroek 	if (len > sizeof(ctx->key)) {
855*00b67f09SDavid van Moolenbroek 		isc_sha384_t sha384ctx;
856*00b67f09SDavid van Moolenbroek 		isc_sha384_init(&sha384ctx);
857*00b67f09SDavid van Moolenbroek 		isc_sha384_update(&sha384ctx, key, len);
858*00b67f09SDavid van Moolenbroek 		isc_sha384_final(ctx->key, &sha384ctx);
859*00b67f09SDavid van Moolenbroek 	} else
860*00b67f09SDavid van Moolenbroek 		memmove(ctx->key, key, len);
861*00b67f09SDavid van Moolenbroek 
862*00b67f09SDavid van Moolenbroek 	isc_sha384_init(&ctx->sha384ctx);
863*00b67f09SDavid van Moolenbroek 	memset(ipad, IPAD, sizeof(ipad));
864*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
865*00b67f09SDavid van Moolenbroek 		ipad[i] ^= ctx->key[i];
866*00b67f09SDavid van Moolenbroek 	isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
867*00b67f09SDavid van Moolenbroek }
868*00b67f09SDavid van Moolenbroek 
869*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_invalidate(isc_hmacsha384_t * ctx)870*00b67f09SDavid van Moolenbroek isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
871*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
872*00b67f09SDavid van Moolenbroek 	memset(ctx, 0, sizeof(*ctx));
873*00b67f09SDavid van Moolenbroek }
874*00b67f09SDavid van Moolenbroek 
875*00b67f09SDavid van Moolenbroek /*
876*00b67f09SDavid van Moolenbroek  * Update context to reflect the concatenation of another buffer full
877*00b67f09SDavid van Moolenbroek  * of bytes.
878*00b67f09SDavid van Moolenbroek  */
879*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_update(isc_hmacsha384_t * ctx,const unsigned char * buf,unsigned int len)880*00b67f09SDavid van Moolenbroek isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
881*00b67f09SDavid van Moolenbroek 		   unsigned int len)
882*00b67f09SDavid van Moolenbroek {
883*00b67f09SDavid van Moolenbroek 	isc_sha384_update(&ctx->sha384ctx, buf, len);
884*00b67f09SDavid van Moolenbroek }
885*00b67f09SDavid van Moolenbroek 
886*00b67f09SDavid van Moolenbroek /*
887*00b67f09SDavid van Moolenbroek  * Compute signature - finalize SHA384 operation and reapply SHA384.
888*00b67f09SDavid van Moolenbroek  */
889*00b67f09SDavid van Moolenbroek void
isc_hmacsha384_sign(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)890*00b67f09SDavid van Moolenbroek isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
891*00b67f09SDavid van Moolenbroek 	unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
892*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
893*00b67f09SDavid van Moolenbroek 	unsigned int i;
894*00b67f09SDavid van Moolenbroek 
895*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
896*00b67f09SDavid van Moolenbroek 	isc_sha384_final(newdigest, &ctx->sha384ctx);
897*00b67f09SDavid van Moolenbroek 
898*00b67f09SDavid van Moolenbroek 	memset(opad, OPAD, sizeof(opad));
899*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
900*00b67f09SDavid van Moolenbroek 		opad[i] ^= ctx->key[i];
901*00b67f09SDavid van Moolenbroek 
902*00b67f09SDavid van Moolenbroek 	isc_sha384_init(&ctx->sha384ctx);
903*00b67f09SDavid van Moolenbroek 	isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
904*00b67f09SDavid van Moolenbroek 	isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
905*00b67f09SDavid van Moolenbroek 	isc_sha384_final(newdigest, &ctx->sha384ctx);
906*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
907*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
908*00b67f09SDavid van Moolenbroek }
909*00b67f09SDavid van Moolenbroek 
910*00b67f09SDavid van Moolenbroek /*
911*00b67f09SDavid van Moolenbroek  * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
912*00b67f09SDavid van Moolenbroek  */
913*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_init(isc_hmacsha512_t * ctx,const unsigned char * key,unsigned int len)914*00b67f09SDavid van Moolenbroek isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
915*00b67f09SDavid van Moolenbroek 		    unsigned int len)
916*00b67f09SDavid van Moolenbroek {
917*00b67f09SDavid van Moolenbroek 	unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
918*00b67f09SDavid van Moolenbroek 	unsigned int i;
919*00b67f09SDavid van Moolenbroek 
920*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
921*00b67f09SDavid van Moolenbroek 	if (len > sizeof(ctx->key)) {
922*00b67f09SDavid van Moolenbroek 		isc_sha512_t sha512ctx;
923*00b67f09SDavid van Moolenbroek 		isc_sha512_init(&sha512ctx);
924*00b67f09SDavid van Moolenbroek 		isc_sha512_update(&sha512ctx, key, len);
925*00b67f09SDavid van Moolenbroek 		isc_sha512_final(ctx->key, &sha512ctx);
926*00b67f09SDavid van Moolenbroek 	} else
927*00b67f09SDavid van Moolenbroek 		memmove(ctx->key, key, len);
928*00b67f09SDavid van Moolenbroek 
929*00b67f09SDavid van Moolenbroek 	isc_sha512_init(&ctx->sha512ctx);
930*00b67f09SDavid van Moolenbroek 	memset(ipad, IPAD, sizeof(ipad));
931*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
932*00b67f09SDavid van Moolenbroek 		ipad[i] ^= ctx->key[i];
933*00b67f09SDavid van Moolenbroek 	isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
934*00b67f09SDavid van Moolenbroek }
935*00b67f09SDavid van Moolenbroek 
936*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_invalidate(isc_hmacsha512_t * ctx)937*00b67f09SDavid van Moolenbroek isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
938*00b67f09SDavid van Moolenbroek 	memset(ctx->key, 0, sizeof(ctx->key));
939*00b67f09SDavid van Moolenbroek 	memset(ctx, 0, sizeof(*ctx));
940*00b67f09SDavid van Moolenbroek }
941*00b67f09SDavid van Moolenbroek 
942*00b67f09SDavid van Moolenbroek /*
943*00b67f09SDavid van Moolenbroek  * Update context to reflect the concatenation of another buffer full
944*00b67f09SDavid van Moolenbroek  * of bytes.
945*00b67f09SDavid van Moolenbroek  */
946*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_update(isc_hmacsha512_t * ctx,const unsigned char * buf,unsigned int len)947*00b67f09SDavid van Moolenbroek isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
948*00b67f09SDavid van Moolenbroek 		   unsigned int len)
949*00b67f09SDavid van Moolenbroek {
950*00b67f09SDavid van Moolenbroek 	isc_sha512_update(&ctx->sha512ctx, buf, len);
951*00b67f09SDavid van Moolenbroek }
952*00b67f09SDavid van Moolenbroek 
953*00b67f09SDavid van Moolenbroek /*
954*00b67f09SDavid van Moolenbroek  * Compute signature - finalize SHA512 operation and reapply SHA512.
955*00b67f09SDavid van Moolenbroek  */
956*00b67f09SDavid van Moolenbroek void
isc_hmacsha512_sign(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)957*00b67f09SDavid van Moolenbroek isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
958*00b67f09SDavid van Moolenbroek 	unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
959*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
960*00b67f09SDavid van Moolenbroek 	unsigned int i;
961*00b67f09SDavid van Moolenbroek 
962*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
963*00b67f09SDavid van Moolenbroek 	isc_sha512_final(newdigest, &ctx->sha512ctx);
964*00b67f09SDavid van Moolenbroek 
965*00b67f09SDavid van Moolenbroek 	memset(opad, OPAD, sizeof(opad));
966*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
967*00b67f09SDavid van Moolenbroek 		opad[i] ^= ctx->key[i];
968*00b67f09SDavid van Moolenbroek 
969*00b67f09SDavid van Moolenbroek 	isc_sha512_init(&ctx->sha512ctx);
970*00b67f09SDavid van Moolenbroek 	isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
971*00b67f09SDavid van Moolenbroek 	isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
972*00b67f09SDavid van Moolenbroek 	isc_sha512_final(newdigest, &ctx->sha512ctx);
973*00b67f09SDavid van Moolenbroek 	memmove(digest, newdigest, len);
974*00b67f09SDavid van Moolenbroek 	memset(newdigest, 0, sizeof(newdigest));
975*00b67f09SDavid van Moolenbroek }
976*00b67f09SDavid van Moolenbroek #endif /* !ISC_PLATFORM_OPENSSLHASH */
977*00b67f09SDavid van Moolenbroek 
978*00b67f09SDavid van Moolenbroek /*
979*00b67f09SDavid van Moolenbroek  * Verify signature - finalize SHA1 operation and reapply SHA1, then
980*00b67f09SDavid van Moolenbroek  * compare to the supplied digest.
981*00b67f09SDavid van Moolenbroek  */
982*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacsha1_verify(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)983*00b67f09SDavid van Moolenbroek isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
984*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
985*00b67f09SDavid van Moolenbroek 
986*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
987*00b67f09SDavid van Moolenbroek 	isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
988*00b67f09SDavid van Moolenbroek 	return (isc_safe_memcmp(digest, newdigest, len));
989*00b67f09SDavid van Moolenbroek }
990*00b67f09SDavid van Moolenbroek 
991*00b67f09SDavid van Moolenbroek /*
992*00b67f09SDavid van Moolenbroek  * Verify signature - finalize SHA224 operation and reapply SHA224, then
993*00b67f09SDavid van Moolenbroek  * compare to the supplied digest.
994*00b67f09SDavid van Moolenbroek  */
995*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacsha224_verify(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)996*00b67f09SDavid van Moolenbroek isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
997*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
998*00b67f09SDavid van Moolenbroek 
999*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
1000*00b67f09SDavid van Moolenbroek 	isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
1001*00b67f09SDavid van Moolenbroek 	return (isc_safe_memcmp(digest, newdigest, len));
1002*00b67f09SDavid van Moolenbroek }
1003*00b67f09SDavid van Moolenbroek 
1004*00b67f09SDavid van Moolenbroek /*
1005*00b67f09SDavid van Moolenbroek  * Verify signature - finalize SHA256 operation and reapply SHA256, then
1006*00b67f09SDavid van Moolenbroek  * compare to the supplied digest.
1007*00b67f09SDavid van Moolenbroek  */
1008*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacsha256_verify(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)1009*00b67f09SDavid van Moolenbroek isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
1010*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
1011*00b67f09SDavid van Moolenbroek 
1012*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
1013*00b67f09SDavid van Moolenbroek 	isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
1014*00b67f09SDavid van Moolenbroek 	return (isc_safe_memcmp(digest, newdigest, len));
1015*00b67f09SDavid van Moolenbroek }
1016*00b67f09SDavid van Moolenbroek 
1017*00b67f09SDavid van Moolenbroek /*
1018*00b67f09SDavid van Moolenbroek  * Verify signature - finalize SHA384 operation and reapply SHA384, then
1019*00b67f09SDavid van Moolenbroek  * compare to the supplied digest.
1020*00b67f09SDavid van Moolenbroek  */
1021*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacsha384_verify(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)1022*00b67f09SDavid van Moolenbroek isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
1023*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
1024*00b67f09SDavid van Moolenbroek 
1025*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
1026*00b67f09SDavid van Moolenbroek 	isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
1027*00b67f09SDavid van Moolenbroek 	return (isc_safe_memcmp(digest, newdigest, len));
1028*00b67f09SDavid van Moolenbroek }
1029*00b67f09SDavid van Moolenbroek 
1030*00b67f09SDavid van Moolenbroek /*
1031*00b67f09SDavid van Moolenbroek  * Verify signature - finalize SHA512 operation and reapply SHA512, then
1032*00b67f09SDavid van Moolenbroek  * compare to the supplied digest.
1033*00b67f09SDavid van Moolenbroek  */
1034*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacsha512_verify(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)1035*00b67f09SDavid van Moolenbroek isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
1036*00b67f09SDavid van Moolenbroek 	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
1037*00b67f09SDavid van Moolenbroek 
1038*00b67f09SDavid van Moolenbroek 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
1039*00b67f09SDavid van Moolenbroek 	isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
1040*00b67f09SDavid van Moolenbroek 	return (isc_safe_memcmp(digest, newdigest, len));
1041*00b67f09SDavid van Moolenbroek }
1042