1170222Sdougb/*
2262706Serwin * Copyright (C) 2005-2007, 2009, 2011, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
3170222Sdougb *
4193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
5170222Sdougb * purpose with or without fee is hereby granted, provided that the above
6170222Sdougb * copyright notice and this permission notice appear in all copies.
7170222Sdougb *
8170222Sdougb * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9170222Sdougb * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10170222Sdougb * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11170222Sdougb * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12170222Sdougb * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13170222Sdougb * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14170222Sdougb * PERFORMANCE OF THIS SOFTWARE.
15170222Sdougb */
16170222Sdougb
17234010Sdougb/* $Id$ */
18170222Sdougb
19170222Sdougb/*	$FreeBSD$	*/
20170222Sdougb/*	$KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $	*/
21170222Sdougb
22170222Sdougb/*
23170222Sdougb * sha2.c
24170222Sdougb *
25170222Sdougb * Version 1.0.0beta1
26170222Sdougb *
27170222Sdougb * Written by Aaron D. Gifford <me@aarongifford.com>
28170222Sdougb *
29170222Sdougb * Copyright 2000 Aaron D. Gifford.  All rights reserved.
30170222Sdougb *
31170222Sdougb * Redistribution and use in source and binary forms, with or without
32170222Sdougb * modification, are permitted provided that the following conditions
33170222Sdougb * are met:
34170222Sdougb * 1. Redistributions of source code must retain the above copyright
35170222Sdougb *    notice, this list of conditions and the following disclaimer.
36170222Sdougb * 2. Redistributions in binary form must reproduce the above copyright
37170222Sdougb *    notice, this list of conditions and the following disclaimer in the
38170222Sdougb *    documentation and/or other materials provided with the distribution.
39170222Sdougb * 3. Neither the name of the copyright holder nor the names of contributors
40170222Sdougb *    may be used to endorse or promote products derived from this software
41170222Sdougb *    without specific prior written permission.
42193149Sdougb *
43170222Sdougb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
44170222Sdougb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45170222Sdougb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46170222Sdougb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
47170222Sdougb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48170222Sdougb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49170222Sdougb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50170222Sdougb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51170222Sdougb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52170222Sdougb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53170222Sdougb * SUCH DAMAGE.
54170222Sdougb *
55170222Sdougb */
56170222Sdougb
57170222Sdougb
58170222Sdougb#include <config.h>
59170222Sdougb
60170222Sdougb#include <isc/assertions.h>
61224092Sdougb#include <isc/platform.h>
62170222Sdougb#include <isc/sha2.h>
63170222Sdougb#include <isc/string.h>
64170222Sdougb#include <isc/util.h>
65170222Sdougb
66224092Sdougb#ifdef ISC_PLATFORM_OPENSSLHASH
67224092Sdougb
68224092Sdougbvoid
69224092Sdougbisc_sha224_init(isc_sha224_t *context) {
70224092Sdougb	if (context == (isc_sha224_t *)0) {
71224092Sdougb		return;
72224092Sdougb	}
73224092Sdougb	EVP_DigestInit(context, EVP_sha224());
74224092Sdougb}
75224092Sdougb
76224092Sdougbvoid
77224092Sdougbisc_sha224_invalidate(isc_sha224_t *context) {
78224092Sdougb	EVP_MD_CTX_cleanup(context);
79224092Sdougb}
80224092Sdougb
81224092Sdougbvoid
82224092Sdougbisc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
83224092Sdougb	if (len == 0U) {
84224092Sdougb		/* Calling with no data is valid - we do nothing */
85224092Sdougb		return;
86224092Sdougb	}
87224092Sdougb
88224092Sdougb	/* Sanity check: */
89224092Sdougb	REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0);
90224092Sdougb
91224092Sdougb	EVP_DigestUpdate(context, (const void *) data, len);
92224092Sdougb}
93224092Sdougb
94224092Sdougbvoid
95224092Sdougbisc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
96224092Sdougb	/* Sanity check: */
97224092Sdougb	REQUIRE(context != (isc_sha224_t *)0);
98224092Sdougb
99224092Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
100224092Sdougb	if (digest != (isc_uint8_t*)0) {
101224092Sdougb		EVP_DigestFinal(context, digest, NULL);
102224092Sdougb	} else {
103224092Sdougb		EVP_MD_CTX_cleanup(context);
104224092Sdougb	}
105224092Sdougb}
106224092Sdougb
107224092Sdougbvoid
108224092Sdougbisc_sha256_init(isc_sha256_t *context) {
109224092Sdougb	if (context == (isc_sha256_t *)0) {
110224092Sdougb		return;
111224092Sdougb	}
112224092Sdougb	EVP_DigestInit(context, EVP_sha256());
113224092Sdougb}
114224092Sdougb
115224092Sdougbvoid
116224092Sdougbisc_sha256_invalidate(isc_sha256_t *context) {
117224092Sdougb	EVP_MD_CTX_cleanup(context);
118224092Sdougb}
119224092Sdougb
120224092Sdougbvoid
121224092Sdougbisc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
122224092Sdougb	if (len == 0U) {
123224092Sdougb		/* Calling with no data is valid - we do nothing */
124224092Sdougb		return;
125224092Sdougb	}
126224092Sdougb
127224092Sdougb	/* Sanity check: */
128224092Sdougb	REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
129224092Sdougb
130224092Sdougb	EVP_DigestUpdate(context, (const void *) data, len);
131224092Sdougb}
132224092Sdougb
133224092Sdougbvoid
134224092Sdougbisc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
135224092Sdougb	/* Sanity check: */
136224092Sdougb	REQUIRE(context != (isc_sha256_t *)0);
137224092Sdougb
138224092Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
139224092Sdougb	if (digest != (isc_uint8_t*)0) {
140224092Sdougb		EVP_DigestFinal(context, digest, NULL);
141224092Sdougb	} else {
142224092Sdougb		EVP_MD_CTX_cleanup(context);
143224092Sdougb	}
144224092Sdougb}
145224092Sdougb
146224092Sdougbvoid
147224092Sdougbisc_sha512_init(isc_sha512_t *context) {
148224092Sdougb	if (context == (isc_sha512_t *)0) {
149224092Sdougb		return;
150224092Sdougb	}
151224092Sdougb	EVP_DigestInit(context, EVP_sha512());
152224092Sdougb}
153224092Sdougb
154224092Sdougbvoid
155224092Sdougbisc_sha512_invalidate(isc_sha512_t *context) {
156224092Sdougb	EVP_MD_CTX_cleanup(context);
157224092Sdougb}
158224092Sdougb
159224092Sdougbvoid isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
160224092Sdougb	if (len == 0U) {
161224092Sdougb		/* Calling with no data is valid - we do nothing */
162224092Sdougb		return;
163224092Sdougb	}
164224092Sdougb
165224092Sdougb	/* Sanity check: */
166224092Sdougb	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
167224092Sdougb
168224092Sdougb	EVP_DigestUpdate(context, (const void *) data, len);
169224092Sdougb}
170224092Sdougb
171224092Sdougbvoid isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
172224092Sdougb	/* Sanity check: */
173224092Sdougb	REQUIRE(context != (isc_sha512_t *)0);
174224092Sdougb
175224092Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
176224092Sdougb	if (digest != (isc_uint8_t*)0) {
177224092Sdougb		EVP_DigestFinal(context, digest, NULL);
178224092Sdougb	} else {
179224092Sdougb		EVP_MD_CTX_cleanup(context);
180224092Sdougb	}
181224092Sdougb}
182224092Sdougb
183224092Sdougbvoid
184224092Sdougbisc_sha384_init(isc_sha384_t *context) {
185224092Sdougb	if (context == (isc_sha384_t *)0) {
186224092Sdougb		return;
187224092Sdougb	}
188224092Sdougb	EVP_DigestInit(context, EVP_sha384());
189224092Sdougb}
190224092Sdougb
191224092Sdougbvoid
192224092Sdougbisc_sha384_invalidate(isc_sha384_t *context) {
193224092Sdougb	EVP_MD_CTX_cleanup(context);
194224092Sdougb}
195224092Sdougb
196224092Sdougbvoid
197224092Sdougbisc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
198224092Sdougb	if (len == 0U) {
199224092Sdougb		/* Calling with no data is valid - we do nothing */
200224092Sdougb		return;
201224092Sdougb	}
202224092Sdougb
203224092Sdougb	/* Sanity check: */
204224092Sdougb	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
205224092Sdougb
206224092Sdougb	EVP_DigestUpdate(context, (const void *) data, len);
207224092Sdougb}
208224092Sdougb
209224092Sdougbvoid
210224092Sdougbisc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
211224092Sdougb	/* Sanity check: */
212224092Sdougb	REQUIRE(context != (isc_sha384_t *)0);
213224092Sdougb
214224092Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
215224092Sdougb	if (digest != (isc_uint8_t*)0) {
216224092Sdougb		EVP_DigestFinal(context, digest, NULL);
217224092Sdougb	} else {
218224092Sdougb		EVP_MD_CTX_cleanup(context);
219224092Sdougb	}
220224092Sdougb}
221224092Sdougb
222224092Sdougb#else
223224092Sdougb
224170222Sdougb/*
225170222Sdougb * UNROLLED TRANSFORM LOOP NOTE:
226170222Sdougb * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
227170222Sdougb * loop version for the hash transform rounds (defined using macros
228170222Sdougb * later in this file).  Either define on the command line, for example:
229170222Sdougb *
230170222Sdougb *   cc -DISC_SHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
231170222Sdougb *
232170222Sdougb * or define below:
233170222Sdougb *
234193149Sdougb *   \#define ISC_SHA2_UNROLL_TRANSFORM
235170222Sdougb *
236170222Sdougb */
237170222Sdougb
238170222Sdougb/*** SHA-256/384/512 Machine Architecture Definitions *****************/
239170222Sdougb/*
240170222Sdougb * BYTE_ORDER NOTE:
241170222Sdougb *
242170222Sdougb * Please make sure that your system defines BYTE_ORDER.  If your
243170222Sdougb * architecture is little-endian, make sure it also defines
244170222Sdougb * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
245193149Sdougb * equivalent.
246170222Sdougb *
247170222Sdougb * If your system does not define the above, then you can do so by
248170222Sdougb * hand like this:
249170222Sdougb *
250193149Sdougb *   \#define LITTLE_ENDIAN 1234
251193149Sdougb *   \#define BIG_ENDIAN    4321
252170222Sdougb *
253170222Sdougb * And for little-endian machines, add:
254170222Sdougb *
255193149Sdougb *   \#define BYTE_ORDER LITTLE_ENDIAN
256170222Sdougb *
257170222Sdougb * Or for big-endian machines:
258170222Sdougb *
259193149Sdougb *   \#define BYTE_ORDER BIG_ENDIAN
260170222Sdougb *
261170222Sdougb * The FreeBSD machine this was written on defines BYTE_ORDER
262170222Sdougb * appropriately by including <sys/types.h> (which in turn includes
263170222Sdougb * <machine/endian.h> where the appropriate definitions are actually
264170222Sdougb * made).
265170222Sdougb */
266170222Sdougb#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
267170222Sdougb#ifndef BYTE_ORDER
268170222Sdougb#ifndef BIG_ENDIAN
269170222Sdougb#define BIG_ENDIAN 4321
270170222Sdougb#endif
271170222Sdougb#ifndef LITTLE_ENDIAN
272170222Sdougb#define LITTLE_ENDIAN 1234
273170222Sdougb#endif
274170222Sdougb#ifdef WORDS_BIGENDIAN
275170222Sdougb#define BYTE_ORDER BIG_ENDIAN
276170222Sdougb#else
277170222Sdougb#define BYTE_ORDER LITTLE_ENDIAN
278170222Sdougb#endif
279170222Sdougb#else
280170222Sdougb#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
281170222Sdougb#endif
282170222Sdougb#endif
283170222Sdougb
284170222Sdougb/*** SHA-256/384/512 Various Length Definitions ***********************/
285170222Sdougb/* NOTE: Most of these are in sha2.h */
286170222Sdougb#define ISC_SHA256_SHORT_BLOCK_LENGTH	(ISC_SHA256_BLOCK_LENGTH - 8)
287170222Sdougb#define ISC_SHA384_SHORT_BLOCK_LENGTH	(ISC_SHA384_BLOCK_LENGTH - 16)
288170222Sdougb#define ISC_SHA512_SHORT_BLOCK_LENGTH	(ISC_SHA512_BLOCK_LENGTH - 16)
289170222Sdougb
290170222Sdougb
291170222Sdougb/*** ENDIAN REVERSAL MACROS *******************************************/
292170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
293170222Sdougb#define REVERSE32(w,x)	{ \
294170222Sdougb	isc_uint32_t tmp = (w); \
295170222Sdougb	tmp = (tmp >> 16) | (tmp << 16); \
296170222Sdougb	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
297170222Sdougb}
298170222Sdougb#ifdef WIN32
299170222Sdougb#define REVERSE64(w,x)	{ \
300170222Sdougb	isc_uint64_t tmp = (w); \
301170222Sdougb	tmp = (tmp >> 32) | (tmp << 32); \
302170222Sdougb	tmp = ((tmp & 0xff00ff00ff00ff00UL) >> 8) | \
303170222Sdougb	      ((tmp & 0x00ff00ff00ff00ffUL) << 8); \
304170222Sdougb	(x) = ((tmp & 0xffff0000ffff0000UL) >> 16) | \
305170222Sdougb	      ((tmp & 0x0000ffff0000ffffUL) << 16); \
306170222Sdougb}
307170222Sdougb#else
308170222Sdougb#define REVERSE64(w,x)	{ \
309170222Sdougb	isc_uint64_t tmp = (w); \
310170222Sdougb	tmp = (tmp >> 32) | (tmp << 32); \
311170222Sdougb	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
312170222Sdougb	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
313170222Sdougb	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
314170222Sdougb	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
315170222Sdougb}
316170222Sdougb#endif
317170222Sdougb#endif /* BYTE_ORDER == LITTLE_ENDIAN */
318170222Sdougb
319170222Sdougb/*
320170222Sdougb * Macro for incrementally adding the unsigned 64-bit integer n to the
321170222Sdougb * unsigned 128-bit integer (represented using a two-element array of
322170222Sdougb * 64-bit words):
323170222Sdougb */
324170222Sdougb#define ADDINC128(w,n)	{ \
325170222Sdougb	(w)[0] += (isc_uint64_t)(n); \
326170222Sdougb	if ((w)[0] < (n)) { \
327170222Sdougb		(w)[1]++; \
328170222Sdougb	} \
329170222Sdougb}
330170222Sdougb
331170222Sdougb/*** THE SIX LOGICAL FUNCTIONS ****************************************/
332170222Sdougb/*
333170222Sdougb * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
334170222Sdougb *
335170222Sdougb *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
336170222Sdougb *   S is a ROTATION) because the SHA-256/384/512 description document
337170222Sdougb *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
338170222Sdougb *   same "backwards" definition.
339170222Sdougb */
340170222Sdougb/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
341170222Sdougb#define R(b,x) 		((x) >> (b))
342170222Sdougb/* 32-bit Rotate-right (used in SHA-256): */
343170222Sdougb#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
344170222Sdougb/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
345170222Sdougb#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
346170222Sdougb
347170222Sdougb/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
348170222Sdougb#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
349170222Sdougb#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
350170222Sdougb
351170222Sdougb/* Four of six logical functions used in SHA-256: */
352170222Sdougb#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
353170222Sdougb#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
354170222Sdougb#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
355170222Sdougb#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
356170222Sdougb
357170222Sdougb/* Four of six logical functions used in SHA-384 and SHA-512: */
358170222Sdougb#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
359170222Sdougb#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
360170222Sdougb#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
361170222Sdougb#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
362170222Sdougb
363170222Sdougb/*** INTERNAL FUNCTION PROTOTYPES *************************************/
364170222Sdougb/* NOTE: These should not be accessed directly from outside this
365170222Sdougb * library -- they are intended for private internal visibility/use
366170222Sdougb * only.
367170222Sdougb */
368170222Sdougbvoid isc_sha512_last(isc_sha512_t *);
369170222Sdougbvoid isc_sha256_transform(isc_sha256_t *, const isc_uint32_t*);
370170222Sdougbvoid isc_sha512_transform(isc_sha512_t *, const isc_uint64_t*);
371170222Sdougb
372170222Sdougb
373170222Sdougb/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
374170222Sdougb/* Hash constant words K for SHA-224 and SHA-256: */
375170222Sdougbstatic const isc_uint32_t K256[64] = {
376170222Sdougb	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
377170222Sdougb	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
378170222Sdougb	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
379170222Sdougb	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
380170222Sdougb	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
381170222Sdougb	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
382170222Sdougb	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
383170222Sdougb	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
384170222Sdougb	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
385170222Sdougb	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
386170222Sdougb	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
387170222Sdougb	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
388170222Sdougb	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
389170222Sdougb	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
390170222Sdougb	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
391170222Sdougb	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
392170222Sdougb};
393170222Sdougb
394170222Sdougb/* Initial hash value H for SHA-224: */
395170222Sdougbstatic const isc_uint32_t sha224_initial_hash_value[8] = {
396170222Sdougb	0xc1059ed8UL,
397170222Sdougb	0x367cd507UL,
398170222Sdougb	0x3070dd17UL,
399170222Sdougb	0xf70e5939UL,
400170222Sdougb	0xffc00b31UL,
401170222Sdougb	0x68581511UL,
402170222Sdougb	0x64f98fa7UL,
403170222Sdougb	0xbefa4fa4UL
404170222Sdougb};
405170222Sdougb
406170222Sdougb/* Initial hash value H for SHA-256: */
407170222Sdougbstatic const isc_uint32_t sha256_initial_hash_value[8] = {
408170222Sdougb	0x6a09e667UL,
409170222Sdougb	0xbb67ae85UL,
410170222Sdougb	0x3c6ef372UL,
411170222Sdougb	0xa54ff53aUL,
412170222Sdougb	0x510e527fUL,
413170222Sdougb	0x9b05688cUL,
414170222Sdougb	0x1f83d9abUL,
415170222Sdougb	0x5be0cd19UL
416170222Sdougb};
417170222Sdougb
418170222Sdougb#ifdef WIN32
419170222Sdougb/* Hash constant words K for SHA-384 and SHA-512: */
420170222Sdougbstatic const isc_uint64_t K512[80] = {
421170222Sdougb	0x428a2f98d728ae22UL, 0x7137449123ef65cdUL,
422170222Sdougb	0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL,
423170222Sdougb	0x3956c25bf348b538UL, 0x59f111f1b605d019UL,
424170222Sdougb	0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL,
425170222Sdougb	0xd807aa98a3030242UL, 0x12835b0145706fbeUL,
426170222Sdougb	0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL,
427170222Sdougb	0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL,
428170222Sdougb	0x9bdc06a725c71235UL, 0xc19bf174cf692694UL,
429170222Sdougb	0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL,
430170222Sdougb	0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL,
431170222Sdougb	0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL,
432170222Sdougb	0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL,
433170222Sdougb	0x983e5152ee66dfabUL, 0xa831c66d2db43210UL,
434170222Sdougb	0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL,
435170222Sdougb	0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL,
436170222Sdougb	0x06ca6351e003826fUL, 0x142929670a0e6e70UL,
437170222Sdougb	0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL,
438170222Sdougb	0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL,
439170222Sdougb	0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL,
440170222Sdougb	0x81c2c92e47edaee6UL, 0x92722c851482353bUL,
441170222Sdougb	0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL,
442170222Sdougb	0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL,
443170222Sdougb	0xd192e819d6ef5218UL, 0xd69906245565a910UL,
444170222Sdougb	0xf40e35855771202aUL, 0x106aa07032bbd1b8UL,
445170222Sdougb	0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL,
446170222Sdougb	0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL,
447170222Sdougb	0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL,
448170222Sdougb	0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL,
449170222Sdougb	0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL,
450170222Sdougb	0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL,
451170222Sdougb	0x90befffa23631e28UL, 0xa4506cebde82bde9UL,
452170222Sdougb	0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL,
453170222Sdougb	0xca273eceea26619cUL, 0xd186b8c721c0c207UL,
454170222Sdougb	0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL,
455170222Sdougb	0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL,
456170222Sdougb	0x113f9804bef90daeUL, 0x1b710b35131c471bUL,
457170222Sdougb	0x28db77f523047d84UL, 0x32caab7b40c72493UL,
458170222Sdougb	0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL,
459170222Sdougb	0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL,
460170222Sdougb	0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL
461170222Sdougb};
462170222Sdougb
463170222Sdougb/* Initial hash value H for SHA-384: */
464170222Sdougbstatic const isc_uint64_t sha384_initial_hash_value[8] = {
465170222Sdougb	0xcbbb9d5dc1059ed8UL,
466170222Sdougb	0x629a292a367cd507UL,
467170222Sdougb	0x9159015a3070dd17UL,
468170222Sdougb	0x152fecd8f70e5939UL,
469170222Sdougb	0x67332667ffc00b31UL,
470170222Sdougb	0x8eb44a8768581511UL,
471170222Sdougb	0xdb0c2e0d64f98fa7UL,
472170222Sdougb	0x47b5481dbefa4fa4UL
473170222Sdougb};
474170222Sdougb
475170222Sdougb/* Initial hash value H for SHA-512: */
476170222Sdougbstatic const isc_uint64_t sha512_initial_hash_value[8] = {
477170222Sdougb	0x6a09e667f3bcc908U,
478170222Sdougb	0xbb67ae8584caa73bUL,
479170222Sdougb	0x3c6ef372fe94f82bUL,
480170222Sdougb	0xa54ff53a5f1d36f1UL,
481170222Sdougb	0x510e527fade682d1UL,
482170222Sdougb	0x9b05688c2b3e6c1fUL,
483170222Sdougb	0x1f83d9abfb41bd6bUL,
484170222Sdougb	0x5be0cd19137e2179UL
485170222Sdougb};
486170222Sdougb#else
487170222Sdougb/* Hash constant words K for SHA-384 and SHA-512: */
488170222Sdougbstatic const isc_uint64_t K512[80] = {
489170222Sdougb	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
490170222Sdougb	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
491170222Sdougb	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
492170222Sdougb	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
493170222Sdougb	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
494170222Sdougb	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
495170222Sdougb	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
496170222Sdougb	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
497170222Sdougb	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
498170222Sdougb	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
499170222Sdougb	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
500170222Sdougb	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
501170222Sdougb	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
502170222Sdougb	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
503170222Sdougb	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
504170222Sdougb	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
505170222Sdougb	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
506170222Sdougb	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
507170222Sdougb	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
508170222Sdougb	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
509170222Sdougb	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
510170222Sdougb	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
511170222Sdougb	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
512170222Sdougb	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
513170222Sdougb	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
514170222Sdougb	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
515170222Sdougb	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
516170222Sdougb	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
517170222Sdougb	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
518170222Sdougb	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
519170222Sdougb	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
520170222Sdougb	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
521170222Sdougb	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
522170222Sdougb	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
523170222Sdougb	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
524170222Sdougb	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
525170222Sdougb	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
526170222Sdougb	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
527170222Sdougb	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
528170222Sdougb	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
529170222Sdougb};
530170222Sdougb
531170222Sdougb/* Initial hash value H for SHA-384: */
532170222Sdougbstatic const isc_uint64_t sha384_initial_hash_value[8] = {
533170222Sdougb	0xcbbb9d5dc1059ed8ULL,
534170222Sdougb	0x629a292a367cd507ULL,
535170222Sdougb	0x9159015a3070dd17ULL,
536170222Sdougb	0x152fecd8f70e5939ULL,
537170222Sdougb	0x67332667ffc00b31ULL,
538170222Sdougb	0x8eb44a8768581511ULL,
539170222Sdougb	0xdb0c2e0d64f98fa7ULL,
540170222Sdougb	0x47b5481dbefa4fa4ULL
541170222Sdougb};
542170222Sdougb
543170222Sdougb/* Initial hash value H for SHA-512: */
544170222Sdougbstatic const isc_uint64_t sha512_initial_hash_value[8] = {
545170222Sdougb	0x6a09e667f3bcc908ULL,
546170222Sdougb	0xbb67ae8584caa73bULL,
547170222Sdougb	0x3c6ef372fe94f82bULL,
548170222Sdougb	0xa54ff53a5f1d36f1ULL,
549170222Sdougb	0x510e527fade682d1ULL,
550170222Sdougb	0x9b05688c2b3e6c1fULL,
551170222Sdougb	0x1f83d9abfb41bd6bULL,
552170222Sdougb	0x5be0cd19137e2179ULL
553170222Sdougb};
554170222Sdougb#endif
555170222Sdougb
556170222Sdougb
557170222Sdougb/*** SHA-224: *********************************************************/
558170222Sdougbvoid
559170222Sdougbisc_sha224_init(isc_sha224_t *context) {
560170222Sdougb	if (context == (isc_sha256_t *)0) {
561170222Sdougb		return;
562170222Sdougb	}
563262706Serwin	memmove(context->state, sha224_initial_hash_value,
564262706Serwin		ISC_SHA256_DIGESTLENGTH);
565170222Sdougb	memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH);
566170222Sdougb	context->bitcount = 0;
567170222Sdougb}
568170222Sdougb
569193149Sdougbvoid
570204619Sdougbisc_sha224_invalidate(isc_sha224_t *context) {
571204619Sdougb	memset(context, 0, sizeof(isc_sha224_t));
572204619Sdougb}
573204619Sdougb
574204619Sdougbvoid
575170222Sdougbisc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
576170222Sdougb	isc_sha256_update((isc_sha256_t *)context, data, len);
577170222Sdougb}
578170222Sdougb
579193149Sdougbvoid
580170222Sdougbisc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
581170222Sdougb	isc_uint8_t sha256_digest[ISC_SHA256_DIGESTLENGTH];
582170222Sdougb	isc_sha256_final(sha256_digest, (isc_sha256_t *)context);
583262706Serwin	memmove(digest, sha256_digest, ISC_SHA224_DIGESTLENGTH);
584170222Sdougb	memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH);
585170222Sdougb}
586170222Sdougb
587170222Sdougb/*** SHA-256: *********************************************************/
588170222Sdougbvoid
589170222Sdougbisc_sha256_init(isc_sha256_t *context) {
590170222Sdougb	if (context == (isc_sha256_t *)0) {
591170222Sdougb		return;
592170222Sdougb	}
593262706Serwin	memmove(context->state, sha256_initial_hash_value,
594170222Sdougb	       ISC_SHA256_DIGESTLENGTH);
595170222Sdougb	memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH);
596170222Sdougb	context->bitcount = 0;
597170222Sdougb}
598170222Sdougb
599224092Sdougbvoid
600224092Sdougbisc_sha256_invalidate(isc_sha256_t *context) {
601224092Sdougb	memset(context, 0, sizeof(isc_sha256_t));
602224092Sdougb}
603224092Sdougb
604170222Sdougb#ifdef ISC_SHA2_UNROLL_TRANSFORM
605170222Sdougb
606170222Sdougb/* Unrolled SHA-256 round macros: */
607170222Sdougb
608170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
609170222Sdougb
610170222Sdougb#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
611170222Sdougb	REVERSE32(*data++, W256[j]); \
612170222Sdougb	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
613193149Sdougb	     K256[j] + W256[j]; \
614170222Sdougb	(d) += T1; \
615170222Sdougb	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
616170222Sdougb	j++
617170222Sdougb
618170222Sdougb
619170222Sdougb#else /* BYTE_ORDER == LITTLE_ENDIAN */
620170222Sdougb
621170222Sdougb#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
622170222Sdougb	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
623170222Sdougb	     K256[j] + (W256[j] = *data++); \
624170222Sdougb	(d) += T1; \
625170222Sdougb	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
626170222Sdougb	j++
627170222Sdougb
628170222Sdougb#endif /* BYTE_ORDER == LITTLE_ENDIAN */
629170222Sdougb
630170222Sdougb#define ROUND256(a,b,c,d,e,f,g,h)	\
631170222Sdougb	s0 = W256[(j+1)&0x0f]; \
632170222Sdougb	s0 = sigma0_256(s0); \
633170222Sdougb	s1 = W256[(j+14)&0x0f]; \
634170222Sdougb	s1 = sigma1_256(s1); \
635170222Sdougb	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
636170222Sdougb	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
637170222Sdougb	(d) += T1; \
638170222Sdougb	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
639170222Sdougb	j++
640170222Sdougb
641170222Sdougbvoid isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
642170222Sdougb	isc_uint32_t	a, b, c, d, e, f, g, h, s0, s1;
643170222Sdougb	isc_uint32_t	T1, *W256;
644170222Sdougb	int		j;
645170222Sdougb
646170222Sdougb	W256 = (isc_uint32_t*)context->buffer;
647170222Sdougb
648170222Sdougb	/* Initialize registers with the prev. intermediate value */
649170222Sdougb	a = context->state[0];
650170222Sdougb	b = context->state[1];
651170222Sdougb	c = context->state[2];
652170222Sdougb	d = context->state[3];
653170222Sdougb	e = context->state[4];
654170222Sdougb	f = context->state[5];
655170222Sdougb	g = context->state[6];
656170222Sdougb	h = context->state[7];
657170222Sdougb
658170222Sdougb	j = 0;
659170222Sdougb	do {
660170222Sdougb		/* Rounds 0 to 15 (unrolled): */
661170222Sdougb		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
662170222Sdougb		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
663170222Sdougb		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
664170222Sdougb		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
665170222Sdougb		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
666170222Sdougb		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
667170222Sdougb		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
668170222Sdougb		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
669170222Sdougb	} while (j < 16);
670170222Sdougb
671170222Sdougb	/* Now for the remaining rounds to 64: */
672170222Sdougb	do {
673170222Sdougb		ROUND256(a,b,c,d,e,f,g,h);
674170222Sdougb		ROUND256(h,a,b,c,d,e,f,g);
675170222Sdougb		ROUND256(g,h,a,b,c,d,e,f);
676170222Sdougb		ROUND256(f,g,h,a,b,c,d,e);
677170222Sdougb		ROUND256(e,f,g,h,a,b,c,d);
678170222Sdougb		ROUND256(d,e,f,g,h,a,b,c);
679170222Sdougb		ROUND256(c,d,e,f,g,h,a,b);
680170222Sdougb		ROUND256(b,c,d,e,f,g,h,a);
681170222Sdougb	} while (j < 64);
682170222Sdougb
683170222Sdougb	/* Compute the current intermediate hash value */
684170222Sdougb	context->state[0] += a;
685170222Sdougb	context->state[1] += b;
686170222Sdougb	context->state[2] += c;
687170222Sdougb	context->state[3] += d;
688170222Sdougb	context->state[4] += e;
689170222Sdougb	context->state[5] += f;
690170222Sdougb	context->state[6] += g;
691170222Sdougb	context->state[7] += h;
692170222Sdougb
693170222Sdougb	/* Clean up */
694170222Sdougb	a = b = c = d = e = f = g = h = T1 = 0;
695225361Sdougb	/* Avoid compiler warnings */
696225361Sdougb	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
697225361Sdougb	POST(g); POST(h); POST(T1);
698170222Sdougb}
699170222Sdougb
700170222Sdougb#else /* ISC_SHA2_UNROLL_TRANSFORM */
701170222Sdougb
702170222Sdougbvoid
703170222Sdougbisc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
704170222Sdougb	isc_uint32_t	a, b, c, d, e, f, g, h, s0, s1;
705170222Sdougb	isc_uint32_t	T1, T2, *W256;
706170222Sdougb	int		j;
707170222Sdougb
708170222Sdougb	W256 = (isc_uint32_t*)context->buffer;
709170222Sdougb
710170222Sdougb	/* Initialize registers with the prev. intermediate value */
711170222Sdougb	a = context->state[0];
712170222Sdougb	b = context->state[1];
713170222Sdougb	c = context->state[2];
714170222Sdougb	d = context->state[3];
715170222Sdougb	e = context->state[4];
716170222Sdougb	f = context->state[5];
717170222Sdougb	g = context->state[6];
718170222Sdougb	h = context->state[7];
719170222Sdougb
720170222Sdougb	j = 0;
721170222Sdougb	do {
722170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
723170222Sdougb		/* Copy data while converting to host byte order */
724170222Sdougb		REVERSE32(*data++,W256[j]);
725170222Sdougb		/* Apply the SHA-256 compression function to update a..h */
726170222Sdougb		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
727170222Sdougb#else /* BYTE_ORDER == LITTLE_ENDIAN */
728170222Sdougb		/* Apply the SHA-256 compression function to update a..h with copy */
729170222Sdougb		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
730170222Sdougb#endif /* BYTE_ORDER == LITTLE_ENDIAN */
731170222Sdougb		T2 = Sigma0_256(a) + Maj(a, b, c);
732170222Sdougb		h = g;
733170222Sdougb		g = f;
734170222Sdougb		f = e;
735170222Sdougb		e = d + T1;
736170222Sdougb		d = c;
737170222Sdougb		c = b;
738170222Sdougb		b = a;
739170222Sdougb		a = T1 + T2;
740170222Sdougb
741170222Sdougb		j++;
742170222Sdougb	} while (j < 16);
743170222Sdougb
744170222Sdougb	do {
745170222Sdougb		/* Part of the message block expansion: */
746170222Sdougb		s0 = W256[(j+1)&0x0f];
747170222Sdougb		s0 = sigma0_256(s0);
748193149Sdougb		s1 = W256[(j+14)&0x0f];
749170222Sdougb		s1 = sigma1_256(s1);
750170222Sdougb
751170222Sdougb		/* Apply the SHA-256 compression function to update a..h */
752193149Sdougb		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
753170222Sdougb		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
754170222Sdougb		T2 = Sigma0_256(a) + Maj(a, b, c);
755170222Sdougb		h = g;
756170222Sdougb		g = f;
757170222Sdougb		f = e;
758170222Sdougb		e = d + T1;
759170222Sdougb		d = c;
760170222Sdougb		c = b;
761170222Sdougb		b = a;
762170222Sdougb		a = T1 + T2;
763170222Sdougb
764170222Sdougb		j++;
765170222Sdougb	} while (j < 64);
766170222Sdougb
767170222Sdougb	/* Compute the current intermediate hash value */
768170222Sdougb	context->state[0] += a;
769170222Sdougb	context->state[1] += b;
770170222Sdougb	context->state[2] += c;
771170222Sdougb	context->state[3] += d;
772170222Sdougb	context->state[4] += e;
773170222Sdougb	context->state[5] += f;
774170222Sdougb	context->state[6] += g;
775170222Sdougb	context->state[7] += h;
776170222Sdougb
777170222Sdougb	/* Clean up */
778170222Sdougb	a = b = c = d = e = f = g = h = T1 = T2 = 0;
779225361Sdougb	/* Avoid compiler warnings */
780225361Sdougb	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
781225361Sdougb	POST(g); POST(h); POST(T1); POST(T2);
782170222Sdougb}
783170222Sdougb
784170222Sdougb#endif /* ISC_SHA2_UNROLL_TRANSFORM */
785170222Sdougb
786170222Sdougbvoid
787170222Sdougbisc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
788170222Sdougb	unsigned int	freespace, usedspace;
789170222Sdougb
790170222Sdougb	if (len == 0U) {
791170222Sdougb		/* Calling with no data is valid - we do nothing */
792170222Sdougb		return;
793170222Sdougb	}
794170222Sdougb
795170222Sdougb	/* Sanity check: */
796170222Sdougb	REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
797170222Sdougb
798170222Sdougb	usedspace = (unsigned int)((context->bitcount >> 3) %
799170222Sdougb				   ISC_SHA256_BLOCK_LENGTH);
800170222Sdougb	if (usedspace > 0) {
801170222Sdougb		/* Calculate how much free space is available in the buffer */
802170222Sdougb		freespace = ISC_SHA256_BLOCK_LENGTH - usedspace;
803170222Sdougb
804170222Sdougb		if (len >= freespace) {
805170222Sdougb			/* Fill the buffer completely and process it */
806262706Serwin			memmove(&context->buffer[usedspace], data, freespace);
807170222Sdougb			context->bitcount += freespace << 3;
808170222Sdougb			len -= freespace;
809170222Sdougb			data += freespace;
810170222Sdougb			isc_sha256_transform(context,
811170222Sdougb					     (isc_uint32_t*)context->buffer);
812170222Sdougb		} else {
813170222Sdougb			/* The buffer is not yet full */
814262706Serwin			memmove(&context->buffer[usedspace], data, len);
815170222Sdougb			context->bitcount += len << 3;
816170222Sdougb			/* Clean up: */
817170222Sdougb			usedspace = freespace = 0;
818225361Sdougb			/* Avoid compiler warnings: */
819225361Sdougb			POST(usedspace); POST(freespace);
820170222Sdougb			return;
821170222Sdougb		}
822170222Sdougb	}
823170222Sdougb	while (len >= ISC_SHA256_BLOCK_LENGTH) {
824170222Sdougb		/* Process as many complete blocks as we can */
825262706Serwin		memmove(context->buffer, data, ISC_SHA256_BLOCK_LENGTH);
826170222Sdougb		isc_sha256_transform(context, (isc_uint32_t*)context->buffer);
827170222Sdougb		context->bitcount += ISC_SHA256_BLOCK_LENGTH << 3;
828170222Sdougb		len -= ISC_SHA256_BLOCK_LENGTH;
829170222Sdougb		data += ISC_SHA256_BLOCK_LENGTH;
830170222Sdougb	}
831170222Sdougb	if (len > 0U) {
832170222Sdougb		/* There's left-overs, so save 'em */
833262706Serwin		memmove(context->buffer, data, len);
834170222Sdougb		context->bitcount += len << 3;
835170222Sdougb	}
836170222Sdougb	/* Clean up: */
837170222Sdougb	usedspace = freespace = 0;
838225361Sdougb	/* Avoid compiler warnings: */
839225361Sdougb	POST(usedspace); POST(freespace);
840170222Sdougb}
841170222Sdougb
842170222Sdougbvoid
843170222Sdougbisc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
844170222Sdougb	isc_uint32_t	*d = (isc_uint32_t*)digest;
845170222Sdougb	unsigned int	usedspace;
846170222Sdougb
847170222Sdougb	/* Sanity check: */
848170222Sdougb	REQUIRE(context != (isc_sha256_t *)0);
849170222Sdougb
850170222Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
851170222Sdougb	if (digest != (isc_uint8_t*)0) {
852170222Sdougb		usedspace = (unsigned int)((context->bitcount >> 3) %
853170222Sdougb					   ISC_SHA256_BLOCK_LENGTH);
854170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
855170222Sdougb		/* Convert FROM host byte order */
856170222Sdougb		REVERSE64(context->bitcount,context->bitcount);
857170222Sdougb#endif
858170222Sdougb		if (usedspace > 0) {
859170222Sdougb			/* Begin padding with a 1 bit: */
860170222Sdougb			context->buffer[usedspace++] = 0x80;
861170222Sdougb
862170222Sdougb			if (usedspace <= ISC_SHA256_SHORT_BLOCK_LENGTH) {
863170222Sdougb				/* Set-up for the last transform: */
864170222Sdougb				memset(&context->buffer[usedspace], 0,
865170222Sdougb				       ISC_SHA256_SHORT_BLOCK_LENGTH - usedspace);
866170222Sdougb			} else {
867170222Sdougb				if (usedspace < ISC_SHA256_BLOCK_LENGTH) {
868170222Sdougb					memset(&context->buffer[usedspace], 0,
869170222Sdougb					       ISC_SHA256_BLOCK_LENGTH -
870170222Sdougb					       usedspace);
871170222Sdougb				}
872170222Sdougb				/* Do second-to-last transform: */
873170222Sdougb				isc_sha256_transform(context,
874170222Sdougb					       (isc_uint32_t*)context->buffer);
875170222Sdougb
876170222Sdougb				/* And set-up for the last transform: */
877170222Sdougb				memset(context->buffer, 0,
878170222Sdougb				       ISC_SHA256_SHORT_BLOCK_LENGTH);
879170222Sdougb			}
880170222Sdougb		} else {
881170222Sdougb			/* Set-up for the last transform: */
882170222Sdougb			memset(context->buffer, 0, ISC_SHA256_SHORT_BLOCK_LENGTH);
883170222Sdougb
884170222Sdougb			/* Begin padding with a 1 bit: */
885170222Sdougb			*context->buffer = 0x80;
886170222Sdougb		}
887170222Sdougb		/* Set the bit count: */
888170222Sdougb		*(isc_uint64_t*)&context->buffer[ISC_SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
889170222Sdougb
890170222Sdougb		/* Final transform: */
891170222Sdougb		isc_sha256_transform(context, (isc_uint32_t*)context->buffer);
892170222Sdougb
893170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
894170222Sdougb		{
895170222Sdougb			/* Convert TO host byte order */
896170222Sdougb			int	j;
897170222Sdougb			for (j = 0; j < 8; j++) {
898170222Sdougb				REVERSE32(context->state[j],context->state[j]);
899170222Sdougb				*d++ = context->state[j];
900170222Sdougb			}
901170222Sdougb		}
902170222Sdougb#else
903262706Serwin		memmove(d, context->state, ISC_SHA256_DIGESTLENGTH);
904170222Sdougb#endif
905170222Sdougb	}
906170222Sdougb
907170222Sdougb	/* Clean up state data: */
908234010Sdougb	memset(context, 0, sizeof(*context));
909170222Sdougb	usedspace = 0;
910225361Sdougb	POST(usedspace);
911170222Sdougb}
912170222Sdougb
913170222Sdougb/*** SHA-512: *********************************************************/
914170222Sdougbvoid
915170222Sdougbisc_sha512_init(isc_sha512_t *context) {
916170222Sdougb	if (context == (isc_sha512_t *)0) {
917170222Sdougb		return;
918170222Sdougb	}
919262706Serwin	memmove(context->state, sha512_initial_hash_value,
920262706Serwin		ISC_SHA512_DIGESTLENGTH);
921170222Sdougb	memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH);
922170222Sdougb	context->bitcount[0] = context->bitcount[1] =  0;
923170222Sdougb}
924170222Sdougb
925224092Sdougbvoid
926224092Sdougbisc_sha512_invalidate(isc_sha512_t *context) {
927224092Sdougb	memset(context, 0, sizeof(isc_sha512_t));
928224092Sdougb}
929224092Sdougb
930170222Sdougb#ifdef ISC_SHA2_UNROLL_TRANSFORM
931170222Sdougb
932170222Sdougb/* Unrolled SHA-512 round macros: */
933170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
934170222Sdougb
935170222Sdougb#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
936170222Sdougb	REVERSE64(*data++, W512[j]); \
937170222Sdougb	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
938193149Sdougb	     K512[j] + W512[j]; \
939170222Sdougb	(d) += T1, \
940170222Sdougb	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
941170222Sdougb	j++
942170222Sdougb
943170222Sdougb
944170222Sdougb#else /* BYTE_ORDER == LITTLE_ENDIAN */
945170222Sdougb
946170222Sdougb#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
947170222Sdougb	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
948193149Sdougb	     K512[j] + (W512[j] = *data++); \
949170222Sdougb	(d) += T1; \
950170222Sdougb	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
951170222Sdougb	j++
952170222Sdougb
953170222Sdougb#endif /* BYTE_ORDER == LITTLE_ENDIAN */
954170222Sdougb
955170222Sdougb#define ROUND512(a,b,c,d,e,f,g,h)	\
956170222Sdougb	s0 = W512[(j+1)&0x0f]; \
957170222Sdougb	s0 = sigma0_512(s0); \
958170222Sdougb	s1 = W512[(j+14)&0x0f]; \
959170222Sdougb	s1 = sigma1_512(s1); \
960170222Sdougb	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
961193149Sdougb	     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
962170222Sdougb	(d) += T1; \
963170222Sdougb	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
964170222Sdougb	j++
965170222Sdougb
966170222Sdougbvoid isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
967170222Sdougb	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;
968170222Sdougb	isc_uint64_t	T1, *W512 = (isc_uint64_t*)context->buffer;
969170222Sdougb	int		j;
970170222Sdougb
971170222Sdougb	/* Initialize registers with the prev. intermediate value */
972170222Sdougb	a = context->state[0];
973170222Sdougb	b = context->state[1];
974170222Sdougb	c = context->state[2];
975170222Sdougb	d = context->state[3];
976170222Sdougb	e = context->state[4];
977170222Sdougb	f = context->state[5];
978170222Sdougb	g = context->state[6];
979170222Sdougb	h = context->state[7];
980170222Sdougb
981170222Sdougb	j = 0;
982170222Sdougb	do {
983170222Sdougb		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
984170222Sdougb		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
985170222Sdougb		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
986170222Sdougb		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
987170222Sdougb		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
988170222Sdougb		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
989170222Sdougb		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
990170222Sdougb		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
991170222Sdougb	} while (j < 16);
992170222Sdougb
993170222Sdougb	/* Now for the remaining rounds up to 79: */
994170222Sdougb	do {
995170222Sdougb		ROUND512(a,b,c,d,e,f,g,h);
996170222Sdougb		ROUND512(h,a,b,c,d,e,f,g);
997170222Sdougb		ROUND512(g,h,a,b,c,d,e,f);
998170222Sdougb		ROUND512(f,g,h,a,b,c,d,e);
999170222Sdougb		ROUND512(e,f,g,h,a,b,c,d);
1000170222Sdougb		ROUND512(d,e,f,g,h,a,b,c);
1001170222Sdougb		ROUND512(c,d,e,f,g,h,a,b);
1002170222Sdougb		ROUND512(b,c,d,e,f,g,h,a);
1003170222Sdougb	} while (j < 80);
1004170222Sdougb
1005170222Sdougb	/* Compute the current intermediate hash value */
1006170222Sdougb	context->state[0] += a;
1007170222Sdougb	context->state[1] += b;
1008170222Sdougb	context->state[2] += c;
1009170222Sdougb	context->state[3] += d;
1010170222Sdougb	context->state[4] += e;
1011170222Sdougb	context->state[5] += f;
1012170222Sdougb	context->state[6] += g;
1013170222Sdougb	context->state[7] += h;
1014170222Sdougb
1015170222Sdougb	/* Clean up */
1016170222Sdougb	a = b = c = d = e = f = g = h = T1 = 0;
1017225361Sdougb	/* Avoid compiler warnings */
1018225361Sdougb	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
1019225361Sdougb	POST(g); POST(h); POST(T1);
1020170222Sdougb}
1021170222Sdougb
1022170222Sdougb#else /* ISC_SHA2_UNROLL_TRANSFORM */
1023170222Sdougb
1024170222Sdougbvoid
1025170222Sdougbisc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
1026170222Sdougb	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;
1027170222Sdougb	isc_uint64_t	T1, T2, *W512 = (isc_uint64_t*)context->buffer;
1028170222Sdougb	int		j;
1029170222Sdougb
1030170222Sdougb	/* Initialize registers with the prev. intermediate value */
1031170222Sdougb	a = context->state[0];
1032170222Sdougb	b = context->state[1];
1033170222Sdougb	c = context->state[2];
1034170222Sdougb	d = context->state[3];
1035170222Sdougb	e = context->state[4];
1036170222Sdougb	f = context->state[5];
1037170222Sdougb	g = context->state[6];
1038170222Sdougb	h = context->state[7];
1039170222Sdougb
1040170222Sdougb	j = 0;
1041170222Sdougb	do {
1042170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
1043170222Sdougb		/* Convert TO host byte order */
1044170222Sdougb		REVERSE64(*data++, W512[j]);
1045170222Sdougb		/* Apply the SHA-512 compression function to update a..h */
1046170222Sdougb		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
1047170222Sdougb#else /* BYTE_ORDER == LITTLE_ENDIAN */
1048170222Sdougb		/* Apply the SHA-512 compression function to update a..h with copy */
1049170222Sdougb		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
1050170222Sdougb#endif /* BYTE_ORDER == LITTLE_ENDIAN */
1051170222Sdougb		T2 = Sigma0_512(a) + Maj(a, b, c);
1052170222Sdougb		h = g;
1053170222Sdougb		g = f;
1054170222Sdougb		f = e;
1055170222Sdougb		e = d + T1;
1056170222Sdougb		d = c;
1057170222Sdougb		c = b;
1058170222Sdougb		b = a;
1059170222Sdougb		a = T1 + T2;
1060170222Sdougb
1061170222Sdougb		j++;
1062170222Sdougb	} while (j < 16);
1063170222Sdougb
1064170222Sdougb	do {
1065170222Sdougb		/* Part of the message block expansion: */
1066170222Sdougb		s0 = W512[(j+1)&0x0f];
1067170222Sdougb		s0 = sigma0_512(s0);
1068170222Sdougb		s1 = W512[(j+14)&0x0f];
1069170222Sdougb		s1 =  sigma1_512(s1);
1070170222Sdougb
1071170222Sdougb		/* Apply the SHA-512 compression function to update a..h */
1072170222Sdougb		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
1073170222Sdougb		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
1074170222Sdougb		T2 = Sigma0_512(a) + Maj(a, b, c);
1075170222Sdougb		h = g;
1076170222Sdougb		g = f;
1077170222Sdougb		f = e;
1078170222Sdougb		e = d + T1;
1079170222Sdougb		d = c;
1080170222Sdougb		c = b;
1081170222Sdougb		b = a;
1082170222Sdougb		a = T1 + T2;
1083170222Sdougb
1084170222Sdougb		j++;
1085170222Sdougb	} while (j < 80);
1086170222Sdougb
1087170222Sdougb	/* Compute the current intermediate hash value */
1088170222Sdougb	context->state[0] += a;
1089170222Sdougb	context->state[1] += b;
1090170222Sdougb	context->state[2] += c;
1091170222Sdougb	context->state[3] += d;
1092170222Sdougb	context->state[4] += e;
1093170222Sdougb	context->state[5] += f;
1094170222Sdougb	context->state[6] += g;
1095170222Sdougb	context->state[7] += h;
1096170222Sdougb
1097170222Sdougb	/* Clean up */
1098170222Sdougb	a = b = c = d = e = f = g = h = T1 = T2 = 0;
1099225361Sdougb	/* Avoid compiler warnings */
1100225361Sdougb	POST(a); POST(b); POST(c); POST(d); POST(e); POST(f);
1101225361Sdougb	POST(g); POST(h); POST(T1); POST(T2);
1102170222Sdougb}
1103170222Sdougb
1104170222Sdougb#endif /* ISC_SHA2_UNROLL_TRANSFORM */
1105170222Sdougb
1106224092Sdougbvoid isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
1107170222Sdougb	unsigned int	freespace, usedspace;
1108170222Sdougb
1109170222Sdougb	if (len == 0U) {
1110170222Sdougb		/* Calling with no data is valid - we do nothing */
1111170222Sdougb		return;
1112170222Sdougb	}
1113170222Sdougb
1114170222Sdougb	/* Sanity check: */
1115170222Sdougb	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
1116170222Sdougb
1117170222Sdougb	usedspace = (unsigned int)((context->bitcount[0] >> 3) %
1118170222Sdougb				   ISC_SHA512_BLOCK_LENGTH);
1119170222Sdougb	if (usedspace > 0) {
1120170222Sdougb		/* Calculate how much free space is available in the buffer */
1121170222Sdougb		freespace = ISC_SHA512_BLOCK_LENGTH - usedspace;
1122170222Sdougb
1123170222Sdougb		if (len >= freespace) {
1124170222Sdougb			/* Fill the buffer completely and process it */
1125262706Serwin			memmove(&context->buffer[usedspace], data, freespace);
1126170222Sdougb			ADDINC128(context->bitcount, freespace << 3);
1127170222Sdougb			len -= freespace;
1128170222Sdougb			data += freespace;
1129170222Sdougb			isc_sha512_transform(context,
1130170222Sdougb					     (isc_uint64_t*)context->buffer);
1131170222Sdougb		} else {
1132170222Sdougb			/* The buffer is not yet full */
1133262706Serwin			memmove(&context->buffer[usedspace], data, len);
1134170222Sdougb			ADDINC128(context->bitcount, len << 3);
1135170222Sdougb			/* Clean up: */
1136170222Sdougb			usedspace = freespace = 0;
1137225361Sdougb			/* Avoid compiler warnings: */
1138225361Sdougb			POST(usedspace); POST(freespace);
1139170222Sdougb			return;
1140170222Sdougb		}
1141170222Sdougb	}
1142170222Sdougb	while (len >= ISC_SHA512_BLOCK_LENGTH) {
1143170222Sdougb		/* Process as many complete blocks as we can */
1144262706Serwin		memmove(context->buffer, data, ISC_SHA512_BLOCK_LENGTH);
1145170222Sdougb		isc_sha512_transform(context, (isc_uint64_t*)context->buffer);
1146170222Sdougb		ADDINC128(context->bitcount, ISC_SHA512_BLOCK_LENGTH << 3);
1147170222Sdougb		len -= ISC_SHA512_BLOCK_LENGTH;
1148170222Sdougb		data += ISC_SHA512_BLOCK_LENGTH;
1149170222Sdougb	}
1150170222Sdougb	if (len > 0U) {
1151170222Sdougb		/* There's left-overs, so save 'em */
1152262706Serwin		memmove(context->buffer, data, len);
1153170222Sdougb		ADDINC128(context->bitcount, len << 3);
1154170222Sdougb	}
1155170222Sdougb	/* Clean up: */
1156170222Sdougb	usedspace = freespace = 0;
1157225361Sdougb	/* Avoid compiler warnings: */
1158225361Sdougb	POST(usedspace); POST(freespace);
1159170222Sdougb}
1160170222Sdougb
1161170222Sdougbvoid isc_sha512_last(isc_sha512_t *context) {
1162170222Sdougb	unsigned int	usedspace;
1163170222Sdougb
1164170222Sdougb	usedspace = (unsigned int)((context->bitcount[0] >> 3) %
1165170222Sdougb				    ISC_SHA512_BLOCK_LENGTH);
1166170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
1167170222Sdougb	/* Convert FROM host byte order */
1168170222Sdougb	REVERSE64(context->bitcount[0],context->bitcount[0]);
1169170222Sdougb	REVERSE64(context->bitcount[1],context->bitcount[1]);
1170170222Sdougb#endif
1171170222Sdougb	if (usedspace > 0) {
1172170222Sdougb		/* Begin padding with a 1 bit: */
1173170222Sdougb		context->buffer[usedspace++] = 0x80;
1174170222Sdougb
1175170222Sdougb		if (usedspace <= ISC_SHA512_SHORT_BLOCK_LENGTH) {
1176170222Sdougb			/* Set-up for the last transform: */
1177170222Sdougb			memset(&context->buffer[usedspace], 0,
1178170222Sdougb			       ISC_SHA512_SHORT_BLOCK_LENGTH - usedspace);
1179170222Sdougb		} else {
1180170222Sdougb			if (usedspace < ISC_SHA512_BLOCK_LENGTH) {
1181170222Sdougb				memset(&context->buffer[usedspace], 0,
1182170222Sdougb				       ISC_SHA512_BLOCK_LENGTH - usedspace);
1183170222Sdougb			}
1184170222Sdougb			/* Do second-to-last transform: */
1185170222Sdougb			isc_sha512_transform(context,
1186170222Sdougb					    (isc_uint64_t*)context->buffer);
1187170222Sdougb
1188170222Sdougb			/* And set-up for the last transform: */
1189170222Sdougb			memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH - 2);
1190170222Sdougb		}
1191170222Sdougb	} else {
1192170222Sdougb		/* Prepare for final transform: */
1193170222Sdougb		memset(context->buffer, 0, ISC_SHA512_SHORT_BLOCK_LENGTH);
1194170222Sdougb
1195170222Sdougb		/* Begin padding with a 1 bit: */
1196170222Sdougb		*context->buffer = 0x80;
1197170222Sdougb	}
1198170222Sdougb	/* Store the length of input data (in bits): */
1199170222Sdougb	*(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
1200170222Sdougb	*(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
1201170222Sdougb
1202170222Sdougb	/* Final transform: */
1203170222Sdougb	isc_sha512_transform(context, (isc_uint64_t*)context->buffer);
1204170222Sdougb}
1205170222Sdougb
1206170222Sdougbvoid isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
1207170222Sdougb	isc_uint64_t	*d = (isc_uint64_t*)digest;
1208170222Sdougb
1209170222Sdougb	/* Sanity check: */
1210170222Sdougb	REQUIRE(context != (isc_sha512_t *)0);
1211170222Sdougb
1212170222Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
1213170222Sdougb	if (digest != (isc_uint8_t*)0) {
1214170222Sdougb		isc_sha512_last(context);
1215170222Sdougb
1216170222Sdougb		/* Save the hash data for output: */
1217170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
1218170222Sdougb		{
1219170222Sdougb			/* Convert TO host byte order */
1220170222Sdougb			int	j;
1221170222Sdougb			for (j = 0; j < 8; j++) {
1222170222Sdougb				REVERSE64(context->state[j],context->state[j]);
1223170222Sdougb				*d++ = context->state[j];
1224170222Sdougb			}
1225170222Sdougb		}
1226170222Sdougb#else
1227262706Serwin		memmove(d, context->state, ISC_SHA512_DIGESTLENGTH);
1228170222Sdougb#endif
1229170222Sdougb	}
1230170222Sdougb
1231170222Sdougb	/* Zero out state data */
1232234010Sdougb	memset(context, 0, sizeof(*context));
1233170222Sdougb}
1234170222Sdougb
1235170222Sdougb
1236170222Sdougb/*** SHA-384: *********************************************************/
1237170222Sdougbvoid
1238170222Sdougbisc_sha384_init(isc_sha384_t *context) {
1239170222Sdougb	if (context == (isc_sha384_t *)0) {
1240170222Sdougb		return;
1241170222Sdougb	}
1242262706Serwin	memmove(context->state, sha384_initial_hash_value,
1243262706Serwin		ISC_SHA512_DIGESTLENGTH);
1244170222Sdougb	memset(context->buffer, 0, ISC_SHA384_BLOCK_LENGTH);
1245170222Sdougb	context->bitcount[0] = context->bitcount[1] = 0;
1246170222Sdougb}
1247170222Sdougb
1248193149Sdougbvoid
1249204619Sdougbisc_sha384_invalidate(isc_sha384_t *context) {
1250204619Sdougb	memset(context, 0, sizeof(isc_sha384_t));
1251204619Sdougb}
1252204619Sdougb
1253204619Sdougbvoid
1254170222Sdougbisc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
1255170222Sdougb	isc_sha512_update((isc_sha512_t *)context, data, len);
1256170222Sdougb}
1257170222Sdougb
1258193149Sdougbvoid
1259170222Sdougbisc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
1260170222Sdougb	isc_uint64_t	*d = (isc_uint64_t*)digest;
1261170222Sdougb
1262170222Sdougb	/* Sanity check: */
1263170222Sdougb	REQUIRE(context != (isc_sha384_t *)0);
1264170222Sdougb
1265170222Sdougb	/* If no digest buffer is passed, we don't bother doing this: */
1266170222Sdougb	if (digest != (isc_uint8_t*)0) {
1267170222Sdougb		isc_sha512_last((isc_sha512_t *)context);
1268170222Sdougb
1269170222Sdougb		/* Save the hash data for output: */
1270170222Sdougb#if BYTE_ORDER == LITTLE_ENDIAN
1271170222Sdougb		{
1272170222Sdougb			/* Convert TO host byte order */
1273170222Sdougb			int	j;
1274170222Sdougb			for (j = 0; j < 6; j++) {
1275170222Sdougb				REVERSE64(context->state[j],context->state[j]);
1276170222Sdougb				*d++ = context->state[j];
1277170222Sdougb			}
1278170222Sdougb		}
1279170222Sdougb#else
1280262706Serwin		memmove(d, context->state, ISC_SHA384_DIGESTLENGTH);
1281170222Sdougb#endif
1282170222Sdougb	}
1283170222Sdougb
1284170222Sdougb	/* Zero out state data */
1285234010Sdougb	memset(context, 0, sizeof(*context));
1286170222Sdougb}
1287224092Sdougb#endif /* !ISC_PLATFORM_OPENSSLHASH */
1288170222Sdougb
1289224092Sdougb/*
1290224092Sdougb * Constant used by SHA256/384/512_End() functions for converting the
1291224092Sdougb * digest to a readable hexadecimal character string:
1292224092Sdougb */
1293224092Sdougbstatic const char *sha2_hex_digits = "0123456789abcdef";
1294224092Sdougb
1295170222Sdougbchar *
1296224092Sdougbisc_sha224_end(isc_sha224_t *context, char buffer[]) {
1297224092Sdougb	isc_uint8_t	digest[ISC_SHA224_DIGESTLENGTH], *d = digest;
1298224092Sdougb	unsigned int	i;
1299224092Sdougb
1300224092Sdougb	/* Sanity check: */
1301224092Sdougb	REQUIRE(context != (isc_sha224_t *)0);
1302224092Sdougb
1303224092Sdougb	if (buffer != (char*)0) {
1304224092Sdougb		isc_sha224_final(digest, context);
1305224092Sdougb
1306224092Sdougb		for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) {
1307224092Sdougb			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1308224092Sdougb			*buffer++ = sha2_hex_digits[*d & 0x0f];
1309224092Sdougb			d++;
1310224092Sdougb		}
1311224092Sdougb		*buffer = (char)0;
1312224092Sdougb	} else {
1313224092Sdougb#ifdef ISC_PLATFORM_OPENSSLHASH
1314224092Sdougb		EVP_MD_CTX_cleanup(context);
1315224092Sdougb#else
1316234010Sdougb		memset(context, 0, sizeof(*context));
1317224092Sdougb#endif
1318224092Sdougb	}
1319224092Sdougb	memset(digest, 0, ISC_SHA224_DIGESTLENGTH);
1320224092Sdougb	return buffer;
1321224092Sdougb}
1322224092Sdougb
1323224092Sdougbchar *
1324224092Sdougbisc_sha224_data(const isc_uint8_t *data, size_t len,
1325224092Sdougb		char digest[ISC_SHA224_DIGESTSTRINGLENGTH])
1326224092Sdougb{
1327224092Sdougb	isc_sha224_t context;
1328224092Sdougb
1329224092Sdougb	isc_sha224_init(&context);
1330224092Sdougb	isc_sha224_update(&context, data, len);
1331224092Sdougb	return (isc_sha224_end(&context, digest));
1332224092Sdougb}
1333224092Sdougb
1334224092Sdougbchar *
1335224092Sdougbisc_sha256_end(isc_sha256_t *context, char buffer[]) {
1336224092Sdougb	isc_uint8_t	digest[ISC_SHA256_DIGESTLENGTH], *d = digest;
1337224092Sdougb	unsigned int	i;
1338224092Sdougb
1339224092Sdougb	/* Sanity check: */
1340224092Sdougb	REQUIRE(context != (isc_sha256_t *)0);
1341224092Sdougb
1342224092Sdougb	if (buffer != (char*)0) {
1343224092Sdougb		isc_sha256_final(digest, context);
1344224092Sdougb
1345224092Sdougb		for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) {
1346224092Sdougb			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1347224092Sdougb			*buffer++ = sha2_hex_digits[*d & 0x0f];
1348224092Sdougb			d++;
1349224092Sdougb		}
1350224092Sdougb		*buffer = (char)0;
1351224092Sdougb	} else {
1352224092Sdougb#ifdef ISC_PLATFORM_OPENSSLHASH
1353224092Sdougb		EVP_MD_CTX_cleanup(context);
1354224092Sdougb#else
1355234010Sdougb		memset(context, 0, sizeof(*context));
1356224092Sdougb#endif
1357224092Sdougb	}
1358224092Sdougb	memset(digest, 0, ISC_SHA256_DIGESTLENGTH);
1359224092Sdougb	return buffer;
1360224092Sdougb}
1361224092Sdougb
1362224092Sdougbchar *
1363224092Sdougbisc_sha256_data(const isc_uint8_t* data, size_t len,
1364224092Sdougb		char digest[ISC_SHA256_DIGESTSTRINGLENGTH])
1365224092Sdougb{
1366224092Sdougb	isc_sha256_t context;
1367224092Sdougb
1368224092Sdougb	isc_sha256_init(&context);
1369224092Sdougb	isc_sha256_update(&context, data, len);
1370224092Sdougb	return (isc_sha256_end(&context, digest));
1371224092Sdougb}
1372224092Sdougb
1373224092Sdougbchar *
1374224092Sdougbisc_sha512_end(isc_sha512_t *context, char buffer[]) {
1375224092Sdougb	isc_uint8_t	digest[ISC_SHA512_DIGESTLENGTH], *d = digest;
1376224092Sdougb	unsigned int	i;
1377224092Sdougb
1378224092Sdougb	/* Sanity check: */
1379224092Sdougb	REQUIRE(context != (isc_sha512_t *)0);
1380224092Sdougb
1381224092Sdougb	if (buffer != (char*)0) {
1382224092Sdougb		isc_sha512_final(digest, context);
1383224092Sdougb
1384224092Sdougb		for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) {
1385224092Sdougb			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1386224092Sdougb			*buffer++ = sha2_hex_digits[*d & 0x0f];
1387224092Sdougb			d++;
1388224092Sdougb		}
1389224092Sdougb		*buffer = (char)0;
1390224092Sdougb	} else {
1391224092Sdougb#ifdef ISC_PLATFORM_OPENSSLHASH
1392224092Sdougb		EVP_MD_CTX_cleanup(context);
1393224092Sdougb#else
1394234010Sdougb		memset(context, 0, sizeof(*context));
1395224092Sdougb#endif
1396224092Sdougb	}
1397224092Sdougb	memset(digest, 0, ISC_SHA512_DIGESTLENGTH);
1398224092Sdougb	return buffer;
1399224092Sdougb}
1400224092Sdougb
1401224092Sdougbchar *
1402224092Sdougbisc_sha512_data(const isc_uint8_t *data, size_t len,
1403224092Sdougb		char digest[ISC_SHA512_DIGESTSTRINGLENGTH])
1404224092Sdougb{
1405224092Sdougb	isc_sha512_t 	context;
1406224092Sdougb
1407224092Sdougb	isc_sha512_init(&context);
1408224092Sdougb	isc_sha512_update(&context, data, len);
1409224092Sdougb	return (isc_sha512_end(&context, digest));
1410224092Sdougb}
1411224092Sdougb
1412224092Sdougbchar *
1413170222Sdougbisc_sha384_end(isc_sha384_t *context, char buffer[]) {
1414170222Sdougb	isc_uint8_t	digest[ISC_SHA384_DIGESTLENGTH], *d = digest;
1415170222Sdougb	unsigned int	i;
1416170222Sdougb
1417170222Sdougb	/* Sanity check: */
1418170222Sdougb	REQUIRE(context != (isc_sha384_t *)0);
1419170222Sdougb
1420170222Sdougb	if (buffer != (char*)0) {
1421170222Sdougb		isc_sha384_final(digest, context);
1422170222Sdougb
1423170222Sdougb		for (i = 0; i < ISC_SHA384_DIGESTLENGTH; i++) {
1424170222Sdougb			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1425170222Sdougb			*buffer++ = sha2_hex_digits[*d & 0x0f];
1426170222Sdougb			d++;
1427170222Sdougb		}
1428170222Sdougb		*buffer = (char)0;
1429170222Sdougb	} else {
1430224092Sdougb#ifdef ISC_PLATFORM_OPENSSLHASH
1431224092Sdougb		EVP_MD_CTX_cleanup(context);
1432224092Sdougb#else
1433234010Sdougb		memset(context, 0, sizeof(*context));
1434224092Sdougb#endif
1435170222Sdougb	}
1436170222Sdougb	memset(digest, 0, ISC_SHA384_DIGESTLENGTH);
1437170222Sdougb	return buffer;
1438170222Sdougb}
1439170222Sdougb
1440224092Sdougbchar *
1441170222Sdougbisc_sha384_data(const isc_uint8_t *data, size_t len,
1442193149Sdougb		char digest[ISC_SHA384_DIGESTSTRINGLENGTH])
1443170222Sdougb{
1444170222Sdougb	isc_sha384_t context;
1445170222Sdougb
1446170222Sdougb	isc_sha384_init(&context);
1447170222Sdougb	isc_sha384_update(&context, data, len);
1448170222Sdougb	return (isc_sha384_end(&context, digest));
1449170222Sdougb}
1450