xref: /minix3/external/bsd/bind/dist/lib/isc/sha2.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: sha2.c,v 1.10 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, 2012, 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 /*	$FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $	*/
22*00b67f09SDavid van Moolenbroek /*	$KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $	*/
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek /*
25*00b67f09SDavid van Moolenbroek  * sha2.c
26*00b67f09SDavid van Moolenbroek  *
27*00b67f09SDavid van Moolenbroek  * Version 1.0.0beta1
28*00b67f09SDavid van Moolenbroek  *
29*00b67f09SDavid van Moolenbroek  * Written by Aaron D. Gifford <me@aarongifford.com>
30*00b67f09SDavid van Moolenbroek  *
31*00b67f09SDavid van Moolenbroek  * Copyright 2000 Aaron D. Gifford.  All rights reserved.
32*00b67f09SDavid van Moolenbroek  *
33*00b67f09SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
34*00b67f09SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
35*00b67f09SDavid van Moolenbroek  * are met:
36*00b67f09SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
37*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
38*00b67f09SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
39*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
40*00b67f09SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
41*00b67f09SDavid van Moolenbroek  * 3. Neither the name of the copyright holder nor the names of contributors
42*00b67f09SDavid van Moolenbroek  *    may be used to endorse or promote products derived from this software
43*00b67f09SDavid van Moolenbroek  *    without specific prior written permission.
44*00b67f09SDavid van Moolenbroek  *
45*00b67f09SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
46*00b67f09SDavid van Moolenbroek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47*00b67f09SDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48*00b67f09SDavid van Moolenbroek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
49*00b67f09SDavid van Moolenbroek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50*00b67f09SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51*00b67f09SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52*00b67f09SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53*00b67f09SDavid van Moolenbroek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54*00b67f09SDavid van Moolenbroek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55*00b67f09SDavid van Moolenbroek  * SUCH DAMAGE.
56*00b67f09SDavid van Moolenbroek  *
57*00b67f09SDavid van Moolenbroek  */
58*00b67f09SDavid van Moolenbroek 
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek #include <config.h>
61*00b67f09SDavid van Moolenbroek 
62*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
63*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
64*00b67f09SDavid van Moolenbroek #include <isc/sha2.h>
65*00b67f09SDavid van Moolenbroek #include <isc/string.h>
66*00b67f09SDavid van Moolenbroek #include <isc/util.h>
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek #if PKCS11CRYPTO
69*00b67f09SDavid van Moolenbroek #include <pk11/internal.h>
70*00b67f09SDavid van Moolenbroek #include <pk11/pk11.h>
71*00b67f09SDavid van Moolenbroek #endif
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
74*00b67f09SDavid van Moolenbroek 
75*00b67f09SDavid van Moolenbroek void
isc_sha224_init(isc_sha224_t * context)76*00b67f09SDavid van Moolenbroek isc_sha224_init(isc_sha224_t *context) {
77*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha224_t *)0) {
78*00b67f09SDavid van Moolenbroek 		return;
79*00b67f09SDavid van Moolenbroek 	}
80*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha224()) == 1);
81*00b67f09SDavid van Moolenbroek }
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek void
isc_sha224_invalidate(isc_sha224_t * context)84*00b67f09SDavid van Moolenbroek isc_sha224_invalidate(isc_sha224_t *context) {
85*00b67f09SDavid van Moolenbroek 	EVP_MD_CTX_cleanup(context);
86*00b67f09SDavid van Moolenbroek }
87*00b67f09SDavid van Moolenbroek 
88*00b67f09SDavid van Moolenbroek void
isc_sha224_update(isc_sha224_t * context,const isc_uint8_t * data,size_t len)89*00b67f09SDavid van Moolenbroek isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
90*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
91*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
92*00b67f09SDavid van Moolenbroek 		return;
93*00b67f09SDavid van Moolenbroek 	}
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
96*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0);
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestUpdate(context,
99*00b67f09SDavid van Moolenbroek 				       (const void *) data, len) == 1);
100*00b67f09SDavid van Moolenbroek }
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek void
isc_sha224_final(isc_uint8_t digest[],isc_sha224_t * context)103*00b67f09SDavid van Moolenbroek isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
104*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
105*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha224_t *)0);
106*00b67f09SDavid van Moolenbroek 
107*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
108*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
109*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1);
110*00b67f09SDavid van Moolenbroek 	} else {
111*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
112*00b67f09SDavid van Moolenbroek 	}
113*00b67f09SDavid van Moolenbroek }
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek void
isc_sha256_init(isc_sha256_t * context)116*00b67f09SDavid van Moolenbroek isc_sha256_init(isc_sha256_t *context) {
117*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha256_t *)0) {
118*00b67f09SDavid van Moolenbroek 		return;
119*00b67f09SDavid van Moolenbroek 	}
120*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha256()) == 1);
121*00b67f09SDavid van Moolenbroek }
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek void
isc_sha256_invalidate(isc_sha256_t * context)124*00b67f09SDavid van Moolenbroek isc_sha256_invalidate(isc_sha256_t *context) {
125*00b67f09SDavid van Moolenbroek 	EVP_MD_CTX_cleanup(context);
126*00b67f09SDavid van Moolenbroek }
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek void
isc_sha256_update(isc_sha256_t * context,const isc_uint8_t * data,size_t len)129*00b67f09SDavid van Moolenbroek isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
130*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
131*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
132*00b67f09SDavid van Moolenbroek 		return;
133*00b67f09SDavid van Moolenbroek 	}
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
136*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
137*00b67f09SDavid van Moolenbroek 
138*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestUpdate(context,
139*00b67f09SDavid van Moolenbroek 				       (const void *) data, len) == 1);
140*00b67f09SDavid van Moolenbroek }
141*00b67f09SDavid van Moolenbroek 
142*00b67f09SDavid van Moolenbroek void
isc_sha256_final(isc_uint8_t digest[],isc_sha256_t * context)143*00b67f09SDavid van Moolenbroek isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
144*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
145*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0);
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
148*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
149*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1);
150*00b67f09SDavid van Moolenbroek 	} else {
151*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
152*00b67f09SDavid van Moolenbroek 	}
153*00b67f09SDavid van Moolenbroek }
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek void
isc_sha512_init(isc_sha512_t * context)156*00b67f09SDavid van Moolenbroek isc_sha512_init(isc_sha512_t *context) {
157*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha512_t *)0) {
158*00b67f09SDavid van Moolenbroek 		return;
159*00b67f09SDavid van Moolenbroek 	}
160*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha512()) == 1);
161*00b67f09SDavid van Moolenbroek }
162*00b67f09SDavid van Moolenbroek 
163*00b67f09SDavid van Moolenbroek void
isc_sha512_invalidate(isc_sha512_t * context)164*00b67f09SDavid van Moolenbroek isc_sha512_invalidate(isc_sha512_t *context) {
165*00b67f09SDavid van Moolenbroek 	EVP_MD_CTX_cleanup(context);
166*00b67f09SDavid van Moolenbroek }
167*00b67f09SDavid van Moolenbroek 
isc_sha512_update(isc_sha512_t * context,const isc_uint8_t * data,size_t len)168*00b67f09SDavid van Moolenbroek void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
169*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
170*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
171*00b67f09SDavid van Moolenbroek 		return;
172*00b67f09SDavid van Moolenbroek 	}
173*00b67f09SDavid van Moolenbroek 
174*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
175*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestUpdate(context,
178*00b67f09SDavid van Moolenbroek 				       (const void *) data, len) == 1);
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek 
isc_sha512_final(isc_uint8_t digest[],isc_sha512_t * context)181*00b67f09SDavid van Moolenbroek void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
182*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
183*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0);
184*00b67f09SDavid van Moolenbroek 
185*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
186*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
187*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1);
188*00b67f09SDavid van Moolenbroek 	} else {
189*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
190*00b67f09SDavid van Moolenbroek 	}
191*00b67f09SDavid van Moolenbroek }
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek void
isc_sha384_init(isc_sha384_t * context)194*00b67f09SDavid van Moolenbroek isc_sha384_init(isc_sha384_t *context) {
195*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha384_t *)0) {
196*00b67f09SDavid van Moolenbroek 		return;
197*00b67f09SDavid van Moolenbroek 	}
198*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha384()) == 1);
199*00b67f09SDavid van Moolenbroek }
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek void
isc_sha384_invalidate(isc_sha384_t * context)202*00b67f09SDavid van Moolenbroek isc_sha384_invalidate(isc_sha384_t *context) {
203*00b67f09SDavid van Moolenbroek 	EVP_MD_CTX_cleanup(context);
204*00b67f09SDavid van Moolenbroek }
205*00b67f09SDavid van Moolenbroek 
206*00b67f09SDavid van Moolenbroek void
isc_sha384_update(isc_sha384_t * context,const isc_uint8_t * data,size_t len)207*00b67f09SDavid van Moolenbroek isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
208*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
209*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
210*00b67f09SDavid van Moolenbroek 		return;
211*00b67f09SDavid van Moolenbroek 	}
212*00b67f09SDavid van Moolenbroek 
213*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
214*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
215*00b67f09SDavid van Moolenbroek 
216*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(EVP_DigestUpdate(context,
217*00b67f09SDavid van Moolenbroek 				       (const void *) data, len) == 1);
218*00b67f09SDavid van Moolenbroek }
219*00b67f09SDavid van Moolenbroek 
220*00b67f09SDavid van Moolenbroek void
isc_sha384_final(isc_uint8_t digest[],isc_sha384_t * context)221*00b67f09SDavid van Moolenbroek isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
222*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
223*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha384_t *)0);
224*00b67f09SDavid van Moolenbroek 
225*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
226*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
227*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1);
228*00b67f09SDavid van Moolenbroek 	} else {
229*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
230*00b67f09SDavid van Moolenbroek 	}
231*00b67f09SDavid van Moolenbroek }
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
234*00b67f09SDavid van Moolenbroek 
235*00b67f09SDavid van Moolenbroek void
isc_sha224_init(isc_sha224_t * context)236*00b67f09SDavid van Moolenbroek isc_sha224_init(isc_sha224_t *context) {
237*00b67f09SDavid van Moolenbroek 	CK_RV rv;
238*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA224, NULL, 0 };
239*00b67f09SDavid van Moolenbroek 
240*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha224_t *)0) {
241*00b67f09SDavid van Moolenbroek 		return;
242*00b67f09SDavid van Moolenbroek 	}
243*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE,
244*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
245*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech));
246*00b67f09SDavid van Moolenbroek }
247*00b67f09SDavid van Moolenbroek 
248*00b67f09SDavid van Moolenbroek void
isc_sha224_invalidate(isc_sha224_t * context)249*00b67f09SDavid van Moolenbroek isc_sha224_invalidate(isc_sha224_t *context) {
250*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH];
251*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA224_DIGESTLENGTH;
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	if (context->handle == NULL)
254*00b67f09SDavid van Moolenbroek 		return;
255*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_DigestFinal(context->session, garbage, &len);
256*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
257*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
258*00b67f09SDavid van Moolenbroek }
259*00b67f09SDavid van Moolenbroek 
260*00b67f09SDavid van Moolenbroek void
isc_sha224_update(isc_sha224_t * context,const isc_uint8_t * data,size_t len)261*00b67f09SDavid van Moolenbroek isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
262*00b67f09SDavid van Moolenbroek 	CK_RV rv;
263*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
266*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
267*00b67f09SDavid van Moolenbroek 		return;
268*00b67f09SDavid van Moolenbroek 	}
269*00b67f09SDavid van Moolenbroek 
270*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
271*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0);
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	DE_CONST(data, pPart);
274*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestUpdate,
275*00b67f09SDavid van Moolenbroek 			(context->session, pPart, (CK_ULONG) len));
276*00b67f09SDavid van Moolenbroek }
277*00b67f09SDavid van Moolenbroek 
278*00b67f09SDavid van Moolenbroek void
isc_sha224_final(isc_uint8_t digest[],isc_sha224_t * context)279*00b67f09SDavid van Moolenbroek isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
280*00b67f09SDavid van Moolenbroek 	CK_RV rv;
281*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA224_DIGESTLENGTH;
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
284*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha224_t *)0);
285*00b67f09SDavid van Moolenbroek 
286*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
287*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
288*00b67f09SDavid van Moolenbroek 		PK11_FATALCHECK(pkcs_C_DigestFinal,
289*00b67f09SDavid van Moolenbroek 				(context->session,
290*00b67f09SDavid van Moolenbroek 				 (CK_BYTE_PTR) digest,
291*00b67f09SDavid van Moolenbroek 				 &len));
292*00b67f09SDavid van Moolenbroek 	} else {
293*00b67f09SDavid van Moolenbroek 		CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH];
294*00b67f09SDavid van Moolenbroek 
295*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DigestFinal(context->session, garbage, &len);
296*00b67f09SDavid van Moolenbroek 		memset(garbage, 0, sizeof(garbage));
297*00b67f09SDavid van Moolenbroek 	}
298*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
299*00b67f09SDavid van Moolenbroek }
300*00b67f09SDavid van Moolenbroek 
301*00b67f09SDavid van Moolenbroek void
isc_sha256_init(isc_sha256_t * context)302*00b67f09SDavid van Moolenbroek isc_sha256_init(isc_sha256_t *context) {
303*00b67f09SDavid van Moolenbroek 	CK_RV rv;
304*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA256, NULL, 0 };
305*00b67f09SDavid van Moolenbroek 
306*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha256_t *)0) {
307*00b67f09SDavid van Moolenbroek 		return;
308*00b67f09SDavid van Moolenbroek 	}
309*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE,
310*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
311*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech));
312*00b67f09SDavid van Moolenbroek }
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek void
isc_sha256_invalidate(isc_sha256_t * context)315*00b67f09SDavid van Moolenbroek isc_sha256_invalidate(isc_sha256_t *context) {
316*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH];
317*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA256_DIGESTLENGTH;
318*00b67f09SDavid van Moolenbroek 
319*00b67f09SDavid van Moolenbroek 	if (context->handle == NULL)
320*00b67f09SDavid van Moolenbroek 		return;
321*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_DigestFinal(context->session, garbage, &len);
322*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
323*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
324*00b67f09SDavid van Moolenbroek }
325*00b67f09SDavid van Moolenbroek 
326*00b67f09SDavid van Moolenbroek void
isc_sha256_update(isc_sha256_t * context,const isc_uint8_t * data,size_t len)327*00b67f09SDavid van Moolenbroek isc_sha256_update(isc_sha256_t *context, const isc_uint8_t* data, size_t len) {
328*00b67f09SDavid van Moolenbroek 	CK_RV rv;
329*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
332*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
333*00b67f09SDavid van Moolenbroek 		return;
334*00b67f09SDavid van Moolenbroek 	}
335*00b67f09SDavid van Moolenbroek 
336*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
337*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 	DE_CONST(data, pPart);
340*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestUpdate,
341*00b67f09SDavid van Moolenbroek 			(context->session, pPart, (CK_ULONG) len));
342*00b67f09SDavid van Moolenbroek }
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek void
isc_sha256_final(isc_uint8_t digest[],isc_sha256_t * context)345*00b67f09SDavid van Moolenbroek isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
346*00b67f09SDavid van Moolenbroek 	CK_RV rv;
347*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA256_DIGESTLENGTH;
348*00b67f09SDavid van Moolenbroek 
349*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
350*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0);
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
353*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
354*00b67f09SDavid van Moolenbroek 		PK11_FATALCHECK(pkcs_C_DigestFinal,
355*00b67f09SDavid van Moolenbroek 				(context->session,
356*00b67f09SDavid van Moolenbroek 				 (CK_BYTE_PTR) digest,
357*00b67f09SDavid van Moolenbroek 				 &len));
358*00b67f09SDavid van Moolenbroek 	} else {
359*00b67f09SDavid van Moolenbroek 		CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH];
360*00b67f09SDavid van Moolenbroek 
361*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DigestFinal(context->session, garbage, &len);
362*00b67f09SDavid van Moolenbroek 		memset(garbage, 0, sizeof(garbage));
363*00b67f09SDavid van Moolenbroek 	}
364*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
365*00b67f09SDavid van Moolenbroek }
366*00b67f09SDavid van Moolenbroek 
367*00b67f09SDavid van Moolenbroek void
isc_sha512_init(isc_sha512_t * context)368*00b67f09SDavid van Moolenbroek isc_sha512_init(isc_sha512_t *context) {
369*00b67f09SDavid van Moolenbroek 	CK_RV rv;
370*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA512, NULL, 0 };
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha512_t *)0) {
373*00b67f09SDavid van Moolenbroek 		return;
374*00b67f09SDavid van Moolenbroek 	}
375*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE,
376*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
377*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech));
378*00b67f09SDavid van Moolenbroek }
379*00b67f09SDavid van Moolenbroek 
380*00b67f09SDavid van Moolenbroek void
isc_sha512_invalidate(isc_sha512_t * context)381*00b67f09SDavid van Moolenbroek isc_sha512_invalidate(isc_sha512_t *context) {
382*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
383*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
384*00b67f09SDavid van Moolenbroek 
385*00b67f09SDavid van Moolenbroek 	if (context->handle == NULL)
386*00b67f09SDavid van Moolenbroek 		return;
387*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_DigestFinal(context->session, garbage, &len);
388*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
389*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
390*00b67f09SDavid van Moolenbroek }
391*00b67f09SDavid van Moolenbroek 
392*00b67f09SDavid van Moolenbroek void
isc_sha512_update(isc_sha512_t * context,const isc_uint8_t * data,size_t len)393*00b67f09SDavid van Moolenbroek isc_sha512_update(isc_sha512_t *context, const isc_uint8_t* data, size_t len) {
394*00b67f09SDavid van Moolenbroek 	CK_RV rv;
395*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
396*00b67f09SDavid van Moolenbroek 
397*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
398*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
399*00b67f09SDavid van Moolenbroek 		return;
400*00b67f09SDavid van Moolenbroek 	}
401*00b67f09SDavid van Moolenbroek 
402*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
403*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
404*00b67f09SDavid van Moolenbroek 
405*00b67f09SDavid van Moolenbroek 	DE_CONST(data, pPart);
406*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestUpdate,
407*00b67f09SDavid van Moolenbroek 			(context->session, pPart, (CK_ULONG) len));
408*00b67f09SDavid van Moolenbroek }
409*00b67f09SDavid van Moolenbroek 
410*00b67f09SDavid van Moolenbroek void
isc_sha512_final(isc_uint8_t digest[],isc_sha512_t * context)411*00b67f09SDavid van Moolenbroek isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
412*00b67f09SDavid van Moolenbroek 	CK_RV rv;
413*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
414*00b67f09SDavid van Moolenbroek 
415*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
416*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0);
417*00b67f09SDavid van Moolenbroek 
418*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
419*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
420*00b67f09SDavid van Moolenbroek 		PK11_FATALCHECK(pkcs_C_DigestFinal,
421*00b67f09SDavid van Moolenbroek 				(context->session,
422*00b67f09SDavid van Moolenbroek 				 (CK_BYTE_PTR) digest,
423*00b67f09SDavid van Moolenbroek 				 &len));
424*00b67f09SDavid van Moolenbroek 	} else {
425*00b67f09SDavid van Moolenbroek 		CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
426*00b67f09SDavid van Moolenbroek 
427*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DigestFinal(context->session, garbage, &len);
428*00b67f09SDavid van Moolenbroek 		memset(garbage, 0, sizeof(garbage));
429*00b67f09SDavid van Moolenbroek 	}
430*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
431*00b67f09SDavid van Moolenbroek }
432*00b67f09SDavid van Moolenbroek 
433*00b67f09SDavid van Moolenbroek void
isc_sha384_init(isc_sha384_t * context)434*00b67f09SDavid van Moolenbroek isc_sha384_init(isc_sha384_t *context) {
435*00b67f09SDavid van Moolenbroek 	CK_RV rv;
436*00b67f09SDavid van Moolenbroek 	CK_MECHANISM mech = { CKM_SHA384, NULL, 0 };
437*00b67f09SDavid van Moolenbroek 
438*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha384_t *)0) {
439*00b67f09SDavid van Moolenbroek 		return;
440*00b67f09SDavid van Moolenbroek 	}
441*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE,
442*00b67f09SDavid van Moolenbroek 				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
443*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech));
444*00b67f09SDavid van Moolenbroek }
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek void
isc_sha384_invalidate(isc_sha384_t * context)447*00b67f09SDavid van Moolenbroek isc_sha384_invalidate(isc_sha384_t *context) {
448*00b67f09SDavid van Moolenbroek 	CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH];
449*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA384_DIGESTLENGTH;
450*00b67f09SDavid van Moolenbroek 
451*00b67f09SDavid van Moolenbroek 	if (context->handle == NULL)
452*00b67f09SDavid van Moolenbroek 		return;
453*00b67f09SDavid van Moolenbroek 	(void) pkcs_C_DigestFinal(context->session, garbage, &len);
454*00b67f09SDavid van Moolenbroek 	memset(garbage, 0, sizeof(garbage));
455*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
456*00b67f09SDavid van Moolenbroek }
457*00b67f09SDavid van Moolenbroek 
458*00b67f09SDavid van Moolenbroek void
isc_sha384_update(isc_sha384_t * context,const isc_uint8_t * data,size_t len)459*00b67f09SDavid van Moolenbroek isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
460*00b67f09SDavid van Moolenbroek 	CK_RV rv;
461*00b67f09SDavid van Moolenbroek 	CK_BYTE_PTR pPart;
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
464*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
465*00b67f09SDavid van Moolenbroek 		return;
466*00b67f09SDavid van Moolenbroek 	}
467*00b67f09SDavid van Moolenbroek 
468*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
469*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha384_t *)0 && data != (isc_uint8_t*)0);
470*00b67f09SDavid van Moolenbroek 
471*00b67f09SDavid van Moolenbroek 	DE_CONST(data, pPart);
472*00b67f09SDavid van Moolenbroek 	PK11_FATALCHECK(pkcs_C_DigestUpdate,
473*00b67f09SDavid van Moolenbroek 			(context->session, pPart, (CK_ULONG) len));
474*00b67f09SDavid van Moolenbroek }
475*00b67f09SDavid van Moolenbroek 
476*00b67f09SDavid van Moolenbroek void
isc_sha384_final(isc_uint8_t digest[],isc_sha384_t * context)477*00b67f09SDavid van Moolenbroek isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
478*00b67f09SDavid van Moolenbroek 	CK_RV rv;
479*00b67f09SDavid van Moolenbroek 	CK_ULONG len = ISC_SHA384_DIGESTLENGTH;
480*00b67f09SDavid van Moolenbroek 
481*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
482*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha384_t *)0);
483*00b67f09SDavid van Moolenbroek 
484*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
485*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
486*00b67f09SDavid van Moolenbroek 		PK11_FATALCHECK(pkcs_C_DigestFinal,
487*00b67f09SDavid van Moolenbroek 				(context->session,
488*00b67f09SDavid van Moolenbroek 				 (CK_BYTE_PTR) digest,
489*00b67f09SDavid van Moolenbroek 				 &len));
490*00b67f09SDavid van Moolenbroek 	} else {
491*00b67f09SDavid van Moolenbroek 		CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH];
492*00b67f09SDavid van Moolenbroek 
493*00b67f09SDavid van Moolenbroek 		(void) pkcs_C_DigestFinal(context->session, garbage, &len);
494*00b67f09SDavid van Moolenbroek 		memset(garbage, 0, sizeof(garbage));
495*00b67f09SDavid van Moolenbroek 	}
496*00b67f09SDavid van Moolenbroek 	pk11_return_session(context);
497*00b67f09SDavid van Moolenbroek }
498*00b67f09SDavid van Moolenbroek 
499*00b67f09SDavid van Moolenbroek #else
500*00b67f09SDavid van Moolenbroek 
501*00b67f09SDavid van Moolenbroek /*
502*00b67f09SDavid van Moolenbroek  * UNROLLED TRANSFORM LOOP NOTE:
503*00b67f09SDavid van Moolenbroek  * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
504*00b67f09SDavid van Moolenbroek  * loop version for the hash transform rounds (defined using macros
505*00b67f09SDavid van Moolenbroek  * later in this file).  Either define on the command line, for example:
506*00b67f09SDavid van Moolenbroek  *
507*00b67f09SDavid van Moolenbroek  *   cc -DISC_SHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
508*00b67f09SDavid van Moolenbroek  *
509*00b67f09SDavid van Moolenbroek  * or define below:
510*00b67f09SDavid van Moolenbroek  *
511*00b67f09SDavid van Moolenbroek  *   \#define ISC_SHA2_UNROLL_TRANSFORM
512*00b67f09SDavid van Moolenbroek  *
513*00b67f09SDavid van Moolenbroek  */
514*00b67f09SDavid van Moolenbroek 
515*00b67f09SDavid van Moolenbroek /*** SHA-256/384/512 Machine Architecture Definitions *****************/
516*00b67f09SDavid van Moolenbroek /*
517*00b67f09SDavid van Moolenbroek  * BYTE_ORDER NOTE:
518*00b67f09SDavid van Moolenbroek  *
519*00b67f09SDavid van Moolenbroek  * Please make sure that your system defines BYTE_ORDER.  If your
520*00b67f09SDavid van Moolenbroek  * architecture is little-endian, make sure it also defines
521*00b67f09SDavid van Moolenbroek  * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
522*00b67f09SDavid van Moolenbroek  * equivalent.
523*00b67f09SDavid van Moolenbroek  *
524*00b67f09SDavid van Moolenbroek  * If your system does not define the above, then you can do so by
525*00b67f09SDavid van Moolenbroek  * hand like this:
526*00b67f09SDavid van Moolenbroek  *
527*00b67f09SDavid van Moolenbroek  *   \#define LITTLE_ENDIAN 1234
528*00b67f09SDavid van Moolenbroek  *   \#define BIG_ENDIAN    4321
529*00b67f09SDavid van Moolenbroek  *
530*00b67f09SDavid van Moolenbroek  * And for little-endian machines, add:
531*00b67f09SDavid van Moolenbroek  *
532*00b67f09SDavid van Moolenbroek  *   \#define BYTE_ORDER LITTLE_ENDIAN
533*00b67f09SDavid van Moolenbroek  *
534*00b67f09SDavid van Moolenbroek  * Or for big-endian machines:
535*00b67f09SDavid van Moolenbroek  *
536*00b67f09SDavid van Moolenbroek  *   \#define BYTE_ORDER BIG_ENDIAN
537*00b67f09SDavid van Moolenbroek  *
538*00b67f09SDavid van Moolenbroek  * The FreeBSD machine this was written on defines BYTE_ORDER
539*00b67f09SDavid van Moolenbroek  * appropriately by including <sys/types.h> (which in turn includes
540*00b67f09SDavid van Moolenbroek  * <machine/endian.h> where the appropriate definitions are actually
541*00b67f09SDavid van Moolenbroek  * made).
542*00b67f09SDavid van Moolenbroek  */
543*00b67f09SDavid van Moolenbroek #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
544*00b67f09SDavid van Moolenbroek #ifndef BYTE_ORDER
545*00b67f09SDavid van Moolenbroek #ifndef BIG_ENDIAN
546*00b67f09SDavid van Moolenbroek #define BIG_ENDIAN 4321
547*00b67f09SDavid van Moolenbroek #endif
548*00b67f09SDavid van Moolenbroek #ifndef LITTLE_ENDIAN
549*00b67f09SDavid van Moolenbroek #define LITTLE_ENDIAN 1234
550*00b67f09SDavid van Moolenbroek #endif
551*00b67f09SDavid van Moolenbroek #ifdef WORDS_BIGENDIAN
552*00b67f09SDavid van Moolenbroek #define BYTE_ORDER BIG_ENDIAN
553*00b67f09SDavid van Moolenbroek #else
554*00b67f09SDavid van Moolenbroek #define BYTE_ORDER LITTLE_ENDIAN
555*00b67f09SDavid van Moolenbroek #endif
556*00b67f09SDavid van Moolenbroek #else
557*00b67f09SDavid van Moolenbroek #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
558*00b67f09SDavid van Moolenbroek #endif
559*00b67f09SDavid van Moolenbroek #endif
560*00b67f09SDavid van Moolenbroek 
561*00b67f09SDavid van Moolenbroek /*** SHA-256/384/512 Various Length Definitions ***********************/
562*00b67f09SDavid van Moolenbroek /* NOTE: Most of these are in sha2.h */
563*00b67f09SDavid van Moolenbroek #define ISC_SHA256_SHORT_BLOCK_LENGTH	(ISC_SHA256_BLOCK_LENGTH - 8)
564*00b67f09SDavid van Moolenbroek #define ISC_SHA384_SHORT_BLOCK_LENGTH	(ISC_SHA384_BLOCK_LENGTH - 16)
565*00b67f09SDavid van Moolenbroek #define ISC_SHA512_SHORT_BLOCK_LENGTH	(ISC_SHA512_BLOCK_LENGTH - 16)
566*00b67f09SDavid van Moolenbroek 
567*00b67f09SDavid van Moolenbroek 
568*00b67f09SDavid van Moolenbroek /*** ENDIAN REVERSAL MACROS *******************************************/
569*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
570*00b67f09SDavid van Moolenbroek #define REVERSE32(w,x)	{ \
571*00b67f09SDavid van Moolenbroek 	isc_uint32_t tmp = (w); \
572*00b67f09SDavid van Moolenbroek 	tmp = (tmp >> 16) | (tmp << 16); \
573*00b67f09SDavid van Moolenbroek 	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
574*00b67f09SDavid van Moolenbroek }
575*00b67f09SDavid van Moolenbroek #ifdef WIN32
576*00b67f09SDavid van Moolenbroek #define REVERSE64(w,x)	{ \
577*00b67f09SDavid van Moolenbroek 	isc_uint64_t tmp = (w); \
578*00b67f09SDavid van Moolenbroek 	tmp = (tmp >> 32) | (tmp << 32); \
579*00b67f09SDavid van Moolenbroek 	tmp = ((tmp & 0xff00ff00ff00ff00UL) >> 8) | \
580*00b67f09SDavid van Moolenbroek 	      ((tmp & 0x00ff00ff00ff00ffUL) << 8); \
581*00b67f09SDavid van Moolenbroek 	(x) = ((tmp & 0xffff0000ffff0000UL) >> 16) | \
582*00b67f09SDavid van Moolenbroek 	      ((tmp & 0x0000ffff0000ffffUL) << 16); \
583*00b67f09SDavid van Moolenbroek }
584*00b67f09SDavid van Moolenbroek #else
585*00b67f09SDavid van Moolenbroek #define REVERSE64(w,x)	{ \
586*00b67f09SDavid van Moolenbroek 	isc_uint64_t tmp = (w); \
587*00b67f09SDavid van Moolenbroek 	tmp = (tmp >> 32) | (tmp << 32); \
588*00b67f09SDavid van Moolenbroek 	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
589*00b67f09SDavid van Moolenbroek 	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
590*00b67f09SDavid van Moolenbroek 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
591*00b67f09SDavid van Moolenbroek 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
592*00b67f09SDavid van Moolenbroek }
593*00b67f09SDavid van Moolenbroek #endif
594*00b67f09SDavid van Moolenbroek #endif /* BYTE_ORDER == LITTLE_ENDIAN */
595*00b67f09SDavid van Moolenbroek 
596*00b67f09SDavid van Moolenbroek /*
597*00b67f09SDavid van Moolenbroek  * Macro for incrementally adding the unsigned 64-bit integer n to the
598*00b67f09SDavid van Moolenbroek  * unsigned 128-bit integer (represented using a two-element array of
599*00b67f09SDavid van Moolenbroek  * 64-bit words):
600*00b67f09SDavid van Moolenbroek  */
601*00b67f09SDavid van Moolenbroek #define ADDINC128(w,n)	{ \
602*00b67f09SDavid van Moolenbroek 	(w)[0] += (isc_uint64_t)(n); \
603*00b67f09SDavid van Moolenbroek 	if ((w)[0] < (n)) { \
604*00b67f09SDavid van Moolenbroek 		(w)[1]++; \
605*00b67f09SDavid van Moolenbroek 	} \
606*00b67f09SDavid van Moolenbroek }
607*00b67f09SDavid van Moolenbroek 
608*00b67f09SDavid van Moolenbroek /*** THE SIX LOGICAL FUNCTIONS ****************************************/
609*00b67f09SDavid van Moolenbroek /*
610*00b67f09SDavid van Moolenbroek  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
611*00b67f09SDavid van Moolenbroek  *
612*00b67f09SDavid van Moolenbroek  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
613*00b67f09SDavid van Moolenbroek  *   S is a ROTATION) because the SHA-256/384/512 description document
614*00b67f09SDavid van Moolenbroek  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
615*00b67f09SDavid van Moolenbroek  *   same "backwards" definition.
616*00b67f09SDavid van Moolenbroek  */
617*00b67f09SDavid van Moolenbroek /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
618*00b67f09SDavid van Moolenbroek #define R(b,x) 		((x) >> (b))
619*00b67f09SDavid van Moolenbroek /* 32-bit Rotate-right (used in SHA-256): */
620*00b67f09SDavid van Moolenbroek #define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
621*00b67f09SDavid van Moolenbroek /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
622*00b67f09SDavid van Moolenbroek #define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
623*00b67f09SDavid van Moolenbroek 
624*00b67f09SDavid van Moolenbroek /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
625*00b67f09SDavid van Moolenbroek #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
626*00b67f09SDavid van Moolenbroek #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
627*00b67f09SDavid van Moolenbroek 
628*00b67f09SDavid van Moolenbroek /* Four of six logical functions used in SHA-256: */
629*00b67f09SDavid van Moolenbroek #define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
630*00b67f09SDavid van Moolenbroek #define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
631*00b67f09SDavid van Moolenbroek #define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
632*00b67f09SDavid van Moolenbroek #define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
633*00b67f09SDavid van Moolenbroek 
634*00b67f09SDavid van Moolenbroek /* Four of six logical functions used in SHA-384 and SHA-512: */
635*00b67f09SDavid van Moolenbroek #define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
636*00b67f09SDavid van Moolenbroek #define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
637*00b67f09SDavid van Moolenbroek #define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
638*00b67f09SDavid van Moolenbroek #define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
639*00b67f09SDavid van Moolenbroek 
640*00b67f09SDavid van Moolenbroek /*** INTERNAL FUNCTION PROTOTYPES *************************************/
641*00b67f09SDavid van Moolenbroek /* NOTE: These should not be accessed directly from outside this
642*00b67f09SDavid van Moolenbroek  * library -- they are intended for private internal visibility/use
643*00b67f09SDavid van Moolenbroek  * only.
644*00b67f09SDavid van Moolenbroek  */
645*00b67f09SDavid van Moolenbroek void isc_sha512_last(isc_sha512_t *);
646*00b67f09SDavid van Moolenbroek void isc_sha256_transform(isc_sha256_t *, const isc_uint32_t*);
647*00b67f09SDavid van Moolenbroek void isc_sha512_transform(isc_sha512_t *, const isc_uint64_t*);
648*00b67f09SDavid van Moolenbroek 
649*00b67f09SDavid van Moolenbroek 
650*00b67f09SDavid van Moolenbroek /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
651*00b67f09SDavid van Moolenbroek /* Hash constant words K for SHA-224 and SHA-256: */
652*00b67f09SDavid van Moolenbroek static const isc_uint32_t K256[64] = {
653*00b67f09SDavid van Moolenbroek 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
654*00b67f09SDavid van Moolenbroek 	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
655*00b67f09SDavid van Moolenbroek 	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
656*00b67f09SDavid van Moolenbroek 	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
657*00b67f09SDavid van Moolenbroek 	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
658*00b67f09SDavid van Moolenbroek 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
659*00b67f09SDavid van Moolenbroek 	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
660*00b67f09SDavid van Moolenbroek 	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
661*00b67f09SDavid van Moolenbroek 	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
662*00b67f09SDavid van Moolenbroek 	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
663*00b67f09SDavid van Moolenbroek 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
664*00b67f09SDavid van Moolenbroek 	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
665*00b67f09SDavid van Moolenbroek 	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
666*00b67f09SDavid van Moolenbroek 	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
667*00b67f09SDavid van Moolenbroek 	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
668*00b67f09SDavid van Moolenbroek 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
669*00b67f09SDavid van Moolenbroek };
670*00b67f09SDavid van Moolenbroek 
671*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-224: */
672*00b67f09SDavid van Moolenbroek static const isc_uint32_t sha224_initial_hash_value[8] = {
673*00b67f09SDavid van Moolenbroek 	0xc1059ed8UL,
674*00b67f09SDavid van Moolenbroek 	0x367cd507UL,
675*00b67f09SDavid van Moolenbroek 	0x3070dd17UL,
676*00b67f09SDavid van Moolenbroek 	0xf70e5939UL,
677*00b67f09SDavid van Moolenbroek 	0xffc00b31UL,
678*00b67f09SDavid van Moolenbroek 	0x68581511UL,
679*00b67f09SDavid van Moolenbroek 	0x64f98fa7UL,
680*00b67f09SDavid van Moolenbroek 	0xbefa4fa4UL
681*00b67f09SDavid van Moolenbroek };
682*00b67f09SDavid van Moolenbroek 
683*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-256: */
684*00b67f09SDavid van Moolenbroek static const isc_uint32_t sha256_initial_hash_value[8] = {
685*00b67f09SDavid van Moolenbroek 	0x6a09e667UL,
686*00b67f09SDavid van Moolenbroek 	0xbb67ae85UL,
687*00b67f09SDavid van Moolenbroek 	0x3c6ef372UL,
688*00b67f09SDavid van Moolenbroek 	0xa54ff53aUL,
689*00b67f09SDavid van Moolenbroek 	0x510e527fUL,
690*00b67f09SDavid van Moolenbroek 	0x9b05688cUL,
691*00b67f09SDavid van Moolenbroek 	0x1f83d9abUL,
692*00b67f09SDavid van Moolenbroek 	0x5be0cd19UL
693*00b67f09SDavid van Moolenbroek };
694*00b67f09SDavid van Moolenbroek 
695*00b67f09SDavid van Moolenbroek #ifdef WIN32
696*00b67f09SDavid van Moolenbroek /* Hash constant words K for SHA-384 and SHA-512: */
697*00b67f09SDavid van Moolenbroek static const isc_uint64_t K512[80] = {
698*00b67f09SDavid van Moolenbroek 	0x428a2f98d728ae22UL, 0x7137449123ef65cdUL,
699*00b67f09SDavid van Moolenbroek 	0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL,
700*00b67f09SDavid van Moolenbroek 	0x3956c25bf348b538UL, 0x59f111f1b605d019UL,
701*00b67f09SDavid van Moolenbroek 	0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL,
702*00b67f09SDavid van Moolenbroek 	0xd807aa98a3030242UL, 0x12835b0145706fbeUL,
703*00b67f09SDavid van Moolenbroek 	0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL,
704*00b67f09SDavid van Moolenbroek 	0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL,
705*00b67f09SDavid van Moolenbroek 	0x9bdc06a725c71235UL, 0xc19bf174cf692694UL,
706*00b67f09SDavid van Moolenbroek 	0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL,
707*00b67f09SDavid van Moolenbroek 	0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL,
708*00b67f09SDavid van Moolenbroek 	0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL,
709*00b67f09SDavid van Moolenbroek 	0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL,
710*00b67f09SDavid van Moolenbroek 	0x983e5152ee66dfabUL, 0xa831c66d2db43210UL,
711*00b67f09SDavid van Moolenbroek 	0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL,
712*00b67f09SDavid van Moolenbroek 	0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL,
713*00b67f09SDavid van Moolenbroek 	0x06ca6351e003826fUL, 0x142929670a0e6e70UL,
714*00b67f09SDavid van Moolenbroek 	0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL,
715*00b67f09SDavid van Moolenbroek 	0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL,
716*00b67f09SDavid van Moolenbroek 	0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL,
717*00b67f09SDavid van Moolenbroek 	0x81c2c92e47edaee6UL, 0x92722c851482353bUL,
718*00b67f09SDavid van Moolenbroek 	0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL,
719*00b67f09SDavid van Moolenbroek 	0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL,
720*00b67f09SDavid van Moolenbroek 	0xd192e819d6ef5218UL, 0xd69906245565a910UL,
721*00b67f09SDavid van Moolenbroek 	0xf40e35855771202aUL, 0x106aa07032bbd1b8UL,
722*00b67f09SDavid van Moolenbroek 	0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL,
723*00b67f09SDavid van Moolenbroek 	0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL,
724*00b67f09SDavid van Moolenbroek 	0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL,
725*00b67f09SDavid van Moolenbroek 	0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL,
726*00b67f09SDavid van Moolenbroek 	0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL,
727*00b67f09SDavid van Moolenbroek 	0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL,
728*00b67f09SDavid van Moolenbroek 	0x90befffa23631e28UL, 0xa4506cebde82bde9UL,
729*00b67f09SDavid van Moolenbroek 	0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL,
730*00b67f09SDavid van Moolenbroek 	0xca273eceea26619cUL, 0xd186b8c721c0c207UL,
731*00b67f09SDavid van Moolenbroek 	0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL,
732*00b67f09SDavid van Moolenbroek 	0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL,
733*00b67f09SDavid van Moolenbroek 	0x113f9804bef90daeUL, 0x1b710b35131c471bUL,
734*00b67f09SDavid van Moolenbroek 	0x28db77f523047d84UL, 0x32caab7b40c72493UL,
735*00b67f09SDavid van Moolenbroek 	0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL,
736*00b67f09SDavid van Moolenbroek 	0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL,
737*00b67f09SDavid van Moolenbroek 	0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL
738*00b67f09SDavid van Moolenbroek };
739*00b67f09SDavid van Moolenbroek 
740*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-384: */
741*00b67f09SDavid van Moolenbroek static const isc_uint64_t sha384_initial_hash_value[8] = {
742*00b67f09SDavid van Moolenbroek 	0xcbbb9d5dc1059ed8UL,
743*00b67f09SDavid van Moolenbroek 	0x629a292a367cd507UL,
744*00b67f09SDavid van Moolenbroek 	0x9159015a3070dd17UL,
745*00b67f09SDavid van Moolenbroek 	0x152fecd8f70e5939UL,
746*00b67f09SDavid van Moolenbroek 	0x67332667ffc00b31UL,
747*00b67f09SDavid van Moolenbroek 	0x8eb44a8768581511UL,
748*00b67f09SDavid van Moolenbroek 	0xdb0c2e0d64f98fa7UL,
749*00b67f09SDavid van Moolenbroek 	0x47b5481dbefa4fa4UL
750*00b67f09SDavid van Moolenbroek };
751*00b67f09SDavid van Moolenbroek 
752*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-512: */
753*00b67f09SDavid van Moolenbroek static const isc_uint64_t sha512_initial_hash_value[8] = {
754*00b67f09SDavid van Moolenbroek 	0x6a09e667f3bcc908U,
755*00b67f09SDavid van Moolenbroek 	0xbb67ae8584caa73bUL,
756*00b67f09SDavid van Moolenbroek 	0x3c6ef372fe94f82bUL,
757*00b67f09SDavid van Moolenbroek 	0xa54ff53a5f1d36f1UL,
758*00b67f09SDavid van Moolenbroek 	0x510e527fade682d1UL,
759*00b67f09SDavid van Moolenbroek 	0x9b05688c2b3e6c1fUL,
760*00b67f09SDavid van Moolenbroek 	0x1f83d9abfb41bd6bUL,
761*00b67f09SDavid van Moolenbroek 	0x5be0cd19137e2179UL
762*00b67f09SDavid van Moolenbroek };
763*00b67f09SDavid van Moolenbroek #else
764*00b67f09SDavid van Moolenbroek /* Hash constant words K for SHA-384 and SHA-512: */
765*00b67f09SDavid van Moolenbroek static const isc_uint64_t K512[80] = {
766*00b67f09SDavid van Moolenbroek 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
767*00b67f09SDavid van Moolenbroek 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
768*00b67f09SDavid van Moolenbroek 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
769*00b67f09SDavid van Moolenbroek 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
770*00b67f09SDavid van Moolenbroek 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
771*00b67f09SDavid van Moolenbroek 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
772*00b67f09SDavid van Moolenbroek 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
773*00b67f09SDavid van Moolenbroek 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
774*00b67f09SDavid van Moolenbroek 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
775*00b67f09SDavid van Moolenbroek 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
776*00b67f09SDavid van Moolenbroek 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
777*00b67f09SDavid van Moolenbroek 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
778*00b67f09SDavid van Moolenbroek 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
779*00b67f09SDavid van Moolenbroek 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
780*00b67f09SDavid van Moolenbroek 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
781*00b67f09SDavid van Moolenbroek 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
782*00b67f09SDavid van Moolenbroek 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
783*00b67f09SDavid van Moolenbroek 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
784*00b67f09SDavid van Moolenbroek 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
785*00b67f09SDavid van Moolenbroek 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
786*00b67f09SDavid van Moolenbroek 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
787*00b67f09SDavid van Moolenbroek 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
788*00b67f09SDavid van Moolenbroek 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
789*00b67f09SDavid van Moolenbroek 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
790*00b67f09SDavid van Moolenbroek 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
791*00b67f09SDavid van Moolenbroek 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
792*00b67f09SDavid van Moolenbroek 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
793*00b67f09SDavid van Moolenbroek 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
794*00b67f09SDavid van Moolenbroek 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
795*00b67f09SDavid van Moolenbroek 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
796*00b67f09SDavid van Moolenbroek 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
797*00b67f09SDavid van Moolenbroek 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
798*00b67f09SDavid van Moolenbroek 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
799*00b67f09SDavid van Moolenbroek 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
800*00b67f09SDavid van Moolenbroek 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
801*00b67f09SDavid van Moolenbroek 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
802*00b67f09SDavid van Moolenbroek 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
803*00b67f09SDavid van Moolenbroek 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
804*00b67f09SDavid van Moolenbroek 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
805*00b67f09SDavid van Moolenbroek 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
806*00b67f09SDavid van Moolenbroek };
807*00b67f09SDavid van Moolenbroek 
808*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-384: */
809*00b67f09SDavid van Moolenbroek static const isc_uint64_t sha384_initial_hash_value[8] = {
810*00b67f09SDavid van Moolenbroek 	0xcbbb9d5dc1059ed8ULL,
811*00b67f09SDavid van Moolenbroek 	0x629a292a367cd507ULL,
812*00b67f09SDavid van Moolenbroek 	0x9159015a3070dd17ULL,
813*00b67f09SDavid van Moolenbroek 	0x152fecd8f70e5939ULL,
814*00b67f09SDavid van Moolenbroek 	0x67332667ffc00b31ULL,
815*00b67f09SDavid van Moolenbroek 	0x8eb44a8768581511ULL,
816*00b67f09SDavid van Moolenbroek 	0xdb0c2e0d64f98fa7ULL,
817*00b67f09SDavid van Moolenbroek 	0x47b5481dbefa4fa4ULL
818*00b67f09SDavid van Moolenbroek };
819*00b67f09SDavid van Moolenbroek 
820*00b67f09SDavid van Moolenbroek /* Initial hash value H for SHA-512: */
821*00b67f09SDavid van Moolenbroek static const isc_uint64_t sha512_initial_hash_value[8] = {
822*00b67f09SDavid van Moolenbroek 	0x6a09e667f3bcc908ULL,
823*00b67f09SDavid van Moolenbroek 	0xbb67ae8584caa73bULL,
824*00b67f09SDavid van Moolenbroek 	0x3c6ef372fe94f82bULL,
825*00b67f09SDavid van Moolenbroek 	0xa54ff53a5f1d36f1ULL,
826*00b67f09SDavid van Moolenbroek 	0x510e527fade682d1ULL,
827*00b67f09SDavid van Moolenbroek 	0x9b05688c2b3e6c1fULL,
828*00b67f09SDavid van Moolenbroek 	0x1f83d9abfb41bd6bULL,
829*00b67f09SDavid van Moolenbroek 	0x5be0cd19137e2179ULL
830*00b67f09SDavid van Moolenbroek };
831*00b67f09SDavid van Moolenbroek #endif
832*00b67f09SDavid van Moolenbroek 
833*00b67f09SDavid van Moolenbroek 
834*00b67f09SDavid van Moolenbroek /*** SHA-224: *********************************************************/
835*00b67f09SDavid van Moolenbroek void
isc_sha224_init(isc_sha224_t * context)836*00b67f09SDavid van Moolenbroek isc_sha224_init(isc_sha224_t *context) {
837*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha256_t *)0) {
838*00b67f09SDavid van Moolenbroek 		return;
839*00b67f09SDavid van Moolenbroek 	}
840*00b67f09SDavid van Moolenbroek 	memmove(context->state, sha224_initial_hash_value,
841*00b67f09SDavid van Moolenbroek 		ISC_SHA256_DIGESTLENGTH);
842*00b67f09SDavid van Moolenbroek 	memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH);
843*00b67f09SDavid van Moolenbroek 	context->bitcount = 0;
844*00b67f09SDavid van Moolenbroek }
845*00b67f09SDavid van Moolenbroek 
846*00b67f09SDavid van Moolenbroek void
isc_sha224_invalidate(isc_sha224_t * context)847*00b67f09SDavid van Moolenbroek isc_sha224_invalidate(isc_sha224_t *context) {
848*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(isc_sha224_t));
849*00b67f09SDavid van Moolenbroek }
850*00b67f09SDavid van Moolenbroek 
851*00b67f09SDavid van Moolenbroek void
isc_sha224_update(isc_sha224_t * context,const isc_uint8_t * data,size_t len)852*00b67f09SDavid van Moolenbroek isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
853*00b67f09SDavid van Moolenbroek 	isc_sha256_update((isc_sha256_t *)context, data, len);
854*00b67f09SDavid van Moolenbroek }
855*00b67f09SDavid van Moolenbroek 
856*00b67f09SDavid van Moolenbroek void
isc_sha224_final(isc_uint8_t digest[],isc_sha224_t * context)857*00b67f09SDavid van Moolenbroek isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
858*00b67f09SDavid van Moolenbroek 	isc_uint8_t sha256_digest[ISC_SHA256_DIGESTLENGTH];
859*00b67f09SDavid van Moolenbroek 	isc_sha256_final(sha256_digest, (isc_sha256_t *)context);
860*00b67f09SDavid van Moolenbroek 	memmove(digest, sha256_digest, ISC_SHA224_DIGESTLENGTH);
861*00b67f09SDavid van Moolenbroek 	memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH);
862*00b67f09SDavid van Moolenbroek }
863*00b67f09SDavid van Moolenbroek 
864*00b67f09SDavid van Moolenbroek /*** SHA-256: *********************************************************/
865*00b67f09SDavid van Moolenbroek void
isc_sha256_init(isc_sha256_t * context)866*00b67f09SDavid van Moolenbroek isc_sha256_init(isc_sha256_t *context) {
867*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha256_t *)0) {
868*00b67f09SDavid van Moolenbroek 		return;
869*00b67f09SDavid van Moolenbroek 	}
870*00b67f09SDavid van Moolenbroek 	memmove(context->state, sha256_initial_hash_value,
871*00b67f09SDavid van Moolenbroek 	       ISC_SHA256_DIGESTLENGTH);
872*00b67f09SDavid van Moolenbroek 	memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH);
873*00b67f09SDavid van Moolenbroek 	context->bitcount = 0;
874*00b67f09SDavid van Moolenbroek }
875*00b67f09SDavid van Moolenbroek 
876*00b67f09SDavid van Moolenbroek void
isc_sha256_invalidate(isc_sha256_t * context)877*00b67f09SDavid van Moolenbroek isc_sha256_invalidate(isc_sha256_t *context) {
878*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(isc_sha256_t));
879*00b67f09SDavid van Moolenbroek }
880*00b67f09SDavid van Moolenbroek 
881*00b67f09SDavid van Moolenbroek #ifdef ISC_SHA2_UNROLL_TRANSFORM
882*00b67f09SDavid van Moolenbroek 
883*00b67f09SDavid van Moolenbroek /* Unrolled SHA-256 round macros: */
884*00b67f09SDavid van Moolenbroek 
885*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
886*00b67f09SDavid van Moolenbroek 
887*00b67f09SDavid van Moolenbroek #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
888*00b67f09SDavid van Moolenbroek 	REVERSE32(*data++, W256[j]); \
889*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
890*00b67f09SDavid van Moolenbroek 	     K256[j] + W256[j]; \
891*00b67f09SDavid van Moolenbroek 	(d) += T1; \
892*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
893*00b67f09SDavid van Moolenbroek 	j++
894*00b67f09SDavid van Moolenbroek 
895*00b67f09SDavid van Moolenbroek 
896*00b67f09SDavid van Moolenbroek #else /* BYTE_ORDER == LITTLE_ENDIAN */
897*00b67f09SDavid van Moolenbroek 
898*00b67f09SDavid van Moolenbroek #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
899*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
900*00b67f09SDavid van Moolenbroek 	     K256[j] + (W256[j] = *data++); \
901*00b67f09SDavid van Moolenbroek 	(d) += T1; \
902*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
903*00b67f09SDavid van Moolenbroek 	j++
904*00b67f09SDavid van Moolenbroek 
905*00b67f09SDavid van Moolenbroek #endif /* BYTE_ORDER == LITTLE_ENDIAN */
906*00b67f09SDavid van Moolenbroek 
907*00b67f09SDavid van Moolenbroek #define ROUND256(a,b,c,d,e,f,g,h)	\
908*00b67f09SDavid van Moolenbroek 	s0 = W256[(j+1)&0x0f]; \
909*00b67f09SDavid van Moolenbroek 	s0 = sigma0_256(s0); \
910*00b67f09SDavid van Moolenbroek 	s1 = W256[(j+14)&0x0f]; \
911*00b67f09SDavid van Moolenbroek 	s1 = sigma1_256(s1); \
912*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
913*00b67f09SDavid van Moolenbroek 	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
914*00b67f09SDavid van Moolenbroek 	(d) += T1; \
915*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
916*00b67f09SDavid van Moolenbroek 	j++
917*00b67f09SDavid van Moolenbroek 
isc_sha256_transform(isc_sha256_t * context,const isc_uint32_t * data)918*00b67f09SDavid van Moolenbroek void isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
919*00b67f09SDavid van Moolenbroek 	isc_uint32_t	a, b, c, d, e, f, g, h, s0, s1;
920*00b67f09SDavid van Moolenbroek 	isc_uint32_t	T1, *W256;
921*00b67f09SDavid van Moolenbroek 	int		j;
922*00b67f09SDavid van Moolenbroek 
923*00b67f09SDavid van Moolenbroek 	W256 = (isc_uint32_t*)context->buffer;
924*00b67f09SDavid van Moolenbroek 
925*00b67f09SDavid van Moolenbroek 	/* Initialize registers with the prev. intermediate value */
926*00b67f09SDavid van Moolenbroek 	a = context->state[0];
927*00b67f09SDavid van Moolenbroek 	b = context->state[1];
928*00b67f09SDavid van Moolenbroek 	c = context->state[2];
929*00b67f09SDavid van Moolenbroek 	d = context->state[3];
930*00b67f09SDavid van Moolenbroek 	e = context->state[4];
931*00b67f09SDavid van Moolenbroek 	f = context->state[5];
932*00b67f09SDavid van Moolenbroek 	g = context->state[6];
933*00b67f09SDavid van Moolenbroek 	h = context->state[7];
934*00b67f09SDavid van Moolenbroek 
935*00b67f09SDavid van Moolenbroek 	j = 0;
936*00b67f09SDavid van Moolenbroek 	do {
937*00b67f09SDavid van Moolenbroek 		/* Rounds 0 to 15 (unrolled): */
938*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
939*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
940*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
941*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
942*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
943*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
944*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
945*00b67f09SDavid van Moolenbroek 		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
946*00b67f09SDavid van Moolenbroek 	} while (j < 16);
947*00b67f09SDavid van Moolenbroek 
948*00b67f09SDavid van Moolenbroek 	/* Now for the remaining rounds to 64: */
949*00b67f09SDavid van Moolenbroek 	do {
950*00b67f09SDavid van Moolenbroek 		ROUND256(a,b,c,d,e,f,g,h);
951*00b67f09SDavid van Moolenbroek 		ROUND256(h,a,b,c,d,e,f,g);
952*00b67f09SDavid van Moolenbroek 		ROUND256(g,h,a,b,c,d,e,f);
953*00b67f09SDavid van Moolenbroek 		ROUND256(f,g,h,a,b,c,d,e);
954*00b67f09SDavid van Moolenbroek 		ROUND256(e,f,g,h,a,b,c,d);
955*00b67f09SDavid van Moolenbroek 		ROUND256(d,e,f,g,h,a,b,c);
956*00b67f09SDavid van Moolenbroek 		ROUND256(c,d,e,f,g,h,a,b);
957*00b67f09SDavid van Moolenbroek 		ROUND256(b,c,d,e,f,g,h,a);
958*00b67f09SDavid van Moolenbroek 	} while (j < 64);
959*00b67f09SDavid van Moolenbroek 
960*00b67f09SDavid van Moolenbroek 	/* Compute the current intermediate hash value */
961*00b67f09SDavid van Moolenbroek 	context->state[0] += a;
962*00b67f09SDavid van Moolenbroek 	context->state[1] += b;
963*00b67f09SDavid van Moolenbroek 	context->state[2] += c;
964*00b67f09SDavid van Moolenbroek 	context->state[3] += d;
965*00b67f09SDavid van Moolenbroek 	context->state[4] += e;
966*00b67f09SDavid van Moolenbroek 	context->state[5] += f;
967*00b67f09SDavid van Moolenbroek 	context->state[6] += g;
968*00b67f09SDavid van Moolenbroek 	context->state[7] += h;
969*00b67f09SDavid van Moolenbroek 
970*00b67f09SDavid van Moolenbroek 	/* Clean up */
971*00b67f09SDavid van Moolenbroek 	a = b = c = d = e = f = g = h = T1 = 0;
972*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings */
973*00b67f09SDavid van Moolenbroek 	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
974*00b67f09SDavid van Moolenbroek 	POST(g); POST(h); POST(T1);
975*00b67f09SDavid van Moolenbroek }
976*00b67f09SDavid van Moolenbroek 
977*00b67f09SDavid van Moolenbroek #else /* ISC_SHA2_UNROLL_TRANSFORM */
978*00b67f09SDavid van Moolenbroek 
979*00b67f09SDavid van Moolenbroek void
isc_sha256_transform(isc_sha256_t * context,const isc_uint32_t * data)980*00b67f09SDavid van Moolenbroek isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
981*00b67f09SDavid van Moolenbroek 	isc_uint32_t	a, b, c, d, e, f, g, h, s0, s1;
982*00b67f09SDavid van Moolenbroek 	isc_uint32_t	T1, T2, *W256;
983*00b67f09SDavid van Moolenbroek 	int		j;
984*00b67f09SDavid van Moolenbroek 
985*00b67f09SDavid van Moolenbroek 	W256 = (isc_uint32_t*)context->buffer;
986*00b67f09SDavid van Moolenbroek 
987*00b67f09SDavid van Moolenbroek 	/* Initialize registers with the prev. intermediate value */
988*00b67f09SDavid van Moolenbroek 	a = context->state[0];
989*00b67f09SDavid van Moolenbroek 	b = context->state[1];
990*00b67f09SDavid van Moolenbroek 	c = context->state[2];
991*00b67f09SDavid van Moolenbroek 	d = context->state[3];
992*00b67f09SDavid van Moolenbroek 	e = context->state[4];
993*00b67f09SDavid van Moolenbroek 	f = context->state[5];
994*00b67f09SDavid van Moolenbroek 	g = context->state[6];
995*00b67f09SDavid van Moolenbroek 	h = context->state[7];
996*00b67f09SDavid van Moolenbroek 
997*00b67f09SDavid van Moolenbroek 	j = 0;
998*00b67f09SDavid van Moolenbroek 	do {
999*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1000*00b67f09SDavid van Moolenbroek 		/* Copy data while converting to host byte order */
1001*00b67f09SDavid van Moolenbroek 		REVERSE32(*data++,W256[j]);
1002*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-256 compression function to update a..h */
1003*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
1004*00b67f09SDavid van Moolenbroek #else /* BYTE_ORDER == LITTLE_ENDIAN */
1005*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-256 compression function to update a..h with copy */
1006*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
1007*00b67f09SDavid van Moolenbroek #endif /* BYTE_ORDER == LITTLE_ENDIAN */
1008*00b67f09SDavid van Moolenbroek 		T2 = Sigma0_256(a) + Maj(a, b, c);
1009*00b67f09SDavid van Moolenbroek 		h = g;
1010*00b67f09SDavid van Moolenbroek 		g = f;
1011*00b67f09SDavid van Moolenbroek 		f = e;
1012*00b67f09SDavid van Moolenbroek 		e = d + T1;
1013*00b67f09SDavid van Moolenbroek 		d = c;
1014*00b67f09SDavid van Moolenbroek 		c = b;
1015*00b67f09SDavid van Moolenbroek 		b = a;
1016*00b67f09SDavid van Moolenbroek 		a = T1 + T2;
1017*00b67f09SDavid van Moolenbroek 
1018*00b67f09SDavid van Moolenbroek 		j++;
1019*00b67f09SDavid van Moolenbroek 	} while (j < 16);
1020*00b67f09SDavid van Moolenbroek 
1021*00b67f09SDavid van Moolenbroek 	do {
1022*00b67f09SDavid van Moolenbroek 		/* Part of the message block expansion: */
1023*00b67f09SDavid van Moolenbroek 		s0 = W256[(j+1)&0x0f];
1024*00b67f09SDavid van Moolenbroek 		s0 = sigma0_256(s0);
1025*00b67f09SDavid van Moolenbroek 		s1 = W256[(j+14)&0x0f];
1026*00b67f09SDavid van Moolenbroek 		s1 = sigma1_256(s1);
1027*00b67f09SDavid van Moolenbroek 
1028*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-256 compression function to update a..h */
1029*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
1030*00b67f09SDavid van Moolenbroek 		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
1031*00b67f09SDavid van Moolenbroek 		T2 = Sigma0_256(a) + Maj(a, b, c);
1032*00b67f09SDavid van Moolenbroek 		h = g;
1033*00b67f09SDavid van Moolenbroek 		g = f;
1034*00b67f09SDavid van Moolenbroek 		f = e;
1035*00b67f09SDavid van Moolenbroek 		e = d + T1;
1036*00b67f09SDavid van Moolenbroek 		d = c;
1037*00b67f09SDavid van Moolenbroek 		c = b;
1038*00b67f09SDavid van Moolenbroek 		b = a;
1039*00b67f09SDavid van Moolenbroek 		a = T1 + T2;
1040*00b67f09SDavid van Moolenbroek 
1041*00b67f09SDavid van Moolenbroek 		j++;
1042*00b67f09SDavid van Moolenbroek 	} while (j < 64);
1043*00b67f09SDavid van Moolenbroek 
1044*00b67f09SDavid van Moolenbroek 	/* Compute the current intermediate hash value */
1045*00b67f09SDavid van Moolenbroek 	context->state[0] += a;
1046*00b67f09SDavid van Moolenbroek 	context->state[1] += b;
1047*00b67f09SDavid van Moolenbroek 	context->state[2] += c;
1048*00b67f09SDavid van Moolenbroek 	context->state[3] += d;
1049*00b67f09SDavid van Moolenbroek 	context->state[4] += e;
1050*00b67f09SDavid van Moolenbroek 	context->state[5] += f;
1051*00b67f09SDavid van Moolenbroek 	context->state[6] += g;
1052*00b67f09SDavid van Moolenbroek 	context->state[7] += h;
1053*00b67f09SDavid van Moolenbroek 
1054*00b67f09SDavid van Moolenbroek 	/* Clean up */
1055*00b67f09SDavid van Moolenbroek 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
1056*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings */
1057*00b67f09SDavid van Moolenbroek 	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
1058*00b67f09SDavid van Moolenbroek 	POST(g); POST(h); POST(T1); POST(T2);
1059*00b67f09SDavid van Moolenbroek }
1060*00b67f09SDavid van Moolenbroek 
1061*00b67f09SDavid van Moolenbroek #endif /* ISC_SHA2_UNROLL_TRANSFORM */
1062*00b67f09SDavid van Moolenbroek 
1063*00b67f09SDavid van Moolenbroek void
isc_sha256_update(isc_sha256_t * context,const isc_uint8_t * data,size_t len)1064*00b67f09SDavid van Moolenbroek isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
1065*00b67f09SDavid van Moolenbroek 	unsigned int	freespace, usedspace;
1066*00b67f09SDavid van Moolenbroek 
1067*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
1068*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
1069*00b67f09SDavid van Moolenbroek 		return;
1070*00b67f09SDavid van Moolenbroek 	}
1071*00b67f09SDavid van Moolenbroek 
1072*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1073*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
1074*00b67f09SDavid van Moolenbroek 
1075*00b67f09SDavid van Moolenbroek 	usedspace = (unsigned int)((context->bitcount >> 3) %
1076*00b67f09SDavid van Moolenbroek 				   ISC_SHA256_BLOCK_LENGTH);
1077*00b67f09SDavid van Moolenbroek 	if (usedspace > 0) {
1078*00b67f09SDavid van Moolenbroek 		/* Calculate how much free space is available in the buffer */
1079*00b67f09SDavid van Moolenbroek 		freespace = ISC_SHA256_BLOCK_LENGTH - usedspace;
1080*00b67f09SDavid van Moolenbroek 
1081*00b67f09SDavid van Moolenbroek 		if (len >= freespace) {
1082*00b67f09SDavid van Moolenbroek 			/* Fill the buffer completely and process it */
1083*00b67f09SDavid van Moolenbroek 			memmove(&context->buffer[usedspace], data, freespace);
1084*00b67f09SDavid van Moolenbroek 			context->bitcount += freespace << 3;
1085*00b67f09SDavid van Moolenbroek 			len -= freespace;
1086*00b67f09SDavid van Moolenbroek 			data += freespace;
1087*00b67f09SDavid van Moolenbroek 			isc_sha256_transform(context,
1088*00b67f09SDavid van Moolenbroek 					     (isc_uint32_t*)context->buffer);
1089*00b67f09SDavid van Moolenbroek 		} else {
1090*00b67f09SDavid van Moolenbroek 			/* The buffer is not yet full */
1091*00b67f09SDavid van Moolenbroek 			memmove(&context->buffer[usedspace], data, len);
1092*00b67f09SDavid van Moolenbroek 			context->bitcount += len << 3;
1093*00b67f09SDavid van Moolenbroek 			/* Clean up: */
1094*00b67f09SDavid van Moolenbroek 			usedspace = freespace = 0;
1095*00b67f09SDavid van Moolenbroek 			/* Avoid compiler warnings: */
1096*00b67f09SDavid van Moolenbroek 			POST(usedspace); POST(freespace);
1097*00b67f09SDavid van Moolenbroek 			return;
1098*00b67f09SDavid van Moolenbroek 		}
1099*00b67f09SDavid van Moolenbroek 	}
1100*00b67f09SDavid van Moolenbroek 	while (len >= ISC_SHA256_BLOCK_LENGTH) {
1101*00b67f09SDavid van Moolenbroek 		/* Process as many complete blocks as we can */
1102*00b67f09SDavid van Moolenbroek 		memmove(context->buffer, data, ISC_SHA256_BLOCK_LENGTH);
1103*00b67f09SDavid van Moolenbroek 		isc_sha256_transform(context, (isc_uint32_t*)context->buffer);
1104*00b67f09SDavid van Moolenbroek 		context->bitcount += ISC_SHA256_BLOCK_LENGTH << 3;
1105*00b67f09SDavid van Moolenbroek 		len -= ISC_SHA256_BLOCK_LENGTH;
1106*00b67f09SDavid van Moolenbroek 		data += ISC_SHA256_BLOCK_LENGTH;
1107*00b67f09SDavid van Moolenbroek 	}
1108*00b67f09SDavid van Moolenbroek 	if (len > 0U) {
1109*00b67f09SDavid van Moolenbroek 		/* There's left-overs, so save 'em */
1110*00b67f09SDavid van Moolenbroek 		memmove(context->buffer, data, len);
1111*00b67f09SDavid van Moolenbroek 		context->bitcount += len << 3;
1112*00b67f09SDavid van Moolenbroek 	}
1113*00b67f09SDavid van Moolenbroek 	/* Clean up: */
1114*00b67f09SDavid van Moolenbroek 	usedspace = freespace = 0;
1115*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings: */
1116*00b67f09SDavid van Moolenbroek 	POST(usedspace); POST(freespace);
1117*00b67f09SDavid van Moolenbroek }
1118*00b67f09SDavid van Moolenbroek 
1119*00b67f09SDavid van Moolenbroek void
isc_sha256_final(isc_uint8_t digest[],isc_sha256_t * context)1120*00b67f09SDavid van Moolenbroek isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
1121*00b67f09SDavid van Moolenbroek 	isc_uint32_t	*d = (isc_uint32_t*)digest;
1122*00b67f09SDavid van Moolenbroek 	unsigned int	usedspace;
1123*00b67f09SDavid van Moolenbroek 
1124*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1125*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0);
1126*00b67f09SDavid van Moolenbroek 
1127*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
1128*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
1129*00b67f09SDavid van Moolenbroek 		usedspace = (unsigned int)((context->bitcount >> 3) %
1130*00b67f09SDavid van Moolenbroek 					   ISC_SHA256_BLOCK_LENGTH);
1131*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1132*00b67f09SDavid van Moolenbroek 		/* Convert FROM host byte order */
1133*00b67f09SDavid van Moolenbroek 		REVERSE64(context->bitcount,context->bitcount);
1134*00b67f09SDavid van Moolenbroek #endif
1135*00b67f09SDavid van Moolenbroek 		if (usedspace > 0) {
1136*00b67f09SDavid van Moolenbroek 			/* Begin padding with a 1 bit: */
1137*00b67f09SDavid van Moolenbroek 			context->buffer[usedspace++] = 0x80;
1138*00b67f09SDavid van Moolenbroek 
1139*00b67f09SDavid van Moolenbroek 			if (usedspace <= ISC_SHA256_SHORT_BLOCK_LENGTH) {
1140*00b67f09SDavid van Moolenbroek 				/* Set-up for the last transform: */
1141*00b67f09SDavid van Moolenbroek 				memset(&context->buffer[usedspace], 0,
1142*00b67f09SDavid van Moolenbroek 				       ISC_SHA256_SHORT_BLOCK_LENGTH - usedspace);
1143*00b67f09SDavid van Moolenbroek 			} else {
1144*00b67f09SDavid van Moolenbroek 				if (usedspace < ISC_SHA256_BLOCK_LENGTH) {
1145*00b67f09SDavid van Moolenbroek 					memset(&context->buffer[usedspace], 0,
1146*00b67f09SDavid van Moolenbroek 					       ISC_SHA256_BLOCK_LENGTH -
1147*00b67f09SDavid van Moolenbroek 					       usedspace);
1148*00b67f09SDavid van Moolenbroek 				}
1149*00b67f09SDavid van Moolenbroek 				/* Do second-to-last transform: */
1150*00b67f09SDavid van Moolenbroek 				isc_sha256_transform(context,
1151*00b67f09SDavid van Moolenbroek 					       (isc_uint32_t*)context->buffer);
1152*00b67f09SDavid van Moolenbroek 
1153*00b67f09SDavid van Moolenbroek 				/* And set-up for the last transform: */
1154*00b67f09SDavid van Moolenbroek 				memset(context->buffer, 0,
1155*00b67f09SDavid van Moolenbroek 				       ISC_SHA256_SHORT_BLOCK_LENGTH);
1156*00b67f09SDavid van Moolenbroek 			}
1157*00b67f09SDavid van Moolenbroek 		} else {
1158*00b67f09SDavid van Moolenbroek 			/* Set-up for the last transform: */
1159*00b67f09SDavid van Moolenbroek 			memset(context->buffer, 0, ISC_SHA256_SHORT_BLOCK_LENGTH);
1160*00b67f09SDavid van Moolenbroek 
1161*00b67f09SDavid van Moolenbroek 			/* Begin padding with a 1 bit: */
1162*00b67f09SDavid van Moolenbroek 			*context->buffer = 0x80;
1163*00b67f09SDavid van Moolenbroek 		}
1164*00b67f09SDavid van Moolenbroek 		/* Set the bit count: */
1165*00b67f09SDavid van Moolenbroek 		memcpy(&context->buffer[ISC_SHA256_SHORT_BLOCK_LENGTH],
1166*00b67f09SDavid van Moolenbroek 		    &context->bitcount, sizeof(isc_uint64_t));
1167*00b67f09SDavid van Moolenbroek 
1168*00b67f09SDavid van Moolenbroek 		/* Final transform: */
1169*00b67f09SDavid van Moolenbroek 		isc_sha256_transform(context, (isc_uint32_t*)context->buffer);
1170*00b67f09SDavid van Moolenbroek 
1171*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1172*00b67f09SDavid van Moolenbroek 		{
1173*00b67f09SDavid van Moolenbroek 			/* Convert TO host byte order */
1174*00b67f09SDavid van Moolenbroek 			int	j;
1175*00b67f09SDavid van Moolenbroek 			for (j = 0; j < 8; j++) {
1176*00b67f09SDavid van Moolenbroek 				REVERSE32(context->state[j],context->state[j]);
1177*00b67f09SDavid van Moolenbroek 				*d++ = context->state[j];
1178*00b67f09SDavid van Moolenbroek 			}
1179*00b67f09SDavid van Moolenbroek 		}
1180*00b67f09SDavid van Moolenbroek #else
1181*00b67f09SDavid van Moolenbroek 		memmove(d, context->state, ISC_SHA256_DIGESTLENGTH);
1182*00b67f09SDavid van Moolenbroek #endif
1183*00b67f09SDavid van Moolenbroek 	}
1184*00b67f09SDavid van Moolenbroek 
1185*00b67f09SDavid van Moolenbroek 	/* Clean up state data: */
1186*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(*context));
1187*00b67f09SDavid van Moolenbroek 	usedspace = 0;
1188*00b67f09SDavid van Moolenbroek 	POST(usedspace);
1189*00b67f09SDavid van Moolenbroek }
1190*00b67f09SDavid van Moolenbroek 
1191*00b67f09SDavid van Moolenbroek /*** SHA-512: *********************************************************/
1192*00b67f09SDavid van Moolenbroek void
isc_sha512_init(isc_sha512_t * context)1193*00b67f09SDavid van Moolenbroek isc_sha512_init(isc_sha512_t *context) {
1194*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha512_t *)0) {
1195*00b67f09SDavid van Moolenbroek 		return;
1196*00b67f09SDavid van Moolenbroek 	}
1197*00b67f09SDavid van Moolenbroek 	memmove(context->state, sha512_initial_hash_value,
1198*00b67f09SDavid van Moolenbroek 		ISC_SHA512_DIGESTLENGTH);
1199*00b67f09SDavid van Moolenbroek 	memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH);
1200*00b67f09SDavid van Moolenbroek 	context->bitcount[0] = context->bitcount[1] =  0;
1201*00b67f09SDavid van Moolenbroek }
1202*00b67f09SDavid van Moolenbroek 
1203*00b67f09SDavid van Moolenbroek void
isc_sha512_invalidate(isc_sha512_t * context)1204*00b67f09SDavid van Moolenbroek isc_sha512_invalidate(isc_sha512_t *context) {
1205*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(isc_sha512_t));
1206*00b67f09SDavid van Moolenbroek }
1207*00b67f09SDavid van Moolenbroek 
1208*00b67f09SDavid van Moolenbroek #ifdef ISC_SHA2_UNROLL_TRANSFORM
1209*00b67f09SDavid van Moolenbroek 
1210*00b67f09SDavid van Moolenbroek /* Unrolled SHA-512 round macros: */
1211*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1212*00b67f09SDavid van Moolenbroek 
1213*00b67f09SDavid van Moolenbroek #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
1214*00b67f09SDavid van Moolenbroek 	REVERSE64(*data++, W512[j]); \
1215*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
1216*00b67f09SDavid van Moolenbroek 	     K512[j] + W512[j]; \
1217*00b67f09SDavid van Moolenbroek 	(d) += T1, \
1218*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
1219*00b67f09SDavid van Moolenbroek 	j++
1220*00b67f09SDavid van Moolenbroek 
1221*00b67f09SDavid van Moolenbroek 
1222*00b67f09SDavid van Moolenbroek #else /* BYTE_ORDER == LITTLE_ENDIAN */
1223*00b67f09SDavid van Moolenbroek 
1224*00b67f09SDavid van Moolenbroek #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
1225*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
1226*00b67f09SDavid van Moolenbroek 	     K512[j] + (W512[j] = *data++); \
1227*00b67f09SDavid van Moolenbroek 	(d) += T1; \
1228*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
1229*00b67f09SDavid van Moolenbroek 	j++
1230*00b67f09SDavid van Moolenbroek 
1231*00b67f09SDavid van Moolenbroek #endif /* BYTE_ORDER == LITTLE_ENDIAN */
1232*00b67f09SDavid van Moolenbroek 
1233*00b67f09SDavid van Moolenbroek #define ROUND512(a,b,c,d,e,f,g,h)	\
1234*00b67f09SDavid van Moolenbroek 	s0 = W512[(j+1)&0x0f]; \
1235*00b67f09SDavid van Moolenbroek 	s0 = sigma0_512(s0); \
1236*00b67f09SDavid van Moolenbroek 	s1 = W512[(j+14)&0x0f]; \
1237*00b67f09SDavid van Moolenbroek 	s1 = sigma1_512(s1); \
1238*00b67f09SDavid van Moolenbroek 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
1239*00b67f09SDavid van Moolenbroek 	     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
1240*00b67f09SDavid van Moolenbroek 	(d) += T1; \
1241*00b67f09SDavid van Moolenbroek 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
1242*00b67f09SDavid van Moolenbroek 	j++
1243*00b67f09SDavid van Moolenbroek 
isc_sha512_transform(isc_sha512_t * context,const isc_uint64_t * data)1244*00b67f09SDavid van Moolenbroek void isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
1245*00b67f09SDavid van Moolenbroek 	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;
1246*00b67f09SDavid van Moolenbroek 	isc_uint64_t	T1, *W512 = (isc_uint64_t*)context->buffer;
1247*00b67f09SDavid van Moolenbroek 	int		j;
1248*00b67f09SDavid van Moolenbroek 
1249*00b67f09SDavid van Moolenbroek 	/* Initialize registers with the prev. intermediate value */
1250*00b67f09SDavid van Moolenbroek 	a = context->state[0];
1251*00b67f09SDavid van Moolenbroek 	b = context->state[1];
1252*00b67f09SDavid van Moolenbroek 	c = context->state[2];
1253*00b67f09SDavid van Moolenbroek 	d = context->state[3];
1254*00b67f09SDavid van Moolenbroek 	e = context->state[4];
1255*00b67f09SDavid van Moolenbroek 	f = context->state[5];
1256*00b67f09SDavid van Moolenbroek 	g = context->state[6];
1257*00b67f09SDavid van Moolenbroek 	h = context->state[7];
1258*00b67f09SDavid van Moolenbroek 
1259*00b67f09SDavid van Moolenbroek 	j = 0;
1260*00b67f09SDavid van Moolenbroek 	do {
1261*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
1262*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
1263*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
1264*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
1265*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
1266*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
1267*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
1268*00b67f09SDavid van Moolenbroek 		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
1269*00b67f09SDavid van Moolenbroek 	} while (j < 16);
1270*00b67f09SDavid van Moolenbroek 
1271*00b67f09SDavid van Moolenbroek 	/* Now for the remaining rounds up to 79: */
1272*00b67f09SDavid van Moolenbroek 	do {
1273*00b67f09SDavid van Moolenbroek 		ROUND512(a,b,c,d,e,f,g,h);
1274*00b67f09SDavid van Moolenbroek 		ROUND512(h,a,b,c,d,e,f,g);
1275*00b67f09SDavid van Moolenbroek 		ROUND512(g,h,a,b,c,d,e,f);
1276*00b67f09SDavid van Moolenbroek 		ROUND512(f,g,h,a,b,c,d,e);
1277*00b67f09SDavid van Moolenbroek 		ROUND512(e,f,g,h,a,b,c,d);
1278*00b67f09SDavid van Moolenbroek 		ROUND512(d,e,f,g,h,a,b,c);
1279*00b67f09SDavid van Moolenbroek 		ROUND512(c,d,e,f,g,h,a,b);
1280*00b67f09SDavid van Moolenbroek 		ROUND512(b,c,d,e,f,g,h,a);
1281*00b67f09SDavid van Moolenbroek 	} while (j < 80);
1282*00b67f09SDavid van Moolenbroek 
1283*00b67f09SDavid van Moolenbroek 	/* Compute the current intermediate hash value */
1284*00b67f09SDavid van Moolenbroek 	context->state[0] += a;
1285*00b67f09SDavid van Moolenbroek 	context->state[1] += b;
1286*00b67f09SDavid van Moolenbroek 	context->state[2] += c;
1287*00b67f09SDavid van Moolenbroek 	context->state[3] += d;
1288*00b67f09SDavid van Moolenbroek 	context->state[4] += e;
1289*00b67f09SDavid van Moolenbroek 	context->state[5] += f;
1290*00b67f09SDavid van Moolenbroek 	context->state[6] += g;
1291*00b67f09SDavid van Moolenbroek 	context->state[7] += h;
1292*00b67f09SDavid van Moolenbroek 
1293*00b67f09SDavid van Moolenbroek 	/* Clean up */
1294*00b67f09SDavid van Moolenbroek 	a = b = c = d = e = f = g = h = T1 = 0;
1295*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings */
1296*00b67f09SDavid van Moolenbroek 	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
1297*00b67f09SDavid van Moolenbroek 	POST(g); POST(h); POST(T1);
1298*00b67f09SDavid van Moolenbroek }
1299*00b67f09SDavid van Moolenbroek 
1300*00b67f09SDavid van Moolenbroek #else /* ISC_SHA2_UNROLL_TRANSFORM */
1301*00b67f09SDavid van Moolenbroek 
1302*00b67f09SDavid van Moolenbroek void
isc_sha512_transform(isc_sha512_t * context,const isc_uint64_t * data)1303*00b67f09SDavid van Moolenbroek isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
1304*00b67f09SDavid van Moolenbroek 	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;
1305*00b67f09SDavid van Moolenbroek 	isc_uint64_t	T1, T2, *W512 = (isc_uint64_t*)context->buffer;
1306*00b67f09SDavid van Moolenbroek 	int		j;
1307*00b67f09SDavid van Moolenbroek 
1308*00b67f09SDavid van Moolenbroek 	/* Initialize registers with the prev. intermediate value */
1309*00b67f09SDavid van Moolenbroek 	a = context->state[0];
1310*00b67f09SDavid van Moolenbroek 	b = context->state[1];
1311*00b67f09SDavid van Moolenbroek 	c = context->state[2];
1312*00b67f09SDavid van Moolenbroek 	d = context->state[3];
1313*00b67f09SDavid van Moolenbroek 	e = context->state[4];
1314*00b67f09SDavid van Moolenbroek 	f = context->state[5];
1315*00b67f09SDavid van Moolenbroek 	g = context->state[6];
1316*00b67f09SDavid van Moolenbroek 	h = context->state[7];
1317*00b67f09SDavid van Moolenbroek 
1318*00b67f09SDavid van Moolenbroek 	j = 0;
1319*00b67f09SDavid van Moolenbroek 	do {
1320*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1321*00b67f09SDavid van Moolenbroek 		/* Convert TO host byte order */
1322*00b67f09SDavid van Moolenbroek 		REVERSE64(*data++, W512[j]);
1323*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-512 compression function to update a..h */
1324*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
1325*00b67f09SDavid van Moolenbroek #else /* BYTE_ORDER == LITTLE_ENDIAN */
1326*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-512 compression function to update a..h with copy */
1327*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
1328*00b67f09SDavid van Moolenbroek #endif /* BYTE_ORDER == LITTLE_ENDIAN */
1329*00b67f09SDavid van Moolenbroek 		T2 = Sigma0_512(a) + Maj(a, b, c);
1330*00b67f09SDavid van Moolenbroek 		h = g;
1331*00b67f09SDavid van Moolenbroek 		g = f;
1332*00b67f09SDavid van Moolenbroek 		f = e;
1333*00b67f09SDavid van Moolenbroek 		e = d + T1;
1334*00b67f09SDavid van Moolenbroek 		d = c;
1335*00b67f09SDavid van Moolenbroek 		c = b;
1336*00b67f09SDavid van Moolenbroek 		b = a;
1337*00b67f09SDavid van Moolenbroek 		a = T1 + T2;
1338*00b67f09SDavid van Moolenbroek 
1339*00b67f09SDavid van Moolenbroek 		j++;
1340*00b67f09SDavid van Moolenbroek 	} while (j < 16);
1341*00b67f09SDavid van Moolenbroek 
1342*00b67f09SDavid van Moolenbroek 	do {
1343*00b67f09SDavid van Moolenbroek 		/* Part of the message block expansion: */
1344*00b67f09SDavid van Moolenbroek 		s0 = W512[(j+1)&0x0f];
1345*00b67f09SDavid van Moolenbroek 		s0 = sigma0_512(s0);
1346*00b67f09SDavid van Moolenbroek 		s1 = W512[(j+14)&0x0f];
1347*00b67f09SDavid van Moolenbroek 		s1 =  sigma1_512(s1);
1348*00b67f09SDavid van Moolenbroek 
1349*00b67f09SDavid van Moolenbroek 		/* Apply the SHA-512 compression function to update a..h */
1350*00b67f09SDavid van Moolenbroek 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
1351*00b67f09SDavid van Moolenbroek 		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
1352*00b67f09SDavid van Moolenbroek 		T2 = Sigma0_512(a) + Maj(a, b, c);
1353*00b67f09SDavid van Moolenbroek 		h = g;
1354*00b67f09SDavid van Moolenbroek 		g = f;
1355*00b67f09SDavid van Moolenbroek 		f = e;
1356*00b67f09SDavid van Moolenbroek 		e = d + T1;
1357*00b67f09SDavid van Moolenbroek 		d = c;
1358*00b67f09SDavid van Moolenbroek 		c = b;
1359*00b67f09SDavid van Moolenbroek 		b = a;
1360*00b67f09SDavid van Moolenbroek 		a = T1 + T2;
1361*00b67f09SDavid van Moolenbroek 
1362*00b67f09SDavid van Moolenbroek 		j++;
1363*00b67f09SDavid van Moolenbroek 	} while (j < 80);
1364*00b67f09SDavid van Moolenbroek 
1365*00b67f09SDavid van Moolenbroek 	/* Compute the current intermediate hash value */
1366*00b67f09SDavid van Moolenbroek 	context->state[0] += a;
1367*00b67f09SDavid van Moolenbroek 	context->state[1] += b;
1368*00b67f09SDavid van Moolenbroek 	context->state[2] += c;
1369*00b67f09SDavid van Moolenbroek 	context->state[3] += d;
1370*00b67f09SDavid van Moolenbroek 	context->state[4] += e;
1371*00b67f09SDavid van Moolenbroek 	context->state[5] += f;
1372*00b67f09SDavid van Moolenbroek 	context->state[6] += g;
1373*00b67f09SDavid van Moolenbroek 	context->state[7] += h;
1374*00b67f09SDavid van Moolenbroek 
1375*00b67f09SDavid van Moolenbroek 	/* Clean up */
1376*00b67f09SDavid van Moolenbroek 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
1377*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings */
1378*00b67f09SDavid van Moolenbroek 	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
1379*00b67f09SDavid van Moolenbroek 	POST(g); POST(h); POST(T1); POST(T2);
1380*00b67f09SDavid van Moolenbroek }
1381*00b67f09SDavid van Moolenbroek 
1382*00b67f09SDavid van Moolenbroek #endif /* ISC_SHA2_UNROLL_TRANSFORM */
1383*00b67f09SDavid van Moolenbroek 
isc_sha512_update(isc_sha512_t * context,const isc_uint8_t * data,size_t len)1384*00b67f09SDavid van Moolenbroek void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
1385*00b67f09SDavid van Moolenbroek 	unsigned int	freespace, usedspace;
1386*00b67f09SDavid van Moolenbroek 
1387*00b67f09SDavid van Moolenbroek 	if (len == 0U) {
1388*00b67f09SDavid van Moolenbroek 		/* Calling with no data is valid - we do nothing */
1389*00b67f09SDavid van Moolenbroek 		return;
1390*00b67f09SDavid van Moolenbroek 	}
1391*00b67f09SDavid van Moolenbroek 
1392*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1393*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
1394*00b67f09SDavid van Moolenbroek 
1395*00b67f09SDavid van Moolenbroek 	usedspace = (unsigned int)((context->bitcount[0] >> 3) %
1396*00b67f09SDavid van Moolenbroek 				   ISC_SHA512_BLOCK_LENGTH);
1397*00b67f09SDavid van Moolenbroek 	if (usedspace > 0) {
1398*00b67f09SDavid van Moolenbroek 		/* Calculate how much free space is available in the buffer */
1399*00b67f09SDavid van Moolenbroek 		freespace = ISC_SHA512_BLOCK_LENGTH - usedspace;
1400*00b67f09SDavid van Moolenbroek 
1401*00b67f09SDavid van Moolenbroek 		if (len >= freespace) {
1402*00b67f09SDavid van Moolenbroek 			/* Fill the buffer completely and process it */
1403*00b67f09SDavid van Moolenbroek 			memmove(&context->buffer[usedspace], data, freespace);
1404*00b67f09SDavid van Moolenbroek 			ADDINC128(context->bitcount, freespace << 3);
1405*00b67f09SDavid van Moolenbroek 			len -= freespace;
1406*00b67f09SDavid van Moolenbroek 			data += freespace;
1407*00b67f09SDavid van Moolenbroek 			isc_sha512_transform(context,
1408*00b67f09SDavid van Moolenbroek 					     (isc_uint64_t*)context->buffer);
1409*00b67f09SDavid van Moolenbroek 		} else {
1410*00b67f09SDavid van Moolenbroek 			/* The buffer is not yet full */
1411*00b67f09SDavid van Moolenbroek 			memmove(&context->buffer[usedspace], data, len);
1412*00b67f09SDavid van Moolenbroek 			ADDINC128(context->bitcount, len << 3);
1413*00b67f09SDavid van Moolenbroek 			/* Clean up: */
1414*00b67f09SDavid van Moolenbroek 			usedspace = freespace = 0;
1415*00b67f09SDavid van Moolenbroek 			/* Avoid compiler warnings: */
1416*00b67f09SDavid van Moolenbroek 			POST(usedspace); POST(freespace);
1417*00b67f09SDavid van Moolenbroek 			return;
1418*00b67f09SDavid van Moolenbroek 		}
1419*00b67f09SDavid van Moolenbroek 	}
1420*00b67f09SDavid van Moolenbroek 	while (len >= ISC_SHA512_BLOCK_LENGTH) {
1421*00b67f09SDavid van Moolenbroek 		/* Process as many complete blocks as we can */
1422*00b67f09SDavid van Moolenbroek 		memmove(context->buffer, data, ISC_SHA512_BLOCK_LENGTH);
1423*00b67f09SDavid van Moolenbroek 		isc_sha512_transform(context, (isc_uint64_t*)context->buffer);
1424*00b67f09SDavid van Moolenbroek 		ADDINC128(context->bitcount, ISC_SHA512_BLOCK_LENGTH << 3);
1425*00b67f09SDavid van Moolenbroek 		len -= ISC_SHA512_BLOCK_LENGTH;
1426*00b67f09SDavid van Moolenbroek 		data += ISC_SHA512_BLOCK_LENGTH;
1427*00b67f09SDavid van Moolenbroek 	}
1428*00b67f09SDavid van Moolenbroek 	if (len > 0U) {
1429*00b67f09SDavid van Moolenbroek 		/* There's left-overs, so save 'em */
1430*00b67f09SDavid van Moolenbroek 		memmove(context->buffer, data, len);
1431*00b67f09SDavid van Moolenbroek 		ADDINC128(context->bitcount, len << 3);
1432*00b67f09SDavid van Moolenbroek 	}
1433*00b67f09SDavid van Moolenbroek 	/* Clean up: */
1434*00b67f09SDavid van Moolenbroek 	usedspace = freespace = 0;
1435*00b67f09SDavid van Moolenbroek 	/* Avoid compiler warnings: */
1436*00b67f09SDavid van Moolenbroek 	POST(usedspace); POST(freespace);
1437*00b67f09SDavid van Moolenbroek }
1438*00b67f09SDavid van Moolenbroek 
isc_sha512_last(isc_sha512_t * context)1439*00b67f09SDavid van Moolenbroek void isc_sha512_last(isc_sha512_t *context) {
1440*00b67f09SDavid van Moolenbroek 	unsigned int	usedspace;
1441*00b67f09SDavid van Moolenbroek 
1442*00b67f09SDavid van Moolenbroek 	usedspace = (unsigned int)((context->bitcount[0] >> 3) %
1443*00b67f09SDavid van Moolenbroek 				    ISC_SHA512_BLOCK_LENGTH);
1444*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1445*00b67f09SDavid van Moolenbroek 	/* Convert FROM host byte order */
1446*00b67f09SDavid van Moolenbroek 	REVERSE64(context->bitcount[0],context->bitcount[0]);
1447*00b67f09SDavid van Moolenbroek 	REVERSE64(context->bitcount[1],context->bitcount[1]);
1448*00b67f09SDavid van Moolenbroek #endif
1449*00b67f09SDavid van Moolenbroek 	if (usedspace > 0) {
1450*00b67f09SDavid van Moolenbroek 		/* Begin padding with a 1 bit: */
1451*00b67f09SDavid van Moolenbroek 		context->buffer[usedspace++] = 0x80;
1452*00b67f09SDavid van Moolenbroek 
1453*00b67f09SDavid van Moolenbroek 		if (usedspace <= ISC_SHA512_SHORT_BLOCK_LENGTH) {
1454*00b67f09SDavid van Moolenbroek 			/* Set-up for the last transform: */
1455*00b67f09SDavid van Moolenbroek 			memset(&context->buffer[usedspace], 0,
1456*00b67f09SDavid van Moolenbroek 			       ISC_SHA512_SHORT_BLOCK_LENGTH - usedspace);
1457*00b67f09SDavid van Moolenbroek 		} else {
1458*00b67f09SDavid van Moolenbroek 			if (usedspace < ISC_SHA512_BLOCK_LENGTH) {
1459*00b67f09SDavid van Moolenbroek 				memset(&context->buffer[usedspace], 0,
1460*00b67f09SDavid van Moolenbroek 				       ISC_SHA512_BLOCK_LENGTH - usedspace);
1461*00b67f09SDavid van Moolenbroek 			}
1462*00b67f09SDavid van Moolenbroek 			/* Do second-to-last transform: */
1463*00b67f09SDavid van Moolenbroek 			isc_sha512_transform(context,
1464*00b67f09SDavid van Moolenbroek 					    (isc_uint64_t*)context->buffer);
1465*00b67f09SDavid van Moolenbroek 
1466*00b67f09SDavid van Moolenbroek 			/* And set-up for the last transform: */
1467*00b67f09SDavid van Moolenbroek 			memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH - 2);
1468*00b67f09SDavid van Moolenbroek 		}
1469*00b67f09SDavid van Moolenbroek 	} else {
1470*00b67f09SDavid van Moolenbroek 		/* Prepare for final transform: */
1471*00b67f09SDavid van Moolenbroek 		memset(context->buffer, 0, ISC_SHA512_SHORT_BLOCK_LENGTH);
1472*00b67f09SDavid van Moolenbroek 
1473*00b67f09SDavid van Moolenbroek 		/* Begin padding with a 1 bit: */
1474*00b67f09SDavid van Moolenbroek 		*context->buffer = 0x80;
1475*00b67f09SDavid van Moolenbroek 	}
1476*00b67f09SDavid van Moolenbroek 	/* Store the length of input data (in bits): */
1477*00b67f09SDavid van Moolenbroek 	memcpy(&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH+8],
1478*00b67f09SDavid van Moolenbroek 	    &context->bitcount[0], sizeof(isc_uint64_t));
1479*00b67f09SDavid van Moolenbroek 
1480*00b67f09SDavid van Moolenbroek 	/* Final transform: */
1481*00b67f09SDavid van Moolenbroek 	isc_sha512_transform(context, (isc_uint64_t*)context->buffer);
1482*00b67f09SDavid van Moolenbroek }
1483*00b67f09SDavid van Moolenbroek 
isc_sha512_final(isc_uint8_t digest[],isc_sha512_t * context)1484*00b67f09SDavid van Moolenbroek void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
1485*00b67f09SDavid van Moolenbroek 	isc_uint64_t	*d = (isc_uint64_t*)digest;
1486*00b67f09SDavid van Moolenbroek 
1487*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1488*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0);
1489*00b67f09SDavid van Moolenbroek 
1490*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
1491*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
1492*00b67f09SDavid van Moolenbroek 		isc_sha512_last(context);
1493*00b67f09SDavid van Moolenbroek 
1494*00b67f09SDavid van Moolenbroek 		/* Save the hash data for output: */
1495*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1496*00b67f09SDavid van Moolenbroek 		{
1497*00b67f09SDavid van Moolenbroek 			/* Convert TO host byte order */
1498*00b67f09SDavid van Moolenbroek 			int	j;
1499*00b67f09SDavid van Moolenbroek 			for (j = 0; j < 8; j++) {
1500*00b67f09SDavid van Moolenbroek 				REVERSE64(context->state[j],context->state[j]);
1501*00b67f09SDavid van Moolenbroek 				*d++ = context->state[j];
1502*00b67f09SDavid van Moolenbroek 			}
1503*00b67f09SDavid van Moolenbroek 		}
1504*00b67f09SDavid van Moolenbroek #else
1505*00b67f09SDavid van Moolenbroek 		memmove(d, context->state, ISC_SHA512_DIGESTLENGTH);
1506*00b67f09SDavid van Moolenbroek #endif
1507*00b67f09SDavid van Moolenbroek 	}
1508*00b67f09SDavid van Moolenbroek 
1509*00b67f09SDavid van Moolenbroek 	/* Zero out state data */
1510*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(*context));
1511*00b67f09SDavid van Moolenbroek }
1512*00b67f09SDavid van Moolenbroek 
1513*00b67f09SDavid van Moolenbroek 
1514*00b67f09SDavid van Moolenbroek /*** SHA-384: *********************************************************/
1515*00b67f09SDavid van Moolenbroek void
isc_sha384_init(isc_sha384_t * context)1516*00b67f09SDavid van Moolenbroek isc_sha384_init(isc_sha384_t *context) {
1517*00b67f09SDavid van Moolenbroek 	if (context == (isc_sha384_t *)0) {
1518*00b67f09SDavid van Moolenbroek 		return;
1519*00b67f09SDavid van Moolenbroek 	}
1520*00b67f09SDavid van Moolenbroek 	memmove(context->state, sha384_initial_hash_value,
1521*00b67f09SDavid van Moolenbroek 		ISC_SHA512_DIGESTLENGTH);
1522*00b67f09SDavid van Moolenbroek 	memset(context->buffer, 0, ISC_SHA384_BLOCK_LENGTH);
1523*00b67f09SDavid van Moolenbroek 	context->bitcount[0] = context->bitcount[1] = 0;
1524*00b67f09SDavid van Moolenbroek }
1525*00b67f09SDavid van Moolenbroek 
1526*00b67f09SDavid van Moolenbroek void
isc_sha384_invalidate(isc_sha384_t * context)1527*00b67f09SDavid van Moolenbroek isc_sha384_invalidate(isc_sha384_t *context) {
1528*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(isc_sha384_t));
1529*00b67f09SDavid van Moolenbroek }
1530*00b67f09SDavid van Moolenbroek 
1531*00b67f09SDavid van Moolenbroek void
isc_sha384_update(isc_sha384_t * context,const isc_uint8_t * data,size_t len)1532*00b67f09SDavid van Moolenbroek isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
1533*00b67f09SDavid van Moolenbroek 	isc_sha512_update((isc_sha512_t *)context, data, len);
1534*00b67f09SDavid van Moolenbroek }
1535*00b67f09SDavid van Moolenbroek 
1536*00b67f09SDavid van Moolenbroek void
isc_sha384_final(isc_uint8_t digest[],isc_sha384_t * context)1537*00b67f09SDavid van Moolenbroek isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
1538*00b67f09SDavid van Moolenbroek 	isc_uint64_t	*d = (isc_uint64_t*)digest;
1539*00b67f09SDavid van Moolenbroek 
1540*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1541*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha384_t *)0);
1542*00b67f09SDavid van Moolenbroek 
1543*00b67f09SDavid van Moolenbroek 	/* If no digest buffer is passed, we don't bother doing this: */
1544*00b67f09SDavid van Moolenbroek 	if (digest != (isc_uint8_t*)0) {
1545*00b67f09SDavid van Moolenbroek 		isc_sha512_last((isc_sha512_t *)context);
1546*00b67f09SDavid van Moolenbroek 
1547*00b67f09SDavid van Moolenbroek 		/* Save the hash data for output: */
1548*00b67f09SDavid van Moolenbroek #if BYTE_ORDER == LITTLE_ENDIAN
1549*00b67f09SDavid van Moolenbroek 		{
1550*00b67f09SDavid van Moolenbroek 			/* Convert TO host byte order */
1551*00b67f09SDavid van Moolenbroek 			int	j;
1552*00b67f09SDavid van Moolenbroek 			for (j = 0; j < 6; j++) {
1553*00b67f09SDavid van Moolenbroek 				REVERSE64(context->state[j],context->state[j]);
1554*00b67f09SDavid van Moolenbroek 				*d++ = context->state[j];
1555*00b67f09SDavid van Moolenbroek 			}
1556*00b67f09SDavid van Moolenbroek 		}
1557*00b67f09SDavid van Moolenbroek #else
1558*00b67f09SDavid van Moolenbroek 		memmove(d, context->state, ISC_SHA384_DIGESTLENGTH);
1559*00b67f09SDavid van Moolenbroek #endif
1560*00b67f09SDavid van Moolenbroek 	}
1561*00b67f09SDavid van Moolenbroek 
1562*00b67f09SDavid van Moolenbroek 	/* Zero out state data */
1563*00b67f09SDavid van Moolenbroek 	memset(context, 0, sizeof(*context));
1564*00b67f09SDavid van Moolenbroek }
1565*00b67f09SDavid van Moolenbroek #endif /* !ISC_PLATFORM_OPENSSLHASH */
1566*00b67f09SDavid van Moolenbroek 
1567*00b67f09SDavid van Moolenbroek /*
1568*00b67f09SDavid van Moolenbroek  * Constant used by SHA256/384/512_End() functions for converting the
1569*00b67f09SDavid van Moolenbroek  * digest to a readable hexadecimal character string:
1570*00b67f09SDavid van Moolenbroek  */
1571*00b67f09SDavid van Moolenbroek static const char *sha2_hex_digits = "0123456789abcdef";
1572*00b67f09SDavid van Moolenbroek 
1573*00b67f09SDavid van Moolenbroek char *
isc_sha224_end(isc_sha224_t * context,char buffer[])1574*00b67f09SDavid van Moolenbroek isc_sha224_end(isc_sha224_t *context, char buffer[]) {
1575*00b67f09SDavid van Moolenbroek 	isc_uint8_t	digest[ISC_SHA224_DIGESTLENGTH], *d = digest;
1576*00b67f09SDavid van Moolenbroek 	unsigned int	i;
1577*00b67f09SDavid van Moolenbroek 
1578*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1579*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha224_t *)0);
1580*00b67f09SDavid van Moolenbroek 
1581*00b67f09SDavid van Moolenbroek 	if (buffer != (char*)0) {
1582*00b67f09SDavid van Moolenbroek 		isc_sha224_final(digest, context);
1583*00b67f09SDavid van Moolenbroek 
1584*00b67f09SDavid van Moolenbroek 		for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) {
1585*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1586*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[*d & 0x0f];
1587*00b67f09SDavid van Moolenbroek 			d++;
1588*00b67f09SDavid van Moolenbroek 		}
1589*00b67f09SDavid van Moolenbroek 		*buffer = (char)0;
1590*00b67f09SDavid van Moolenbroek 	} else {
1591*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
1592*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
1593*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
1594*00b67f09SDavid van Moolenbroek 		pk11_return_session(context);
1595*00b67f09SDavid van Moolenbroek #else
1596*00b67f09SDavid van Moolenbroek 		memset(context, 0, sizeof(*context));
1597*00b67f09SDavid van Moolenbroek #endif
1598*00b67f09SDavid van Moolenbroek 	}
1599*00b67f09SDavid van Moolenbroek 	memset(digest, 0, ISC_SHA224_DIGESTLENGTH);
1600*00b67f09SDavid van Moolenbroek 	return buffer;
1601*00b67f09SDavid van Moolenbroek }
1602*00b67f09SDavid van Moolenbroek 
1603*00b67f09SDavid van Moolenbroek char *
isc_sha224_data(const isc_uint8_t * data,size_t len,char digest[ISC_SHA224_DIGESTSTRINGLENGTH])1604*00b67f09SDavid van Moolenbroek isc_sha224_data(const isc_uint8_t *data, size_t len,
1605*00b67f09SDavid van Moolenbroek 		char digest[ISC_SHA224_DIGESTSTRINGLENGTH])
1606*00b67f09SDavid van Moolenbroek {
1607*00b67f09SDavid van Moolenbroek 	isc_sha224_t context;
1608*00b67f09SDavid van Moolenbroek 
1609*00b67f09SDavid van Moolenbroek 	isc_sha224_init(&context);
1610*00b67f09SDavid van Moolenbroek 	isc_sha224_update(&context, data, len);
1611*00b67f09SDavid van Moolenbroek 	return (isc_sha224_end(&context, digest));
1612*00b67f09SDavid van Moolenbroek }
1613*00b67f09SDavid van Moolenbroek 
1614*00b67f09SDavid van Moolenbroek char *
isc_sha256_end(isc_sha256_t * context,char buffer[])1615*00b67f09SDavid van Moolenbroek isc_sha256_end(isc_sha256_t *context, char buffer[]) {
1616*00b67f09SDavid van Moolenbroek 	isc_uint8_t	digest[ISC_SHA256_DIGESTLENGTH], *d = digest;
1617*00b67f09SDavid van Moolenbroek 	unsigned int	i;
1618*00b67f09SDavid van Moolenbroek 
1619*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1620*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha256_t *)0);
1621*00b67f09SDavid van Moolenbroek 
1622*00b67f09SDavid van Moolenbroek 	if (buffer != (char*)0) {
1623*00b67f09SDavid van Moolenbroek 		isc_sha256_final(digest, context);
1624*00b67f09SDavid van Moolenbroek 
1625*00b67f09SDavid van Moolenbroek 		for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) {
1626*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1627*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[*d & 0x0f];
1628*00b67f09SDavid van Moolenbroek 			d++;
1629*00b67f09SDavid van Moolenbroek 		}
1630*00b67f09SDavid van Moolenbroek 		*buffer = (char)0;
1631*00b67f09SDavid van Moolenbroek 	} else {
1632*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
1633*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
1634*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
1635*00b67f09SDavid van Moolenbroek 		pk11_return_session(context);
1636*00b67f09SDavid van Moolenbroek #else
1637*00b67f09SDavid van Moolenbroek 		memset(context, 0, sizeof(*context));
1638*00b67f09SDavid van Moolenbroek #endif
1639*00b67f09SDavid van Moolenbroek 	}
1640*00b67f09SDavid van Moolenbroek 	memset(digest, 0, ISC_SHA256_DIGESTLENGTH);
1641*00b67f09SDavid van Moolenbroek 	return buffer;
1642*00b67f09SDavid van Moolenbroek }
1643*00b67f09SDavid van Moolenbroek 
1644*00b67f09SDavid van Moolenbroek char *
isc_sha256_data(const isc_uint8_t * data,size_t len,char digest[ISC_SHA256_DIGESTSTRINGLENGTH])1645*00b67f09SDavid van Moolenbroek isc_sha256_data(const isc_uint8_t* data, size_t len,
1646*00b67f09SDavid van Moolenbroek 		char digest[ISC_SHA256_DIGESTSTRINGLENGTH])
1647*00b67f09SDavid van Moolenbroek {
1648*00b67f09SDavid van Moolenbroek 	isc_sha256_t context;
1649*00b67f09SDavid van Moolenbroek 
1650*00b67f09SDavid van Moolenbroek 	isc_sha256_init(&context);
1651*00b67f09SDavid van Moolenbroek 	isc_sha256_update(&context, data, len);
1652*00b67f09SDavid van Moolenbroek 	return (isc_sha256_end(&context, digest));
1653*00b67f09SDavid van Moolenbroek }
1654*00b67f09SDavid van Moolenbroek 
1655*00b67f09SDavid van Moolenbroek char *
isc_sha512_end(isc_sha512_t * context,char buffer[])1656*00b67f09SDavid van Moolenbroek isc_sha512_end(isc_sha512_t *context, char buffer[]) {
1657*00b67f09SDavid van Moolenbroek 	isc_uint8_t	digest[ISC_SHA512_DIGESTLENGTH], *d = digest;
1658*00b67f09SDavid van Moolenbroek 	unsigned int	i;
1659*00b67f09SDavid van Moolenbroek 
1660*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1661*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha512_t *)0);
1662*00b67f09SDavid van Moolenbroek 
1663*00b67f09SDavid van Moolenbroek 	if (buffer != (char*)0) {
1664*00b67f09SDavid van Moolenbroek 		isc_sha512_final(digest, context);
1665*00b67f09SDavid van Moolenbroek 
1666*00b67f09SDavid van Moolenbroek 		for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) {
1667*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1668*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[*d & 0x0f];
1669*00b67f09SDavid van Moolenbroek 			d++;
1670*00b67f09SDavid van Moolenbroek 		}
1671*00b67f09SDavid van Moolenbroek 		*buffer = (char)0;
1672*00b67f09SDavid van Moolenbroek 	} else {
1673*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
1674*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
1675*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
1676*00b67f09SDavid van Moolenbroek 		pk11_return_session(context);
1677*00b67f09SDavid van Moolenbroek #else
1678*00b67f09SDavid van Moolenbroek 		memset(context, 0, sizeof(*context));
1679*00b67f09SDavid van Moolenbroek #endif
1680*00b67f09SDavid van Moolenbroek 	}
1681*00b67f09SDavid van Moolenbroek 	memset(digest, 0, ISC_SHA512_DIGESTLENGTH);
1682*00b67f09SDavid van Moolenbroek 	return buffer;
1683*00b67f09SDavid van Moolenbroek }
1684*00b67f09SDavid van Moolenbroek 
1685*00b67f09SDavid van Moolenbroek char *
isc_sha512_data(const isc_uint8_t * data,size_t len,char digest[ISC_SHA512_DIGESTSTRINGLENGTH])1686*00b67f09SDavid van Moolenbroek isc_sha512_data(const isc_uint8_t *data, size_t len,
1687*00b67f09SDavid van Moolenbroek 		char digest[ISC_SHA512_DIGESTSTRINGLENGTH])
1688*00b67f09SDavid van Moolenbroek {
1689*00b67f09SDavid van Moolenbroek 	isc_sha512_t 	context;
1690*00b67f09SDavid van Moolenbroek 
1691*00b67f09SDavid van Moolenbroek 	isc_sha512_init(&context);
1692*00b67f09SDavid van Moolenbroek 	isc_sha512_update(&context, data, len);
1693*00b67f09SDavid van Moolenbroek 	return (isc_sha512_end(&context, digest));
1694*00b67f09SDavid van Moolenbroek }
1695*00b67f09SDavid van Moolenbroek 
1696*00b67f09SDavid van Moolenbroek char *
isc_sha384_end(isc_sha384_t * context,char buffer[])1697*00b67f09SDavid van Moolenbroek isc_sha384_end(isc_sha384_t *context, char buffer[]) {
1698*00b67f09SDavid van Moolenbroek 	isc_uint8_t	digest[ISC_SHA384_DIGESTLENGTH], *d = digest;
1699*00b67f09SDavid van Moolenbroek 	unsigned int	i;
1700*00b67f09SDavid van Moolenbroek 
1701*00b67f09SDavid van Moolenbroek 	/* Sanity check: */
1702*00b67f09SDavid van Moolenbroek 	REQUIRE(context != (isc_sha384_t *)0);
1703*00b67f09SDavid van Moolenbroek 
1704*00b67f09SDavid van Moolenbroek 	if (buffer != (char*)0) {
1705*00b67f09SDavid van Moolenbroek 		isc_sha384_final(digest, context);
1706*00b67f09SDavid van Moolenbroek 
1707*00b67f09SDavid van Moolenbroek 		for (i = 0; i < ISC_SHA384_DIGESTLENGTH; i++) {
1708*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1709*00b67f09SDavid van Moolenbroek 			*buffer++ = sha2_hex_digits[*d & 0x0f];
1710*00b67f09SDavid van Moolenbroek 			d++;
1711*00b67f09SDavid van Moolenbroek 		}
1712*00b67f09SDavid van Moolenbroek 		*buffer = (char)0;
1713*00b67f09SDavid van Moolenbroek 	} else {
1714*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
1715*00b67f09SDavid van Moolenbroek 		EVP_MD_CTX_cleanup(context);
1716*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
1717*00b67f09SDavid van Moolenbroek 		pk11_return_session(context);
1718*00b67f09SDavid van Moolenbroek #else
1719*00b67f09SDavid van Moolenbroek 		memset(context, 0, sizeof(*context));
1720*00b67f09SDavid van Moolenbroek #endif
1721*00b67f09SDavid van Moolenbroek 	}
1722*00b67f09SDavid van Moolenbroek 	memset(digest, 0, ISC_SHA384_DIGESTLENGTH);
1723*00b67f09SDavid van Moolenbroek 	return buffer;
1724*00b67f09SDavid van Moolenbroek }
1725*00b67f09SDavid van Moolenbroek 
1726*00b67f09SDavid van Moolenbroek char *
isc_sha384_data(const isc_uint8_t * data,size_t len,char digest[ISC_SHA384_DIGESTSTRINGLENGTH])1727*00b67f09SDavid van Moolenbroek isc_sha384_data(const isc_uint8_t *data, size_t len,
1728*00b67f09SDavid van Moolenbroek 		char digest[ISC_SHA384_DIGESTSTRINGLENGTH])
1729*00b67f09SDavid van Moolenbroek {
1730*00b67f09SDavid van Moolenbroek 	isc_sha384_t context;
1731*00b67f09SDavid van Moolenbroek 
1732*00b67f09SDavid van Moolenbroek 	isc_sha384_init(&context);
1733*00b67f09SDavid van Moolenbroek 	isc_sha384_update(&context, data, len);
1734*00b67f09SDavid van Moolenbroek 	return (isc_sha384_end(&context, digest));
1735*00b67f09SDavid van Moolenbroek }
1736