xref: /dragonfly/contrib/ldns/sha2.c (revision ee791feb)
1825eb42bSJan Lentfer /*
2825eb42bSJan Lentfer  * FILE:	sha2.c
3825eb42bSJan Lentfer  * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
4825eb42bSJan Lentfer  *
5825eb42bSJan Lentfer  * Copyright (c) 2000-2001, Aaron D. Gifford
6825eb42bSJan Lentfer  * All rights reserved.
7825eb42bSJan Lentfer  *
8825eb42bSJan Lentfer  * Modified by Jelte Jansen to fit in ldns, and not clash with any
9825eb42bSJan Lentfer  * system-defined SHA code.
10825eb42bSJan Lentfer  * Changes:
11825eb42bSJan Lentfer  * - Renamed (external) functions and constants to fit ldns style
12825eb42bSJan Lentfer  * - Removed _End and _Data functions
13825eb42bSJan Lentfer  * - Added ldns_shaX(data, len, digest) convenience functions
14825eb42bSJan Lentfer  * - Removed prototypes of _Transform functions and made those static
15825eb42bSJan Lentfer  *
16825eb42bSJan Lentfer  * Redistribution and use in source and binary forms, with or without
17825eb42bSJan Lentfer  * modification, are permitted provided that the following conditions
18825eb42bSJan Lentfer  * are met:
19825eb42bSJan Lentfer  * 1. Redistributions of source code must retain the above copyright
20825eb42bSJan Lentfer  *    notice, this list of conditions and the following disclaimer.
21825eb42bSJan Lentfer  * 2. Redistributions in binary form must reproduce the above copyright
22825eb42bSJan Lentfer  *    notice, this list of conditions and the following disclaimer in the
23825eb42bSJan Lentfer  *    documentation and/or other materials provided with the distribution.
24825eb42bSJan Lentfer  * 3. Neither the name of the copyright holder nor the names of contributors
25825eb42bSJan Lentfer  *    may be used to endorse or promote products derived from this software
26825eb42bSJan Lentfer  *    without specific prior written permission.
27825eb42bSJan Lentfer  *
28825eb42bSJan Lentfer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
29825eb42bSJan Lentfer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30825eb42bSJan Lentfer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31825eb42bSJan Lentfer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
32825eb42bSJan Lentfer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33825eb42bSJan Lentfer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34825eb42bSJan Lentfer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35825eb42bSJan Lentfer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36825eb42bSJan Lentfer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37825eb42bSJan Lentfer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38825eb42bSJan Lentfer  * SUCH DAMAGE.
39825eb42bSJan Lentfer  *
40825eb42bSJan Lentfer  * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
41825eb42bSJan Lentfer  */
42825eb42bSJan Lentfer 
43825eb42bSJan Lentfer #include <ldns/config.h>
44825eb42bSJan Lentfer #include <string.h>	/* memcpy()/memset() or bcopy()/bzero() */
45825eb42bSJan Lentfer #include <assert.h>	/* assert() */
46825eb42bSJan Lentfer #include <ldns/sha2.h>
47825eb42bSJan Lentfer 
48825eb42bSJan Lentfer /*
49825eb42bSJan Lentfer  * ASSERT NOTE:
50825eb42bSJan Lentfer  * Some sanity checking code is included using assert().  On my FreeBSD
51825eb42bSJan Lentfer  * system, this additional code can be removed by compiling with NDEBUG
52825eb42bSJan Lentfer  * defined.  Check your own systems manpage on assert() to see how to
53825eb42bSJan Lentfer  * compile WITHOUT the sanity checking code on your system.
54825eb42bSJan Lentfer  *
55825eb42bSJan Lentfer  * UNROLLED TRANSFORM LOOP NOTE:
56825eb42bSJan Lentfer  * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
57825eb42bSJan Lentfer  * loop version for the hash transform rounds (defined using macros
58825eb42bSJan Lentfer  * later in this file).  Either define on the command line, for example:
59825eb42bSJan Lentfer  *
60825eb42bSJan Lentfer  *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
61825eb42bSJan Lentfer  *
62825eb42bSJan Lentfer  * or define below:
63825eb42bSJan Lentfer  *
64825eb42bSJan Lentfer  *   #define SHA2_UNROLL_TRANSFORM
65825eb42bSJan Lentfer  *
66825eb42bSJan Lentfer  */
67825eb42bSJan Lentfer 
68825eb42bSJan Lentfer 
69825eb42bSJan Lentfer /*** SHA-256/384/512 Machine Architecture Definitions *****************/
70825eb42bSJan Lentfer /*
71825eb42bSJan Lentfer  * BYTE_ORDER NOTE:
72825eb42bSJan Lentfer  *
73825eb42bSJan Lentfer  * Please make sure that your system defines BYTE_ORDER.  If your
74825eb42bSJan Lentfer  * architecture is little-endian, make sure it also defines
75825eb42bSJan Lentfer  * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
76*ee791febSAntonio Huete Jimenez  * equivalent.
77825eb42bSJan Lentfer  *
78825eb42bSJan Lentfer  * If your system does not define the above, then you can do so by
79825eb42bSJan Lentfer  * hand like this:
80825eb42bSJan Lentfer  *
81825eb42bSJan Lentfer  *   #define LITTLE_ENDIAN 1234
82825eb42bSJan Lentfer  *   #define BIG_ENDIAN    4321
83825eb42bSJan Lentfer  *
84825eb42bSJan Lentfer  * And for little-endian machines, add:
85825eb42bSJan Lentfer  *
86825eb42bSJan Lentfer  *   #define BYTE_ORDER LITTLE_ENDIAN
87825eb42bSJan Lentfer  *
88825eb42bSJan Lentfer  * Or for big-endian machines:
89825eb42bSJan Lentfer  *
90825eb42bSJan Lentfer  *   #define BYTE_ORDER BIG_ENDIAN
91825eb42bSJan Lentfer  *
92825eb42bSJan Lentfer  * The FreeBSD machine this was written on defines BYTE_ORDER
93825eb42bSJan Lentfer  * appropriately by including <sys/types.h> (which in turn includes
94825eb42bSJan Lentfer  * <machine/endian.h> where the appropriate definitions are actually
95825eb42bSJan Lentfer  * made).
96825eb42bSJan Lentfer  */
97825eb42bSJan Lentfer #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
98825eb42bSJan Lentfer #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
99825eb42bSJan Lentfer #endif
100825eb42bSJan Lentfer 
101825eb42bSJan Lentfer typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
102825eb42bSJan Lentfer typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
103fd185f4dSJan Lentfer #ifdef S_SPLINT_S
104fd185f4dSJan Lentfer typedef unsigned long long sha2_word64; /* lint 8 bytes */
105fd185f4dSJan Lentfer #else
106825eb42bSJan Lentfer typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
107fd185f4dSJan Lentfer #endif
108825eb42bSJan Lentfer 
109825eb42bSJan Lentfer /*** SHA-256/384/512 Various Length Definitions ***********************/
110825eb42bSJan Lentfer /* NOTE: Most of these are in sha2.h */
111825eb42bSJan Lentfer #define ldns_sha256_SHORT_BLOCK_LENGTH	(LDNS_SHA256_BLOCK_LENGTH - 8)
112825eb42bSJan Lentfer #define ldns_sha384_SHORT_BLOCK_LENGTH	(LDNS_SHA384_BLOCK_LENGTH - 16)
113825eb42bSJan Lentfer #define ldns_sha512_SHORT_BLOCK_LENGTH	(LDNS_SHA512_BLOCK_LENGTH - 16)
114825eb42bSJan Lentfer 
115825eb42bSJan Lentfer 
116825eb42bSJan Lentfer /*** ENDIAN REVERSAL MACROS *******************************************/
117825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
118825eb42bSJan Lentfer #define REVERSE32(w,x)	{ \
119825eb42bSJan Lentfer 	sha2_word32 tmp = (w); \
120825eb42bSJan Lentfer 	tmp = (tmp >> 16) | (tmp << 16); \
121825eb42bSJan Lentfer 	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
122825eb42bSJan Lentfer }
123fd185f4dSJan Lentfer #ifndef S_SPLINT_S
124825eb42bSJan Lentfer #define REVERSE64(w,x)	{ \
125825eb42bSJan Lentfer 	sha2_word64 tmp = (w); \
126825eb42bSJan Lentfer 	tmp = (tmp >> 32) | (tmp << 32); \
127825eb42bSJan Lentfer 	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
128825eb42bSJan Lentfer 	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
129825eb42bSJan Lentfer 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
130825eb42bSJan Lentfer 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
131825eb42bSJan Lentfer }
132fd185f4dSJan Lentfer #else /* splint */
133fd185f4dSJan Lentfer #define REVERSE64(w,x) /* splint */
134fd185f4dSJan Lentfer #endif /* splint */
135825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */
136825eb42bSJan Lentfer 
137825eb42bSJan Lentfer /*
138825eb42bSJan Lentfer  * Macro for incrementally adding the unsigned 64-bit integer n to the
139825eb42bSJan Lentfer  * unsigned 128-bit integer (represented using a two-element array of
140825eb42bSJan Lentfer  * 64-bit words):
141825eb42bSJan Lentfer  */
142825eb42bSJan Lentfer #define ADDINC128(w,n)	{ \
143825eb42bSJan Lentfer 	(w)[0] += (sha2_word64)(n); \
144825eb42bSJan Lentfer 	if ((w)[0] < (n)) { \
145825eb42bSJan Lentfer 		(w)[1]++; \
146825eb42bSJan Lentfer 	} \
147825eb42bSJan Lentfer }
148fd185f4dSJan Lentfer #ifdef S_SPLINT_S
149fd185f4dSJan Lentfer #undef ADDINC128
150fd185f4dSJan Lentfer #define ADDINC128(w,n) /* splint */
151fd185f4dSJan Lentfer #endif
152825eb42bSJan Lentfer 
153825eb42bSJan Lentfer /*
154825eb42bSJan Lentfer  * Macros for copying blocks of memory and for zeroing out ranges
155825eb42bSJan Lentfer  * of memory.  Using these macros makes it easy to switch from
156825eb42bSJan Lentfer  * using memset()/memcpy() and using bzero()/bcopy().
157825eb42bSJan Lentfer  *
158825eb42bSJan Lentfer  * Please define either SHA2_USE_MEMSET_MEMCPY or define
159825eb42bSJan Lentfer  * SHA2_USE_BZERO_BCOPY depending on which function set you
160825eb42bSJan Lentfer  * choose to use:
161825eb42bSJan Lentfer  */
162825eb42bSJan Lentfer #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
163825eb42bSJan Lentfer /* Default to memset()/memcpy() if no option is specified */
164825eb42bSJan Lentfer #define	SHA2_USE_MEMSET_MEMCPY	1
165825eb42bSJan Lentfer #endif
166825eb42bSJan Lentfer #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
167825eb42bSJan Lentfer /* Abort with an error if BOTH options are defined */
168825eb42bSJan Lentfer #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
169825eb42bSJan Lentfer #endif
170825eb42bSJan Lentfer 
171825eb42bSJan Lentfer #ifdef SHA2_USE_MEMSET_MEMCPY
172825eb42bSJan Lentfer #define MEMSET_BZERO(p,l)	memset((p), 0, (l))
173825eb42bSJan Lentfer #define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
174825eb42bSJan Lentfer #endif
175825eb42bSJan Lentfer #ifdef SHA2_USE_BZERO_BCOPY
176825eb42bSJan Lentfer #define MEMSET_BZERO(p,l)	bzero((p), (l))
177825eb42bSJan Lentfer #define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
178825eb42bSJan Lentfer #endif
179825eb42bSJan Lentfer 
180825eb42bSJan Lentfer 
181825eb42bSJan Lentfer /*** THE SIX LOGICAL FUNCTIONS ****************************************/
182825eb42bSJan Lentfer /*
183825eb42bSJan Lentfer  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
184825eb42bSJan Lentfer  *
185825eb42bSJan Lentfer  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
186825eb42bSJan Lentfer  *   S is a ROTATION) because the SHA-256/384/512 description document
187825eb42bSJan Lentfer  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
188825eb42bSJan Lentfer  *   same "backwards" definition.
189825eb42bSJan Lentfer  */
190825eb42bSJan Lentfer /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
191825eb42bSJan Lentfer #define R(b,x) 		((x) >> (b))
192825eb42bSJan Lentfer /* 32-bit Rotate-right (used in SHA-256): */
193825eb42bSJan Lentfer #define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
194825eb42bSJan Lentfer /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
195825eb42bSJan Lentfer #define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
196825eb42bSJan Lentfer 
197825eb42bSJan Lentfer /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
198825eb42bSJan Lentfer #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
199825eb42bSJan Lentfer #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
200825eb42bSJan Lentfer 
201825eb42bSJan Lentfer /* Four of six logical functions used in SHA-256: */
202825eb42bSJan Lentfer #define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
203825eb42bSJan Lentfer #define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
204825eb42bSJan Lentfer #define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
205825eb42bSJan Lentfer #define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
206825eb42bSJan Lentfer 
207825eb42bSJan Lentfer /* Four of six logical functions used in SHA-384 and SHA-512: */
208825eb42bSJan Lentfer #define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
209825eb42bSJan Lentfer #define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
210825eb42bSJan Lentfer #define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
211825eb42bSJan Lentfer #define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
212825eb42bSJan Lentfer 
213825eb42bSJan Lentfer /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
214825eb42bSJan Lentfer /* Hash constant words K for SHA-256: */
215825eb42bSJan Lentfer static const sha2_word32 K256[64] = {
216825eb42bSJan Lentfer 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
217825eb42bSJan Lentfer 	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
218825eb42bSJan Lentfer 	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
219825eb42bSJan Lentfer 	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
220825eb42bSJan Lentfer 	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
221825eb42bSJan Lentfer 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
222825eb42bSJan Lentfer 	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
223825eb42bSJan Lentfer 	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
224825eb42bSJan Lentfer 	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
225825eb42bSJan Lentfer 	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
226825eb42bSJan Lentfer 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
227825eb42bSJan Lentfer 	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
228825eb42bSJan Lentfer 	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
229825eb42bSJan Lentfer 	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
230825eb42bSJan Lentfer 	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
231825eb42bSJan Lentfer 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
232825eb42bSJan Lentfer };
233825eb42bSJan Lentfer 
234825eb42bSJan Lentfer /* initial hash value H for SHA-256: */
235825eb42bSJan Lentfer static const sha2_word32 ldns_sha256_initial_hash_value[8] = {
236825eb42bSJan Lentfer 	0x6a09e667UL,
237825eb42bSJan Lentfer 	0xbb67ae85UL,
238825eb42bSJan Lentfer 	0x3c6ef372UL,
239825eb42bSJan Lentfer 	0xa54ff53aUL,
240825eb42bSJan Lentfer 	0x510e527fUL,
241825eb42bSJan Lentfer 	0x9b05688cUL,
242825eb42bSJan Lentfer 	0x1f83d9abUL,
243825eb42bSJan Lentfer 	0x5be0cd19UL
244825eb42bSJan Lentfer };
245825eb42bSJan Lentfer 
246825eb42bSJan Lentfer /* Hash constant words K for SHA-384 and SHA-512: */
247825eb42bSJan Lentfer static const sha2_word64 K512[80] = {
248825eb42bSJan Lentfer 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
249825eb42bSJan Lentfer 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
250825eb42bSJan Lentfer 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
251825eb42bSJan Lentfer 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
252825eb42bSJan Lentfer 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
253825eb42bSJan Lentfer 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
254825eb42bSJan Lentfer 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
255825eb42bSJan Lentfer 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
256825eb42bSJan Lentfer 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
257825eb42bSJan Lentfer 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
258825eb42bSJan Lentfer 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
259825eb42bSJan Lentfer 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
260825eb42bSJan Lentfer 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
261825eb42bSJan Lentfer 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
262825eb42bSJan Lentfer 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
263825eb42bSJan Lentfer 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
264825eb42bSJan Lentfer 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
265825eb42bSJan Lentfer 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
266825eb42bSJan Lentfer 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
267825eb42bSJan Lentfer 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
268825eb42bSJan Lentfer 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
269825eb42bSJan Lentfer 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
270825eb42bSJan Lentfer 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
271825eb42bSJan Lentfer 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
272825eb42bSJan Lentfer 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
273825eb42bSJan Lentfer 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
274825eb42bSJan Lentfer 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
275825eb42bSJan Lentfer 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
276825eb42bSJan Lentfer 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
277825eb42bSJan Lentfer 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
278825eb42bSJan Lentfer 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
279825eb42bSJan Lentfer 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
280825eb42bSJan Lentfer 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
281825eb42bSJan Lentfer 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
282825eb42bSJan Lentfer 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
283825eb42bSJan Lentfer 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
284825eb42bSJan Lentfer 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
285825eb42bSJan Lentfer 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
286825eb42bSJan Lentfer 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
287825eb42bSJan Lentfer 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
288825eb42bSJan Lentfer };
289825eb42bSJan Lentfer 
290825eb42bSJan Lentfer /* initial hash value H for SHA-384 */
291825eb42bSJan Lentfer static const sha2_word64 sha384_initial_hash_value[8] = {
292825eb42bSJan Lentfer 	0xcbbb9d5dc1059ed8ULL,
293825eb42bSJan Lentfer 	0x629a292a367cd507ULL,
294825eb42bSJan Lentfer 	0x9159015a3070dd17ULL,
295825eb42bSJan Lentfer 	0x152fecd8f70e5939ULL,
296825eb42bSJan Lentfer 	0x67332667ffc00b31ULL,
297825eb42bSJan Lentfer 	0x8eb44a8768581511ULL,
298825eb42bSJan Lentfer 	0xdb0c2e0d64f98fa7ULL,
299825eb42bSJan Lentfer 	0x47b5481dbefa4fa4ULL
300825eb42bSJan Lentfer };
301825eb42bSJan Lentfer 
302825eb42bSJan Lentfer /* initial hash value H for SHA-512 */
303825eb42bSJan Lentfer static const sha2_word64 sha512_initial_hash_value[8] = {
304825eb42bSJan Lentfer 	0x6a09e667f3bcc908ULL,
305825eb42bSJan Lentfer 	0xbb67ae8584caa73bULL,
306825eb42bSJan Lentfer 	0x3c6ef372fe94f82bULL,
307825eb42bSJan Lentfer 	0xa54ff53a5f1d36f1ULL,
308825eb42bSJan Lentfer 	0x510e527fade682d1ULL,
309825eb42bSJan Lentfer 	0x9b05688c2b3e6c1fULL,
310825eb42bSJan Lentfer 	0x1f83d9abfb41bd6bULL,
311825eb42bSJan Lentfer 	0x5be0cd19137e2179ULL
312825eb42bSJan Lentfer };
313825eb42bSJan Lentfer 
314825eb42bSJan Lentfer /*** SHA-256: *********************************************************/
ldns_sha256_init(ldns_sha256_CTX * context)315825eb42bSJan Lentfer void ldns_sha256_init(ldns_sha256_CTX* context) {
316825eb42bSJan Lentfer 	if (context == (ldns_sha256_CTX*)0) {
317825eb42bSJan Lentfer 		return;
318825eb42bSJan Lentfer 	}
319825eb42bSJan Lentfer 	MEMCPY_BCOPY(context->state, ldns_sha256_initial_hash_value, LDNS_SHA256_DIGEST_LENGTH);
320825eb42bSJan Lentfer 	MEMSET_BZERO(context->buffer, LDNS_SHA256_BLOCK_LENGTH);
321825eb42bSJan Lentfer 	context->bitcount = 0;
322825eb42bSJan Lentfer }
323825eb42bSJan Lentfer 
324825eb42bSJan Lentfer #ifdef SHA2_UNROLL_TRANSFORM
325825eb42bSJan Lentfer 
326825eb42bSJan Lentfer /* Unrolled SHA-256 round macros: */
327825eb42bSJan Lentfer 
328825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
329825eb42bSJan Lentfer 
330825eb42bSJan Lentfer #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
331825eb42bSJan Lentfer 	REVERSE32(*data++, W256[j]); \
332825eb42bSJan Lentfer 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
333825eb42bSJan Lentfer              K256[j] + W256[j]; \
334825eb42bSJan Lentfer 	(d) += T1; \
335825eb42bSJan Lentfer 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
336825eb42bSJan Lentfer 	j++
337825eb42bSJan Lentfer 
338825eb42bSJan Lentfer 
339825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */
340825eb42bSJan Lentfer 
341825eb42bSJan Lentfer #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
342825eb42bSJan Lentfer 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
343825eb42bSJan Lentfer 	     K256[j] + (W256[j] = *data++); \
344825eb42bSJan Lentfer 	(d) += T1; \
345825eb42bSJan Lentfer 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
346825eb42bSJan Lentfer 	j++
347825eb42bSJan Lentfer 
348825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */
349825eb42bSJan Lentfer 
350825eb42bSJan Lentfer #define ROUND256(a,b,c,d,e,f,g,h)	\
351825eb42bSJan Lentfer 	s0 = W256[(j+1)&0x0f]; \
352825eb42bSJan Lentfer 	s0 = sigma0_256(s0); \
353825eb42bSJan Lentfer 	s1 = W256[(j+14)&0x0f]; \
354825eb42bSJan Lentfer 	s1 = sigma1_256(s1); \
355825eb42bSJan Lentfer 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
356825eb42bSJan Lentfer 	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
357825eb42bSJan Lentfer 	(d) += T1; \
358825eb42bSJan Lentfer 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
359825eb42bSJan Lentfer 	j++
360825eb42bSJan Lentfer 
ldns_sha256_Transform(ldns_sha256_CTX * context,const sha2_word32 * data)361825eb42bSJan Lentfer static void ldns_sha256_Transform(ldns_sha256_CTX* context,
362825eb42bSJan Lentfer                                   const sha2_word32* data) {
363825eb42bSJan Lentfer 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
364825eb42bSJan Lentfer 	sha2_word32	T1, *W256;
365825eb42bSJan Lentfer 	int		j;
366825eb42bSJan Lentfer 
367825eb42bSJan Lentfer 	W256 = (sha2_word32*)context->buffer;
368825eb42bSJan Lentfer 
369825eb42bSJan Lentfer 	/* initialize registers with the prev. intermediate value */
370825eb42bSJan Lentfer 	a = context->state[0];
371825eb42bSJan Lentfer 	b = context->state[1];
372825eb42bSJan Lentfer 	c = context->state[2];
373825eb42bSJan Lentfer 	d = context->state[3];
374825eb42bSJan Lentfer 	e = context->state[4];
375825eb42bSJan Lentfer 	f = context->state[5];
376825eb42bSJan Lentfer 	g = context->state[6];
377825eb42bSJan Lentfer 	h = context->state[7];
378825eb42bSJan Lentfer 
379825eb42bSJan Lentfer 	j = 0;
380825eb42bSJan Lentfer 	do {
381825eb42bSJan Lentfer 		/* Rounds 0 to 15 (unrolled): */
382825eb42bSJan Lentfer 		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
383825eb42bSJan Lentfer 		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
384825eb42bSJan Lentfer 		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
385825eb42bSJan Lentfer 		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
386825eb42bSJan Lentfer 		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
387825eb42bSJan Lentfer 		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
388825eb42bSJan Lentfer 		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
389825eb42bSJan Lentfer 		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
390825eb42bSJan Lentfer 	} while (j < 16);
391825eb42bSJan Lentfer 
392825eb42bSJan Lentfer 	/* Now for the remaining rounds to 64: */
393825eb42bSJan Lentfer 	do {
394825eb42bSJan Lentfer 		ROUND256(a,b,c,d,e,f,g,h);
395825eb42bSJan Lentfer 		ROUND256(h,a,b,c,d,e,f,g);
396825eb42bSJan Lentfer 		ROUND256(g,h,a,b,c,d,e,f);
397825eb42bSJan Lentfer 		ROUND256(f,g,h,a,b,c,d,e);
398825eb42bSJan Lentfer 		ROUND256(e,f,g,h,a,b,c,d);
399825eb42bSJan Lentfer 		ROUND256(d,e,f,g,h,a,b,c);
400825eb42bSJan Lentfer 		ROUND256(c,d,e,f,g,h,a,b);
401825eb42bSJan Lentfer 		ROUND256(b,c,d,e,f,g,h,a);
402825eb42bSJan Lentfer 	} while (j < 64);
403825eb42bSJan Lentfer 
404825eb42bSJan Lentfer 	/* Compute the current intermediate hash value */
405825eb42bSJan Lentfer 	context->state[0] += a;
406825eb42bSJan Lentfer 	context->state[1] += b;
407825eb42bSJan Lentfer 	context->state[2] += c;
408825eb42bSJan Lentfer 	context->state[3] += d;
409825eb42bSJan Lentfer 	context->state[4] += e;
410825eb42bSJan Lentfer 	context->state[5] += f;
411825eb42bSJan Lentfer 	context->state[6] += g;
412825eb42bSJan Lentfer 	context->state[7] += h;
413825eb42bSJan Lentfer 
414825eb42bSJan Lentfer 	/* Clean up */
415825eb42bSJan Lentfer 	a = b = c = d = e = f = g = h = T1 = 0;
416825eb42bSJan Lentfer }
417825eb42bSJan Lentfer 
418825eb42bSJan Lentfer #else /* SHA2_UNROLL_TRANSFORM */
419825eb42bSJan Lentfer 
ldns_sha256_Transform(ldns_sha256_CTX * context,const sha2_word32 * data)420825eb42bSJan Lentfer static void ldns_sha256_Transform(ldns_sha256_CTX* context,
421825eb42bSJan Lentfer                                   const sha2_word32* data) {
422825eb42bSJan Lentfer 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
423825eb42bSJan Lentfer 	sha2_word32	T1, T2, *W256;
424825eb42bSJan Lentfer 	int		j;
425825eb42bSJan Lentfer 
426825eb42bSJan Lentfer 	W256 = (sha2_word32*)context->buffer;
427825eb42bSJan Lentfer 
428825eb42bSJan Lentfer 	/* initialize registers with the prev. intermediate value */
429825eb42bSJan Lentfer 	a = context->state[0];
430825eb42bSJan Lentfer 	b = context->state[1];
431825eb42bSJan Lentfer 	c = context->state[2];
432825eb42bSJan Lentfer 	d = context->state[3];
433825eb42bSJan Lentfer 	e = context->state[4];
434825eb42bSJan Lentfer 	f = context->state[5];
435825eb42bSJan Lentfer 	g = context->state[6];
436825eb42bSJan Lentfer 	h = context->state[7];
437825eb42bSJan Lentfer 
438825eb42bSJan Lentfer 	j = 0;
439825eb42bSJan Lentfer 	do {
440825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
441825eb42bSJan Lentfer 		/* Copy data while converting to host byte order */
442825eb42bSJan Lentfer 		REVERSE32(*data++,W256[j]);
443825eb42bSJan Lentfer 		/* Apply the SHA-256 compression function to update a..h */
444825eb42bSJan Lentfer 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
445825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */
446825eb42bSJan Lentfer 		/* Apply the SHA-256 compression function to update a..h with copy */
447825eb42bSJan Lentfer 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
448825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */
449825eb42bSJan Lentfer 		T2 = Sigma0_256(a) + Maj(a, b, c);
450825eb42bSJan Lentfer 		h = g;
451825eb42bSJan Lentfer 		g = f;
452825eb42bSJan Lentfer 		f = e;
453825eb42bSJan Lentfer 		e = d + T1;
454825eb42bSJan Lentfer 		d = c;
455825eb42bSJan Lentfer 		c = b;
456825eb42bSJan Lentfer 		b = a;
457825eb42bSJan Lentfer 		a = T1 + T2;
458825eb42bSJan Lentfer 
459825eb42bSJan Lentfer 		j++;
460825eb42bSJan Lentfer 	} while (j < 16);
461825eb42bSJan Lentfer 
462825eb42bSJan Lentfer 	do {
463825eb42bSJan Lentfer 		/* Part of the message block expansion: */
464825eb42bSJan Lentfer 		s0 = W256[(j+1)&0x0f];
465825eb42bSJan Lentfer 		s0 = sigma0_256(s0);
466825eb42bSJan Lentfer 		s1 = W256[(j+14)&0x0f];
467825eb42bSJan Lentfer 		s1 = sigma1_256(s1);
468825eb42bSJan Lentfer 
469825eb42bSJan Lentfer 		/* Apply the SHA-256 compression function to update a..h */
470825eb42bSJan Lentfer 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
471825eb42bSJan Lentfer 		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
472825eb42bSJan Lentfer 		T2 = Sigma0_256(a) + Maj(a, b, c);
473825eb42bSJan Lentfer 		h = g;
474825eb42bSJan Lentfer 		g = f;
475825eb42bSJan Lentfer 		f = e;
476825eb42bSJan Lentfer 		e = d + T1;
477825eb42bSJan Lentfer 		d = c;
478825eb42bSJan Lentfer 		c = b;
479825eb42bSJan Lentfer 		b = a;
480825eb42bSJan Lentfer 		a = T1 + T2;
481825eb42bSJan Lentfer 
482825eb42bSJan Lentfer 		j++;
483825eb42bSJan Lentfer 	} while (j < 64);
484825eb42bSJan Lentfer 
485825eb42bSJan Lentfer 	/* Compute the current intermediate hash value */
486825eb42bSJan Lentfer 	context->state[0] += a;
487825eb42bSJan Lentfer 	context->state[1] += b;
488825eb42bSJan Lentfer 	context->state[2] += c;
489825eb42bSJan Lentfer 	context->state[3] += d;
490825eb42bSJan Lentfer 	context->state[4] += e;
491825eb42bSJan Lentfer 	context->state[5] += f;
492825eb42bSJan Lentfer 	context->state[6] += g;
493825eb42bSJan Lentfer 	context->state[7] += h;
494825eb42bSJan Lentfer 
495825eb42bSJan Lentfer 	/* Clean up */
496825eb42bSJan Lentfer 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
497819dec71SDaniel Fojt 	(void)a;
498825eb42bSJan Lentfer }
499825eb42bSJan Lentfer 
500825eb42bSJan Lentfer #endif /* SHA2_UNROLL_TRANSFORM */
501825eb42bSJan Lentfer 
ldns_sha256_update(ldns_sha256_CTX * context,const sha2_byte * data,size_t len)502825eb42bSJan Lentfer void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) {
503fd185f4dSJan Lentfer 	size_t freespace, usedspace;
504825eb42bSJan Lentfer 
505825eb42bSJan Lentfer 	if (len == 0) {
506825eb42bSJan Lentfer 		/* Calling with no data is valid - we do nothing */
507825eb42bSJan Lentfer 		return;
508825eb42bSJan Lentfer 	}
509825eb42bSJan Lentfer 
510825eb42bSJan Lentfer 	/* Sanity check: */
511825eb42bSJan Lentfer 	assert(context != (ldns_sha256_CTX*)0 && data != (sha2_byte*)0);
512825eb42bSJan Lentfer 
513825eb42bSJan Lentfer 	usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
514825eb42bSJan Lentfer 	if (usedspace > 0) {
515825eb42bSJan Lentfer 		/* Calculate how much free space is available in the buffer */
516825eb42bSJan Lentfer 		freespace = LDNS_SHA256_BLOCK_LENGTH - usedspace;
517825eb42bSJan Lentfer 
518825eb42bSJan Lentfer 		if (len >= freespace) {
519825eb42bSJan Lentfer 			/* Fill the buffer completely and process it */
520825eb42bSJan Lentfer 			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
521825eb42bSJan Lentfer 			context->bitcount += freespace << 3;
522825eb42bSJan Lentfer 			len -= freespace;
523825eb42bSJan Lentfer 			data += freespace;
524825eb42bSJan Lentfer 			ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
525825eb42bSJan Lentfer 		} else {
526825eb42bSJan Lentfer 			/* The buffer is not yet full */
527825eb42bSJan Lentfer 			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
528825eb42bSJan Lentfer 			context->bitcount += len << 3;
529825eb42bSJan Lentfer 			/* Clean up: */
530825eb42bSJan Lentfer 			usedspace = freespace = 0;
531819dec71SDaniel Fojt 			(void)usedspace;
532825eb42bSJan Lentfer 			return;
533825eb42bSJan Lentfer 		}
534825eb42bSJan Lentfer 	}
535825eb42bSJan Lentfer 	while (len >= LDNS_SHA256_BLOCK_LENGTH) {
536825eb42bSJan Lentfer 		/* Process as many complete blocks as we can */
537825eb42bSJan Lentfer 		ldns_sha256_Transform(context, (sha2_word32*)data);
538825eb42bSJan Lentfer 		context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3;
539825eb42bSJan Lentfer 		len -= LDNS_SHA256_BLOCK_LENGTH;
540825eb42bSJan Lentfer 		data += LDNS_SHA256_BLOCK_LENGTH;
541825eb42bSJan Lentfer 	}
542825eb42bSJan Lentfer 	if (len > 0) {
543825eb42bSJan Lentfer 		/* There's left-overs, so save 'em */
544825eb42bSJan Lentfer 		MEMCPY_BCOPY(context->buffer, data, len);
545825eb42bSJan Lentfer 		context->bitcount += len << 3;
546825eb42bSJan Lentfer 	}
547825eb42bSJan Lentfer 	/* Clean up: */
548825eb42bSJan Lentfer 	usedspace = freespace = 0;
549819dec71SDaniel Fojt 	(void)usedspace;
550825eb42bSJan Lentfer }
551825eb42bSJan Lentfer 
5525340022aSzrj typedef union _ldns_sha2_buffer_union {
5535340022aSzrj         uint8_t*  theChars;
5545340022aSzrj         uint64_t* theLongs;
5555340022aSzrj } ldns_sha2_buffer_union;
5565340022aSzrj 
ldns_sha256_final(sha2_byte digest[LDNS_SHA256_DIGEST_LENGTH],ldns_sha256_CTX * context)557*ee791febSAntonio Huete Jimenez void ldns_sha256_final(sha2_byte digest[LDNS_SHA256_DIGEST_LENGTH], ldns_sha256_CTX* context) {
558825eb42bSJan Lentfer 	sha2_word32	*d = (sha2_word32*)digest;
559fd185f4dSJan Lentfer 	size_t usedspace;
5605340022aSzrj 	ldns_sha2_buffer_union cast_var;
561825eb42bSJan Lentfer 
562825eb42bSJan Lentfer 	/* Sanity check: */
563825eb42bSJan Lentfer 	assert(context != (ldns_sha256_CTX*)0);
564825eb42bSJan Lentfer 
565825eb42bSJan Lentfer 	/* If no digest buffer is passed, we don't bother doing this: */
566825eb42bSJan Lentfer 	if (digest != (sha2_byte*)0) {
567825eb42bSJan Lentfer 		usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
568825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
569825eb42bSJan Lentfer 		/* Convert FROM host byte order */
570825eb42bSJan Lentfer 		REVERSE64(context->bitcount,context->bitcount);
571825eb42bSJan Lentfer #endif
572825eb42bSJan Lentfer 		if (usedspace > 0) {
573825eb42bSJan Lentfer 			/* Begin padding with a 1 bit: */
574825eb42bSJan Lentfer 			context->buffer[usedspace++] = 0x80;
575825eb42bSJan Lentfer 
576825eb42bSJan Lentfer 			if (usedspace <= ldns_sha256_SHORT_BLOCK_LENGTH) {
577825eb42bSJan Lentfer 				/* Set-up for the last transform: */
578825eb42bSJan Lentfer 				MEMSET_BZERO(&context->buffer[usedspace], ldns_sha256_SHORT_BLOCK_LENGTH - usedspace);
579825eb42bSJan Lentfer 			} else {
580825eb42bSJan Lentfer 				if (usedspace < LDNS_SHA256_BLOCK_LENGTH) {
581825eb42bSJan Lentfer 					MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA256_BLOCK_LENGTH - usedspace);
582825eb42bSJan Lentfer 				}
583825eb42bSJan Lentfer 				/* Do second-to-last transform: */
584825eb42bSJan Lentfer 				ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
585825eb42bSJan Lentfer 
586825eb42bSJan Lentfer 				/* And set-up for the last transform: */
587825eb42bSJan Lentfer 				MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
588825eb42bSJan Lentfer 			}
589825eb42bSJan Lentfer 		} else {
590825eb42bSJan Lentfer 			/* Set-up for the last transform: */
591825eb42bSJan Lentfer 			MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
592825eb42bSJan Lentfer 
593825eb42bSJan Lentfer 			/* Begin padding with a 1 bit: */
594825eb42bSJan Lentfer 			*context->buffer = 0x80;
595825eb42bSJan Lentfer 		}
596825eb42bSJan Lentfer 		/* Set the bit count: */
5975340022aSzrj 		cast_var.theChars = context->buffer;
5985340022aSzrj 		cast_var.theLongs[ldns_sha256_SHORT_BLOCK_LENGTH / 8] = context->bitcount;
599825eb42bSJan Lentfer 
600825eb42bSJan Lentfer 		/* final transform: */
601825eb42bSJan Lentfer 		ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
602825eb42bSJan Lentfer 
603825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
604825eb42bSJan Lentfer 		{
605825eb42bSJan Lentfer 			/* Convert TO host byte order */
606825eb42bSJan Lentfer 			int	j;
607825eb42bSJan Lentfer 			for (j = 0; j < 8; j++) {
608825eb42bSJan Lentfer 				REVERSE32(context->state[j],context->state[j]);
609825eb42bSJan Lentfer 				*d++ = context->state[j];
610825eb42bSJan Lentfer 			}
611825eb42bSJan Lentfer 		}
612825eb42bSJan Lentfer #else
613825eb42bSJan Lentfer 		MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH);
614825eb42bSJan Lentfer #endif
615825eb42bSJan Lentfer 	}
616825eb42bSJan Lentfer 
617825eb42bSJan Lentfer 	/* Clean up state data: */
618b5dedccaSJan Lentfer 	MEMSET_BZERO(context, sizeof(ldns_sha256_CTX));
619825eb42bSJan Lentfer 	usedspace = 0;
620819dec71SDaniel Fojt 	(void)usedspace;
621825eb42bSJan Lentfer }
622825eb42bSJan Lentfer 
623825eb42bSJan Lentfer unsigned char *
ldns_sha256(const unsigned char * data,unsigned int data_len,unsigned char * digest)624*ee791febSAntonio Huete Jimenez ldns_sha256(const unsigned char *data, unsigned int data_len, unsigned char *digest)
625825eb42bSJan Lentfer {
626825eb42bSJan Lentfer     ldns_sha256_CTX ctx;
627825eb42bSJan Lentfer     ldns_sha256_init(&ctx);
628825eb42bSJan Lentfer     ldns_sha256_update(&ctx, data, data_len);
629825eb42bSJan Lentfer     ldns_sha256_final(digest, &ctx);
630825eb42bSJan Lentfer     return digest;
631825eb42bSJan Lentfer }
632825eb42bSJan Lentfer 
633825eb42bSJan Lentfer /*** SHA-512: *********************************************************/
ldns_sha512_init(ldns_sha512_CTX * context)634825eb42bSJan Lentfer void ldns_sha512_init(ldns_sha512_CTX* context) {
635825eb42bSJan Lentfer 	if (context == (ldns_sha512_CTX*)0) {
636825eb42bSJan Lentfer 		return;
637825eb42bSJan Lentfer 	}
638825eb42bSJan Lentfer 	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
639825eb42bSJan Lentfer 	MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH);
640825eb42bSJan Lentfer 	context->bitcount[0] = context->bitcount[1] =  0;
641825eb42bSJan Lentfer }
642825eb42bSJan Lentfer 
643825eb42bSJan Lentfer #ifdef SHA2_UNROLL_TRANSFORM
644825eb42bSJan Lentfer 
645825eb42bSJan Lentfer /* Unrolled SHA-512 round macros: */
646825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
647825eb42bSJan Lentfer 
648825eb42bSJan Lentfer #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
649825eb42bSJan Lentfer 	REVERSE64(*data++, W512[j]); \
650825eb42bSJan Lentfer 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
651825eb42bSJan Lentfer              K512[j] + W512[j]; \
652825eb42bSJan Lentfer 	(d) += T1, \
653825eb42bSJan Lentfer 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
654825eb42bSJan Lentfer 	j++
655825eb42bSJan Lentfer 
656825eb42bSJan Lentfer 
657825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */
658825eb42bSJan Lentfer 
659825eb42bSJan Lentfer #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
660825eb42bSJan Lentfer 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
661825eb42bSJan Lentfer              K512[j] + (W512[j] = *data++); \
662825eb42bSJan Lentfer 	(d) += T1; \
663825eb42bSJan Lentfer 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
664825eb42bSJan Lentfer 	j++
665825eb42bSJan Lentfer 
666825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */
667825eb42bSJan Lentfer 
668825eb42bSJan Lentfer #define ROUND512(a,b,c,d,e,f,g,h)	\
669825eb42bSJan Lentfer 	s0 = W512[(j+1)&0x0f]; \
670825eb42bSJan Lentfer 	s0 = sigma0_512(s0); \
671825eb42bSJan Lentfer 	s1 = W512[(j+14)&0x0f]; \
672825eb42bSJan Lentfer 	s1 = sigma1_512(s1); \
673825eb42bSJan Lentfer 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
674825eb42bSJan Lentfer              (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
675825eb42bSJan Lentfer 	(d) += T1; \
676825eb42bSJan Lentfer 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
677825eb42bSJan Lentfer 	j++
678825eb42bSJan Lentfer 
ldns_sha512_Transform(ldns_sha512_CTX * context,const sha2_word64 * data)679825eb42bSJan Lentfer static void ldns_sha512_Transform(ldns_sha512_CTX* context,
680825eb42bSJan Lentfer                                   const sha2_word64* data) {
681825eb42bSJan Lentfer 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
682825eb42bSJan Lentfer 	sha2_word64	T1, *W512 = (sha2_word64*)context->buffer;
683825eb42bSJan Lentfer 	int		j;
684825eb42bSJan Lentfer 
685825eb42bSJan Lentfer 	/* initialize registers with the prev. intermediate value */
686825eb42bSJan Lentfer 	a = context->state[0];
687825eb42bSJan Lentfer 	b = context->state[1];
688825eb42bSJan Lentfer 	c = context->state[2];
689825eb42bSJan Lentfer 	d = context->state[3];
690825eb42bSJan Lentfer 	e = context->state[4];
691825eb42bSJan Lentfer 	f = context->state[5];
692825eb42bSJan Lentfer 	g = context->state[6];
693825eb42bSJan Lentfer 	h = context->state[7];
694825eb42bSJan Lentfer 
695825eb42bSJan Lentfer 	j = 0;
696825eb42bSJan Lentfer 	do {
697825eb42bSJan Lentfer 		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
698825eb42bSJan Lentfer 		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
699825eb42bSJan Lentfer 		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
700825eb42bSJan Lentfer 		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
701825eb42bSJan Lentfer 		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
702825eb42bSJan Lentfer 		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
703825eb42bSJan Lentfer 		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
704825eb42bSJan Lentfer 		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
705825eb42bSJan Lentfer 	} while (j < 16);
706825eb42bSJan Lentfer 
707825eb42bSJan Lentfer 	/* Now for the remaining rounds up to 79: */
708825eb42bSJan Lentfer 	do {
709825eb42bSJan Lentfer 		ROUND512(a,b,c,d,e,f,g,h);
710825eb42bSJan Lentfer 		ROUND512(h,a,b,c,d,e,f,g);
711825eb42bSJan Lentfer 		ROUND512(g,h,a,b,c,d,e,f);
712825eb42bSJan Lentfer 		ROUND512(f,g,h,a,b,c,d,e);
713825eb42bSJan Lentfer 		ROUND512(e,f,g,h,a,b,c,d);
714825eb42bSJan Lentfer 		ROUND512(d,e,f,g,h,a,b,c);
715825eb42bSJan Lentfer 		ROUND512(c,d,e,f,g,h,a,b);
716825eb42bSJan Lentfer 		ROUND512(b,c,d,e,f,g,h,a);
717825eb42bSJan Lentfer 	} while (j < 80);
718825eb42bSJan Lentfer 
719825eb42bSJan Lentfer 	/* Compute the current intermediate hash value */
720825eb42bSJan Lentfer 	context->state[0] += a;
721825eb42bSJan Lentfer 	context->state[1] += b;
722825eb42bSJan Lentfer 	context->state[2] += c;
723825eb42bSJan Lentfer 	context->state[3] += d;
724825eb42bSJan Lentfer 	context->state[4] += e;
725825eb42bSJan Lentfer 	context->state[5] += f;
726825eb42bSJan Lentfer 	context->state[6] += g;
727825eb42bSJan Lentfer 	context->state[7] += h;
728825eb42bSJan Lentfer 
729825eb42bSJan Lentfer 	/* Clean up */
730825eb42bSJan Lentfer 	a = b = c = d = e = f = g = h = T1 = 0;
731825eb42bSJan Lentfer }
732825eb42bSJan Lentfer 
733825eb42bSJan Lentfer #else /* SHA2_UNROLL_TRANSFORM */
734825eb42bSJan Lentfer 
ldns_sha512_Transform(ldns_sha512_CTX * context,const sha2_word64 * data)735825eb42bSJan Lentfer static void ldns_sha512_Transform(ldns_sha512_CTX* context,
736825eb42bSJan Lentfer                                   const sha2_word64* data) {
737825eb42bSJan Lentfer 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
738825eb42bSJan Lentfer 	sha2_word64	T1, T2, *W512 = (sha2_word64*)context->buffer;
739825eb42bSJan Lentfer 	int		j;
740825eb42bSJan Lentfer 
741825eb42bSJan Lentfer 	/* initialize registers with the prev. intermediate value */
742825eb42bSJan Lentfer 	a = context->state[0];
743825eb42bSJan Lentfer 	b = context->state[1];
744825eb42bSJan Lentfer 	c = context->state[2];
745825eb42bSJan Lentfer 	d = context->state[3];
746825eb42bSJan Lentfer 	e = context->state[4];
747825eb42bSJan Lentfer 	f = context->state[5];
748825eb42bSJan Lentfer 	g = context->state[6];
749825eb42bSJan Lentfer 	h = context->state[7];
750825eb42bSJan Lentfer 
751825eb42bSJan Lentfer 	j = 0;
752825eb42bSJan Lentfer 	do {
753825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
754825eb42bSJan Lentfer 		/* Convert TO host byte order */
755825eb42bSJan Lentfer 		REVERSE64(*data++, W512[j]);
756825eb42bSJan Lentfer 		/* Apply the SHA-512 compression function to update a..h */
757825eb42bSJan Lentfer 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
758825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */
759825eb42bSJan Lentfer 		/* Apply the SHA-512 compression function to update a..h with copy */
760825eb42bSJan Lentfer 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
761825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */
762825eb42bSJan Lentfer 		T2 = Sigma0_512(a) + Maj(a, b, c);
763825eb42bSJan Lentfer 		h = g;
764825eb42bSJan Lentfer 		g = f;
765825eb42bSJan Lentfer 		f = e;
766825eb42bSJan Lentfer 		e = d + T1;
767825eb42bSJan Lentfer 		d = c;
768825eb42bSJan Lentfer 		c = b;
769825eb42bSJan Lentfer 		b = a;
770825eb42bSJan Lentfer 		a = T1 + T2;
771825eb42bSJan Lentfer 
772825eb42bSJan Lentfer 		j++;
773825eb42bSJan Lentfer 	} while (j < 16);
774825eb42bSJan Lentfer 
775825eb42bSJan Lentfer 	do {
776825eb42bSJan Lentfer 		/* Part of the message block expansion: */
777825eb42bSJan Lentfer 		s0 = W512[(j+1)&0x0f];
778825eb42bSJan Lentfer 		s0 = sigma0_512(s0);
779825eb42bSJan Lentfer 		s1 = W512[(j+14)&0x0f];
780825eb42bSJan Lentfer 		s1 =  sigma1_512(s1);
781825eb42bSJan Lentfer 
782825eb42bSJan Lentfer 		/* Apply the SHA-512 compression function to update a..h */
783825eb42bSJan Lentfer 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
784825eb42bSJan Lentfer 		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
785825eb42bSJan Lentfer 		T2 = Sigma0_512(a) + Maj(a, b, c);
786825eb42bSJan Lentfer 		h = g;
787825eb42bSJan Lentfer 		g = f;
788825eb42bSJan Lentfer 		f = e;
789825eb42bSJan Lentfer 		e = d + T1;
790825eb42bSJan Lentfer 		d = c;
791825eb42bSJan Lentfer 		c = b;
792825eb42bSJan Lentfer 		b = a;
793825eb42bSJan Lentfer 		a = T1 + T2;
794825eb42bSJan Lentfer 
795825eb42bSJan Lentfer 		j++;
796825eb42bSJan Lentfer 	} while (j < 80);
797825eb42bSJan Lentfer 
798825eb42bSJan Lentfer 	/* Compute the current intermediate hash value */
799825eb42bSJan Lentfer 	context->state[0] += a;
800825eb42bSJan Lentfer 	context->state[1] += b;
801825eb42bSJan Lentfer 	context->state[2] += c;
802825eb42bSJan Lentfer 	context->state[3] += d;
803825eb42bSJan Lentfer 	context->state[4] += e;
804825eb42bSJan Lentfer 	context->state[5] += f;
805825eb42bSJan Lentfer 	context->state[6] += g;
806825eb42bSJan Lentfer 	context->state[7] += h;
807825eb42bSJan Lentfer 
808825eb42bSJan Lentfer 	/* Clean up */
809825eb42bSJan Lentfer 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
810819dec71SDaniel Fojt 	(void)a;
811825eb42bSJan Lentfer }
812825eb42bSJan Lentfer 
813825eb42bSJan Lentfer #endif /* SHA2_UNROLL_TRANSFORM */
814825eb42bSJan Lentfer 
ldns_sha512_update(ldns_sha512_CTX * context,const sha2_byte * data,size_t len)815825eb42bSJan Lentfer void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) {
816fd185f4dSJan Lentfer 	size_t freespace, usedspace;
817825eb42bSJan Lentfer 
818825eb42bSJan Lentfer 	if (len == 0) {
819825eb42bSJan Lentfer 		/* Calling with no data is valid - we do nothing */
820825eb42bSJan Lentfer 		return;
821825eb42bSJan Lentfer 	}
822825eb42bSJan Lentfer 
823825eb42bSJan Lentfer 	/* Sanity check: */
824825eb42bSJan Lentfer 	assert(context != (ldns_sha512_CTX*)0 && data != (sha2_byte*)0);
825825eb42bSJan Lentfer 
826825eb42bSJan Lentfer 	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
827825eb42bSJan Lentfer 	if (usedspace > 0) {
828825eb42bSJan Lentfer 		/* Calculate how much free space is available in the buffer */
829825eb42bSJan Lentfer 		freespace = LDNS_SHA512_BLOCK_LENGTH - usedspace;
830825eb42bSJan Lentfer 
831825eb42bSJan Lentfer 		if (len >= freespace) {
832825eb42bSJan Lentfer 			/* Fill the buffer completely and process it */
833825eb42bSJan Lentfer 			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
834825eb42bSJan Lentfer 			ADDINC128(context->bitcount, freespace << 3);
835825eb42bSJan Lentfer 			len -= freespace;
836825eb42bSJan Lentfer 			data += freespace;
837825eb42bSJan Lentfer 			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
838825eb42bSJan Lentfer 		} else {
839825eb42bSJan Lentfer 			/* The buffer is not yet full */
840825eb42bSJan Lentfer 			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
841825eb42bSJan Lentfer 			ADDINC128(context->bitcount, len << 3);
842825eb42bSJan Lentfer 			/* Clean up: */
843825eb42bSJan Lentfer 			usedspace = freespace = 0;
844819dec71SDaniel Fojt 			(void)usedspace;
845825eb42bSJan Lentfer 			return;
846825eb42bSJan Lentfer 		}
847825eb42bSJan Lentfer 	}
848825eb42bSJan Lentfer 	while (len >= LDNS_SHA512_BLOCK_LENGTH) {
849825eb42bSJan Lentfer 		/* Process as many complete blocks as we can */
850825eb42bSJan Lentfer 		ldns_sha512_Transform(context, (sha2_word64*)data);
851825eb42bSJan Lentfer 		ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3);
852825eb42bSJan Lentfer 		len -= LDNS_SHA512_BLOCK_LENGTH;
853825eb42bSJan Lentfer 		data += LDNS_SHA512_BLOCK_LENGTH;
854825eb42bSJan Lentfer 	}
855825eb42bSJan Lentfer 	if (len > 0) {
856825eb42bSJan Lentfer 		/* There's left-overs, so save 'em */
857825eb42bSJan Lentfer 		MEMCPY_BCOPY(context->buffer, data, len);
858825eb42bSJan Lentfer 		ADDINC128(context->bitcount, len << 3);
859825eb42bSJan Lentfer 	}
860825eb42bSJan Lentfer 	/* Clean up: */
861825eb42bSJan Lentfer 	usedspace = freespace = 0;
862819dec71SDaniel Fojt 	(void)usedspace;
863825eb42bSJan Lentfer }
864825eb42bSJan Lentfer 
ldns_sha512_Last(ldns_sha512_CTX * context)865825eb42bSJan Lentfer static void ldns_sha512_Last(ldns_sha512_CTX* context) {
866fd185f4dSJan Lentfer 	size_t usedspace;
8675340022aSzrj 	ldns_sha2_buffer_union cast_var;
868825eb42bSJan Lentfer 
869825eb42bSJan Lentfer 	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
870825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
871825eb42bSJan Lentfer 	/* Convert FROM host byte order */
872825eb42bSJan Lentfer 	REVERSE64(context->bitcount[0],context->bitcount[0]);
873825eb42bSJan Lentfer 	REVERSE64(context->bitcount[1],context->bitcount[1]);
874825eb42bSJan Lentfer #endif
875825eb42bSJan Lentfer 	if (usedspace > 0) {
876825eb42bSJan Lentfer 		/* Begin padding with a 1 bit: */
877825eb42bSJan Lentfer 		context->buffer[usedspace++] = 0x80;
878825eb42bSJan Lentfer 
879825eb42bSJan Lentfer 		if (usedspace <= ldns_sha512_SHORT_BLOCK_LENGTH) {
880825eb42bSJan Lentfer 			/* Set-up for the last transform: */
881825eb42bSJan Lentfer 			MEMSET_BZERO(&context->buffer[usedspace], ldns_sha512_SHORT_BLOCK_LENGTH - usedspace);
882825eb42bSJan Lentfer 		} else {
883825eb42bSJan Lentfer 			if (usedspace < LDNS_SHA512_BLOCK_LENGTH) {
884825eb42bSJan Lentfer 				MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA512_BLOCK_LENGTH - usedspace);
885825eb42bSJan Lentfer 			}
886825eb42bSJan Lentfer 			/* Do second-to-last transform: */
887825eb42bSJan Lentfer 			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
888825eb42bSJan Lentfer 
889825eb42bSJan Lentfer 			/* And set-up for the last transform: */
890825eb42bSJan Lentfer 			MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH - 2);
891825eb42bSJan Lentfer 		}
892825eb42bSJan Lentfer 	} else {
893825eb42bSJan Lentfer 		/* Prepare for final transform: */
894825eb42bSJan Lentfer 		MEMSET_BZERO(context->buffer, ldns_sha512_SHORT_BLOCK_LENGTH);
895825eb42bSJan Lentfer 
896825eb42bSJan Lentfer 		/* Begin padding with a 1 bit: */
897825eb42bSJan Lentfer 		*context->buffer = 0x80;
898825eb42bSJan Lentfer 	}
899825eb42bSJan Lentfer 	/* Store the length of input data (in bits): */
9005340022aSzrj 	cast_var.theChars = context->buffer;
9015340022aSzrj 	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
9025340022aSzrj 	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
903825eb42bSJan Lentfer 
904825eb42bSJan Lentfer 	/* final transform: */
905825eb42bSJan Lentfer 	ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
906825eb42bSJan Lentfer }
907825eb42bSJan Lentfer 
ldns_sha512_final(sha2_byte digest[LDNS_SHA512_DIGEST_LENGTH],ldns_sha512_CTX * context)908*ee791febSAntonio Huete Jimenez void ldns_sha512_final(sha2_byte digest[LDNS_SHA512_DIGEST_LENGTH], ldns_sha512_CTX* context) {
909825eb42bSJan Lentfer 	sha2_word64	*d = (sha2_word64*)digest;
910825eb42bSJan Lentfer 
911825eb42bSJan Lentfer 	/* Sanity check: */
912825eb42bSJan Lentfer 	assert(context != (ldns_sha512_CTX*)0);
913825eb42bSJan Lentfer 
914825eb42bSJan Lentfer 	/* If no digest buffer is passed, we don't bother doing this: */
915825eb42bSJan Lentfer 	if (digest != (sha2_byte*)0) {
916825eb42bSJan Lentfer 		ldns_sha512_Last(context);
917825eb42bSJan Lentfer 
918825eb42bSJan Lentfer 		/* Save the hash data for output: */
919825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
920825eb42bSJan Lentfer 		{
921825eb42bSJan Lentfer 			/* Convert TO host byte order */
922825eb42bSJan Lentfer 			int	j;
923825eb42bSJan Lentfer 			for (j = 0; j < 8; j++) {
924825eb42bSJan Lentfer 				REVERSE64(context->state[j],context->state[j]);
925825eb42bSJan Lentfer 				*d++ = context->state[j];
926825eb42bSJan Lentfer 			}
927825eb42bSJan Lentfer 		}
928825eb42bSJan Lentfer #else
929825eb42bSJan Lentfer 		MEMCPY_BCOPY(d, context->state, LDNS_SHA512_DIGEST_LENGTH);
930825eb42bSJan Lentfer #endif
931825eb42bSJan Lentfer 	}
932825eb42bSJan Lentfer 
933825eb42bSJan Lentfer 	/* Zero out state data */
934b5dedccaSJan Lentfer 	MEMSET_BZERO(context, sizeof(ldns_sha512_CTX));
935825eb42bSJan Lentfer }
936825eb42bSJan Lentfer 
937825eb42bSJan Lentfer unsigned char *
ldns_sha512(const unsigned char * data,unsigned int data_len,unsigned char * digest)938*ee791febSAntonio Huete Jimenez ldns_sha512(const unsigned char *data, unsigned int data_len, unsigned char *digest)
939825eb42bSJan Lentfer {
940825eb42bSJan Lentfer     ldns_sha512_CTX ctx;
941825eb42bSJan Lentfer     ldns_sha512_init(&ctx);
942825eb42bSJan Lentfer     ldns_sha512_update(&ctx, data, data_len);
943825eb42bSJan Lentfer     ldns_sha512_final(digest, &ctx);
944825eb42bSJan Lentfer     return digest;
945825eb42bSJan Lentfer }
946825eb42bSJan Lentfer 
947825eb42bSJan Lentfer /*** SHA-384: *********************************************************/
ldns_sha384_init(ldns_sha384_CTX * context)948825eb42bSJan Lentfer void ldns_sha384_init(ldns_sha384_CTX* context) {
949825eb42bSJan Lentfer 	if (context == (ldns_sha384_CTX*)0) {
950825eb42bSJan Lentfer 		return;
951825eb42bSJan Lentfer 	}
952825eb42bSJan Lentfer 	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
953825eb42bSJan Lentfer 	MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH);
954825eb42bSJan Lentfer 	context->bitcount[0] = context->bitcount[1] = 0;
955825eb42bSJan Lentfer }
956825eb42bSJan Lentfer 
ldns_sha384_update(ldns_sha384_CTX * context,const sha2_byte * data,size_t len)957825eb42bSJan Lentfer void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) {
958825eb42bSJan Lentfer 	ldns_sha512_update((ldns_sha512_CTX*)context, data, len);
959825eb42bSJan Lentfer }
960825eb42bSJan Lentfer 
ldns_sha384_final(sha2_byte digest[LDNS_SHA384_DIGEST_LENGTH],ldns_sha384_CTX * context)961*ee791febSAntonio Huete Jimenez void ldns_sha384_final(sha2_byte digest[LDNS_SHA384_DIGEST_LENGTH], ldns_sha384_CTX* context) {
962825eb42bSJan Lentfer 	sha2_word64	*d = (sha2_word64*)digest;
963825eb42bSJan Lentfer 
964825eb42bSJan Lentfer 	/* Sanity check: */
965825eb42bSJan Lentfer 	assert(context != (ldns_sha384_CTX*)0);
966825eb42bSJan Lentfer 
967825eb42bSJan Lentfer 	/* If no digest buffer is passed, we don't bother doing this: */
968825eb42bSJan Lentfer 	if (digest != (sha2_byte*)0) {
969825eb42bSJan Lentfer 		ldns_sha512_Last((ldns_sha512_CTX*)context);
970825eb42bSJan Lentfer 
971825eb42bSJan Lentfer 		/* Save the hash data for output: */
972825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN
973825eb42bSJan Lentfer 		{
974825eb42bSJan Lentfer 			/* Convert TO host byte order */
975825eb42bSJan Lentfer 			int	j;
976825eb42bSJan Lentfer 			for (j = 0; j < 6; j++) {
977825eb42bSJan Lentfer 				REVERSE64(context->state[j],context->state[j]);
978825eb42bSJan Lentfer 				*d++ = context->state[j];
979825eb42bSJan Lentfer 			}
980825eb42bSJan Lentfer 		}
981825eb42bSJan Lentfer #else
982825eb42bSJan Lentfer 		MEMCPY_BCOPY(d, context->state, LDNS_SHA384_DIGEST_LENGTH);
983825eb42bSJan Lentfer #endif
984825eb42bSJan Lentfer 	}
985825eb42bSJan Lentfer 
986825eb42bSJan Lentfer 	/* Zero out state data */
987b5dedccaSJan Lentfer 	MEMSET_BZERO(context, sizeof(ldns_sha384_CTX));
988825eb42bSJan Lentfer }
989825eb42bSJan Lentfer 
990825eb42bSJan Lentfer unsigned char *
ldns_sha384(const unsigned char * data,unsigned int data_len,unsigned char * digest)991*ee791febSAntonio Huete Jimenez ldns_sha384(const unsigned char *data, unsigned int data_len, unsigned char *digest)
992825eb42bSJan Lentfer {
993825eb42bSJan Lentfer     ldns_sha384_CTX ctx;
994825eb42bSJan Lentfer     ldns_sha384_init(&ctx);
995825eb42bSJan Lentfer     ldns_sha384_update(&ctx, data, data_len);
996825eb42bSJan Lentfer     ldns_sha384_final(digest, &ctx);
997825eb42bSJan Lentfer     return digest;
998825eb42bSJan Lentfer }
999