1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1996-2010 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                                                                      *
19***********************************************************************/
20#pragma prototyped
21
22#if _typ_int64_t
23
24/*
25 * Aaron D. Gifford's SHA {256,384,512} code transcribed into a -lsum method
26 */
27
28/*
29 * Copyright (c) 2000-2001, Aaron D. Gifford
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 *    notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 * 3. Neither the name of the copyright holder nor the names of contributors
41 *    may be used to endorse or promote products derived from this software
42 *    without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57/*
58 * ASSERT NOTE:
59 * Some sanity checking code is included using assert().  On my FreeBSD
60 * system, this additional code can be removed by compiling with NDEBUG
61 * defined.  Check your own systems manpage on assert() to see how to
62 * compile WITHOUT the sanity checking code on your system.
63 *
64 * UNROLLED TRANSFORM LOOP NOTE:
65 * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
66 * loop version for the hash transform rounds (defined using macros
67 * later in this file).  Either define on the command line, for example:
68 *
69 *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
70 *
71 * or define below:
72 *
73 *   #define SHA2_UNROLL_TRANSFORM
74 *
75 */
76
77/*** SHA-256/384/512 Machine Architecture Definitions *****************/
78
79#if _PACKAGE_ast
80
81#ifndef __USE_BSD
82#define __undef__USE_BSD
83#define __USE_BSD
84#endif
85#include <endian.h>
86#ifdef	__undef__USE_BSD
87#undef	__undef__USE_BSD
88#undef	__USE_BSD
89#endif
90
91typedef  uint8_t sha2_byte;	/* Exactly 1 byte */
92typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
93typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
94
95#define assert(x)
96
97#undef	R
98#undef	S32
99#undef	S64
100
101#else /* _PACKAGE_ast */
102
103/*
104 * BYTE_ORDER NOTE:
105 *
106 * Please make sure that your system defines BYTE_ORDER.  If your
107 * architecture is little-endian, make sure it also defines
108 * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
109 * equivilent.
110 *
111 * If your system does not define the above, then you can do so by
112 * hand like this:
113 *
114 *   #define LITTLE_ENDIAN 1234
115 *   #define BIG_ENDIAN    4321
116 *
117 * And for little-endian machines, add:
118 *
119 *   #define BYTE_ORDER LITTLE_ENDIAN
120 *
121 * Or for big-endian machines:
122 *
123 *   #define BYTE_ORDER BIG_ENDIAN
124 *
125 * The FreeBSD machine this was written on defines BYTE_ORDER
126 * appropriately by including <sys/types.h> (which in turn includes
127 * <machine/endian.h> where the appropriate definitions are actually
128 * made).
129 */
130
131#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
132#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
133#endif
134
135/*
136 * Define the following sha2_* types to types of the correct length on
137 * the native archtecture.   Most BSD systems and Linux define u_intXX_t
138 * types.  Machines with very recent ANSI C headers, can use the
139 * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
140 * during compile or in the sha.h header file.
141 *
142 * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
143 * will need to define these three typedefs below (and the appropriate
144 * ones in sha.h too) by hand according to their system architecture.
145 *
146 * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
147 * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
148 */
149
150#ifdef SHA2_USE_INTTYPES_H
151
152typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
153typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
154typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
155
156#else /* SHA2_USE_INTTYPES_H */
157
158typedef u_int8_t  sha2_byte;	/* Exactly 1 byte */
159typedef u_int32_t sha2_word32;	/* Exactly 4 bytes */
160typedef u_int64_t sha2_word64;	/* Exactly 8 bytes */
161
162#endif /* SHA2_USE_INTTYPES_H */
163
164#endif /* _PACKAGE_ast */
165
166/*** SHA-256/384/512 Various Length Definitions ***********************/
167
168#define SHA256_BLOCK_LENGTH		64
169#define SHA256_DIGEST_LENGTH		32
170#define SHA384_BLOCK_LENGTH		128
171#define SHA384_DIGEST_LENGTH		48
172#define SHA512_BLOCK_LENGTH		128
173#define SHA512_DIGEST_LENGTH		64
174
175#define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
176#define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
177#define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
178
179/*** ENDIAN REVERSAL MACROS *******************************************/
180#if BYTE_ORDER == LITTLE_ENDIAN
181#define REVERSE32(w,x)	{ \
182	sha2_word32 tmp = (w); \
183	tmp = (tmp >> 16) | (tmp << 16); \
184	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
185}
186#if _ast_LL
187#define REVERSE64(w,x)	{ \
188	sha2_word64 tmp = (w); \
189	tmp = (tmp >> 32) | (tmp << 32); \
190	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
191	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
192	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
193	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
194}
195#else
196#define REVERSE64(w,x)	{ \
197	sha2_word64 tmp = (w); \
198	tmp = (tmp >> 32) | (tmp << 32); \
199	tmp = ((tmp & ((sha2_word64)0xff00ff00ff00ff00)) >> 8) | \
200	      ((tmp & ((sha2_word64)0x00ff00ff00ff00ff)) << 8); \
201	(x) = ((tmp & ((sha2_word64)0xffff0000ffff0000)) >> 16) | \
202	      ((tmp & ((sha2_word64)0x0000ffff0000ffff)) << 16); \
203}
204#endif
205#endif /* BYTE_ORDER == LITTLE_ENDIAN */
206
207/*
208 * Macro for incrementally adding the unsigned 64-bit integer n to the
209 * unsigned 128-bit integer (represented using a two-element array of
210 * 64-bit words):
211 */
212
213#define ADDINC128(w,n)	{ \
214	(w)[0] += (sha2_word64)(n); \
215	if ((w)[0] < (n)) { \
216		(w)[1]++; \
217	} \
218}
219
220/*
221 * Macros for copying blocks of memory and for zeroing out ranges
222 * of memory.  Using these macros makes it easy to switch from
223 * using memset()/memcpy() and using bzero()/bcopy().
224 *
225 * Please define either SHA2_USE_MEMSET_MEMCPY or define
226 * SHA2_USE_BZERO_BCOPY depending on which function set you
227 * choose to use:
228 */
229
230#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
231/* Default to memset()/memcpy() if no option is specified */
232#define	SHA2_USE_MEMSET_MEMCPY	1
233#endif
234#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
235/* Abort with an error if BOTH options are defined */
236#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
237#endif
238
239#ifdef SHA2_USE_MEMSET_MEMCPY
240#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
241#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
242#endif
243#ifdef SHA2_USE_BZERO_BCOPY
244#define MEMSET_BZERO(p,l)	bzero((p), (l))
245#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
246#endif
247
248
249/*** THE SIX LOGICAL FUNCTIONS ****************************************/
250/*
251 * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
252 *
253 *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
254 *   S is a ROTATION) because the SHA-256/384/512 description document
255 *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
256 *   same "backwards" definition.
257 */
258
259/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
260#define R(b,x) 		((x) >> (b))
261/* 32-bit Rotate-right (used in SHA-256): */
262#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
263/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
264#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
265
266/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
267#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
268#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
269
270/* Four of six logical functions used in SHA-256: */
271#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
272#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
273#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
274#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
275
276/* Four of six logical functions used in SHA-384 and SHA-512: */
277#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
278#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
279#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
280#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
281
282/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
283/* Hash constant words K for SHA-256: */
284static const sha2_word32 K256[64] = {
285	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
286	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
287	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
288	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
289	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
290	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
291	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
292	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
293	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
294	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
295	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
296	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
297	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
298	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
299	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
300	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
301};
302
303/* Initial hash value H for SHA-256: */
304static const sha2_word32 sha256_initial_hash_value[8] = {
305	0x6a09e667UL,
306	0xbb67ae85UL,
307	0x3c6ef372UL,
308	0xa54ff53aUL,
309	0x510e527fUL,
310	0x9b05688cUL,
311	0x1f83d9abUL,
312	0x5be0cd19UL
313};
314
315/* Hash constant words K for SHA-384 and SHA-512: */
316static const sha2_word64 K512[80] = {
317#if _ast_LL
318	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
319	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
320	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
321	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
322	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
323	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
324	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
325	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
326	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
327	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
328	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
329	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
330	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
331	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
332	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
333	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
334	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
335	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
336	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
337	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
338	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
339	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
340	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
341	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
342	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
343	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
344	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
345	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
346	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
347	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
348	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
349	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
350	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
351	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
352	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
353	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
354	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
355	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
356	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
357	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
358#else
359	((sha2_word64)0x428a2f98d728ae22), ((sha2_word64)0x7137449123ef65cd),
360	((sha2_word64)0xb5c0fbcfec4d3b2f), ((sha2_word64)0xe9b5dba58189dbbc),
361	((sha2_word64)0x3956c25bf348b538), ((sha2_word64)0x59f111f1b605d019),
362	((sha2_word64)0x923f82a4af194f9b), ((sha2_word64)0xab1c5ed5da6d8118),
363	((sha2_word64)0xd807aa98a3030242), ((sha2_word64)0x12835b0145706fbe),
364	((sha2_word64)0x243185be4ee4b28c), ((sha2_word64)0x550c7dc3d5ffb4e2),
365	((sha2_word64)0x72be5d74f27b896f), ((sha2_word64)0x80deb1fe3b1696b1),
366	((sha2_word64)0x9bdc06a725c71235), ((sha2_word64)0xc19bf174cf692694),
367	((sha2_word64)0xe49b69c19ef14ad2), ((sha2_word64)0xefbe4786384f25e3),
368	((sha2_word64)0x0fc19dc68b8cd5b5), ((sha2_word64)0x240ca1cc77ac9c65),
369	((sha2_word64)0x2de92c6f592b0275), ((sha2_word64)0x4a7484aa6ea6e483),
370	((sha2_word64)0x5cb0a9dcbd41fbd4), ((sha2_word64)0x76f988da831153b5),
371	((sha2_word64)0x983e5152ee66dfab), ((sha2_word64)0xa831c66d2db43210),
372	((sha2_word64)0xb00327c898fb213f), ((sha2_word64)0xbf597fc7beef0ee4),
373	((sha2_word64)0xc6e00bf33da88fc2), ((sha2_word64)0xd5a79147930aa725),
374	((sha2_word64)0x06ca6351e003826f), ((sha2_word64)0x142929670a0e6e70),
375	((sha2_word64)0x27b70a8546d22ffc), ((sha2_word64)0x2e1b21385c26c926),
376	((sha2_word64)0x4d2c6dfc5ac42aed), ((sha2_word64)0x53380d139d95b3df),
377	((sha2_word64)0x650a73548baf63de), ((sha2_word64)0x766a0abb3c77b2a8),
378	((sha2_word64)0x81c2c92e47edaee6), ((sha2_word64)0x92722c851482353b),
379	((sha2_word64)0xa2bfe8a14cf10364), ((sha2_word64)0xa81a664bbc423001),
380	((sha2_word64)0xc24b8b70d0f89791), ((sha2_word64)0xc76c51a30654be30),
381	((sha2_word64)0xd192e819d6ef5218), ((sha2_word64)0xd69906245565a910),
382	((sha2_word64)0xf40e35855771202a), ((sha2_word64)0x106aa07032bbd1b8),
383	((sha2_word64)0x19a4c116b8d2d0c8), ((sha2_word64)0x1e376c085141ab53),
384	((sha2_word64)0x2748774cdf8eeb99), ((sha2_word64)0x34b0bcb5e19b48a8),
385	((sha2_word64)0x391c0cb3c5c95a63), ((sha2_word64)0x4ed8aa4ae3418acb),
386	((sha2_word64)0x5b9cca4f7763e373), ((sha2_word64)0x682e6ff3d6b2b8a3),
387	((sha2_word64)0x748f82ee5defb2fc), ((sha2_word64)0x78a5636f43172f60),
388	((sha2_word64)0x84c87814a1f0ab72), ((sha2_word64)0x8cc702081a6439ec),
389	((sha2_word64)0x90befffa23631e28), ((sha2_word64)0xa4506cebde82bde9),
390	((sha2_word64)0xbef9a3f7b2c67915), ((sha2_word64)0xc67178f2e372532b),
391	((sha2_word64)0xca273eceea26619c), ((sha2_word64)0xd186b8c721c0c207),
392	((sha2_word64)0xeada7dd6cde0eb1e), ((sha2_word64)0xf57d4f7fee6ed178),
393	((sha2_word64)0x06f067aa72176fba), ((sha2_word64)0x0a637dc5a2c898a6),
394	((sha2_word64)0x113f9804bef90dae), ((sha2_word64)0x1b710b35131c471b),
395	((sha2_word64)0x28db77f523047d84), ((sha2_word64)0x32caab7b40c72493),
396	((sha2_word64)0x3c9ebe0a15c9bebc), ((sha2_word64)0x431d67c49c100d4c),
397	((sha2_word64)0x4cc5d4becb3e42b6), ((sha2_word64)0x597f299cfc657e2a),
398	((sha2_word64)0x5fcb6fab3ad6faec), ((sha2_word64)0x6c44198c4a475817)
399#endif
400};
401
402/* Initial hash value H for SHA-384 */
403static const sha2_word64 sha384_initial_hash_value[8] = {
404#if _ast_LL
405	0xcbbb9d5dc1059ed8ULL,
406	0x629a292a367cd507ULL,
407	0x9159015a3070dd17ULL,
408	0x152fecd8f70e5939ULL,
409	0x67332667ffc00b31ULL,
410	0x8eb44a8768581511ULL,
411	0xdb0c2e0d64f98fa7ULL,
412	0x47b5481dbefa4fa4ULL
413#else
414	((sha2_word64)0xcbbb9d5dc1059ed8),
415	((sha2_word64)0x629a292a367cd507),
416	((sha2_word64)0x9159015a3070dd17),
417	((sha2_word64)0x152fecd8f70e5939),
418	((sha2_word64)0x67332667ffc00b31),
419	((sha2_word64)0x8eb44a8768581511),
420	((sha2_word64)0xdb0c2e0d64f98fa7),
421	((sha2_word64)0x47b5481dbefa4fa4)
422#endif
423};
424
425/* Initial hash value H for SHA-512 */
426static const sha2_word64 sha512_initial_hash_value[8] = {
427#if _ast_LL
428	0x6a09e667f3bcc908ULL,
429	0xbb67ae8584caa73bULL,
430	0x3c6ef372fe94f82bULL,
431	0xa54ff53a5f1d36f1ULL,
432	0x510e527fade682d1ULL,
433	0x9b05688c2b3e6c1fULL,
434	0x1f83d9abfb41bd6bULL,
435	0x5be0cd19137e2179ULL
436#else
437	((sha2_word64)0x6a09e667f3bcc908),
438	((sha2_word64)0xbb67ae8584caa73b),
439	((sha2_word64)0x3c6ef372fe94f82b),
440	((sha2_word64)0xa54ff53a5f1d36f1),
441	((sha2_word64)0x510e527fade682d1),
442	((sha2_word64)0x9b05688c2b3e6c1f),
443	((sha2_word64)0x1f83d9abfb41bd6b),
444	((sha2_word64)0x5be0cd19137e2179)
445#endif
446};
447
448/*** SHA-256: *********************************************************/
449
450#define sha256_description "FIPS SHA-256 secure hash algorithm."
451#define sha256_options	"\
452[+(version)?sha-256 (FIPS) 2000-01-01]\
453[+(author)?Aaron D. Gifford]\
454"
455#define sha256_match	"sha256|sha-256|SHA256|SHA-256"
456#define sha256_scale	0
457
458#define sha256_padding	md5_pad
459
460#define SHA256_CTX	Sha256_t
461
462typedef struct Sha256_s
463{
464	_SUM_PUBLIC_
465	_SUM_PRIVATE_
466	sha2_byte	digest[SHA256_DIGEST_LENGTH];
467	sha2_byte	digest_sum[SHA256_DIGEST_LENGTH];
468	sha2_word32	state[8];
469	sha2_word64	bitcount;
470	sha2_byte	buffer[SHA256_BLOCK_LENGTH];
471} Sha256_t;
472
473#ifdef SHA2_UNROLL_TRANSFORM
474
475/* Unrolled SHA-256 round macros: */
476
477#if BYTE_ORDER == LITTLE_ENDIAN
478
479#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
480	REVERSE32(*data++, W256[j]); \
481	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
482             K256[j] + W256[j]; \
483	(d) += T1; \
484	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
485	j++
486
487
488#else /* BYTE_ORDER == LITTLE_ENDIAN */
489
490#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
491	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
492	     K256[j] + (W256[j] = *data++); \
493	(d) += T1; \
494	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
495	j++
496
497#endif /* BYTE_ORDER == LITTLE_ENDIAN */
498
499#define ROUND256(a,b,c,d,e,f,g,h)	\
500	s0 = W256[(j+1)&0x0f]; \
501	s0 = sigma0_256(s0); \
502	s1 = W256[(j+14)&0x0f]; \
503	s1 = sigma1_256(s1); \
504	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
505	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
506	(d) += T1; \
507	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
508	j++
509
510static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
511	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
512	sha2_word32	T1, *W256;
513	int		j;
514
515	W256 = (sha2_word32*)sha->buffer;
516
517	/* Initialize registers with the prev. intermediate value */
518	a = sha->state[0];
519	b = sha->state[1];
520	c = sha->state[2];
521	d = sha->state[3];
522	e = sha->state[4];
523	f = sha->state[5];
524	g = sha->state[6];
525	h = sha->state[7];
526
527	j = 0;
528	do {
529		/* Rounds 0 to 15 (unrolled): */
530		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
531		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
532		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
533		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
534		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
535		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
536		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
537		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
538	} while (j < 16);
539
540	/* Now for the remaining rounds to 64: */
541	do {
542		ROUND256(a,b,c,d,e,f,g,h);
543		ROUND256(h,a,b,c,d,e,f,g);
544		ROUND256(g,h,a,b,c,d,e,f);
545		ROUND256(f,g,h,a,b,c,d,e);
546		ROUND256(e,f,g,h,a,b,c,d);
547		ROUND256(d,e,f,g,h,a,b,c);
548		ROUND256(c,d,e,f,g,h,a,b);
549		ROUND256(b,c,d,e,f,g,h,a);
550	} while (j < 64);
551
552	/* Compute the current intermediate hash value */
553	sha->state[0] += a;
554	sha->state[1] += b;
555	sha->state[2] += c;
556	sha->state[3] += d;
557	sha->state[4] += e;
558	sha->state[5] += f;
559	sha->state[6] += g;
560	sha->state[7] += h;
561
562	/* Clean up */
563	a = b = c = d = e = f = g = h = T1 = 0;
564}
565
566#else /* SHA2_UNROLL_TRANSFORM */
567
568static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
569	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
570	sha2_word32	T1, T2, *W256;
571	int		j;
572
573	W256 = (sha2_word32*)sha->buffer;
574
575	/* Initialize registers with the prev. intermediate value */
576	a = sha->state[0];
577	b = sha->state[1];
578	c = sha->state[2];
579	d = sha->state[3];
580	e = sha->state[4];
581	f = sha->state[5];
582	g = sha->state[6];
583	h = sha->state[7];
584
585	j = 0;
586	do {
587#if BYTE_ORDER == LITTLE_ENDIAN
588		/* Copy data while converting to host byte order */
589		REVERSE32(*data++,W256[j]);
590		/* Apply the SHA-256 compression function to update a..h */
591		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
592#else /* BYTE_ORDER == LITTLE_ENDIAN */
593		/* Apply the SHA-256 compression function to update a..h with copy */
594		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
595#endif /* BYTE_ORDER == LITTLE_ENDIAN */
596		T2 = Sigma0_256(a) + Maj(a, b, c);
597		h = g;
598		g = f;
599		f = e;
600		e = d + T1;
601		d = c;
602		c = b;
603		b = a;
604		a = T1 + T2;
605
606		j++;
607	} while (j < 16);
608
609	do {
610		/* Part of the message block expansion: */
611		s0 = W256[(j+1)&0x0f];
612		s0 = sigma0_256(s0);
613		s1 = W256[(j+14)&0x0f];
614		s1 = sigma1_256(s1);
615
616		/* Apply the SHA-256 compression function to update a..h */
617		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
618		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
619		T2 = Sigma0_256(a) + Maj(a, b, c);
620		h = g;
621		g = f;
622		f = e;
623		e = d + T1;
624		d = c;
625		c = b;
626		b = a;
627		a = T1 + T2;
628
629		j++;
630	} while (j < 64);
631
632	/* Compute the current intermediate hash value */
633	sha->state[0] += a;
634	sha->state[1] += b;
635	sha->state[2] += c;
636	sha->state[3] += d;
637	sha->state[4] += e;
638	sha->state[5] += f;
639	sha->state[6] += g;
640	sha->state[7] += h;
641
642	/* Clean up */
643	a = b = c = d = e = f = g = h = T1 = T2 = 0;
644}
645
646#endif /* SHA2_UNROLL_TRANSFORM */
647
648static int
649sha256_block(register Sum_t* p, const void* s, size_t len)
650{
651	Sha256_t*	sha = (Sha256_t*)p;
652	sha2_byte*	data = (sha2_byte*)s;
653	unsigned int	freespace, usedspace;
654
655	if (!len)
656		return 0;
657	usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
658	if (usedspace > 0) {
659		/* Calculate how much free space is available in the buffer */
660		freespace = SHA256_BLOCK_LENGTH - usedspace;
661
662		if (len >= freespace) {
663			/* Fill the buffer completely and process it */
664			MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
665			sha->bitcount += freespace << 3;
666			len -= freespace;
667			data += freespace;
668			SHA256_Transform(sha, (sha2_word32*)sha->buffer);
669		} else {
670			/* The buffer is not yet full */
671			MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
672			sha->bitcount += len << 3;
673			/* Clean up: */
674			usedspace = freespace = 0;
675			return 0;
676		}
677	}
678	while (len >= SHA256_BLOCK_LENGTH) {
679		/* Process as many complete blocks as we can */
680		SHA256_Transform(sha, (sha2_word32*)data);
681		sha->bitcount += SHA256_BLOCK_LENGTH << 3;
682		len -= SHA256_BLOCK_LENGTH;
683		data += SHA256_BLOCK_LENGTH;
684	}
685	if (len > 0) {
686		/* There's left-overs, so save 'em */
687		MEMCPY_BCOPY(sha->buffer, data, len);
688		sha->bitcount += len << 3;
689	}
690	/* Clean up: */
691	usedspace = freespace = 0;
692
693	return 0;
694}
695
696static int
697sha256_init(Sum_t* p)
698{
699	register Sha256_t*	sha = (Sha256_t*)p;
700
701	MEMCPY_BCOPY(sha->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
702	MEMSET_BZERO(sha->buffer, SHA256_BLOCK_LENGTH);
703	sha->bitcount = 0;
704
705	return 0;
706}
707
708static Sum_t*
709sha256_open(const Method_t* method, const char* name)
710{
711	Sha256_t*	sha;
712
713	if (sha = newof(0, Sha256_t, 1, 0))
714	{
715		sha->method = (Method_t*)method;
716		sha->name = name;
717		sha256_init((Sum_t*)sha);
718	}
719	return (Sum_t*)sha;
720}
721
722static int
723sha256_done(Sum_t* p)
724{
725	Sha256_t*	sha = (Sha256_t*)p;
726	unsigned int	usedspace;
727	register int	i;
728
729	/* Sanity check: */
730	assert(sha != (SHA256_CTX*)0);
731
732	usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
733#if BYTE_ORDER == LITTLE_ENDIAN
734	/* Convert FROM host byte order */
735	REVERSE64(sha->bitcount,sha->bitcount);
736#endif
737	if (usedspace > 0) {
738		/* Begin padding with a 1 bit: */
739		sha->buffer[usedspace++] = 0x80;
740
741		if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
742			/* Set-up for the last transform: */
743			MEMSET_BZERO(&sha->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
744		} else {
745			if (usedspace < SHA256_BLOCK_LENGTH) {
746				MEMSET_BZERO(&sha->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
747			}
748			/* Do second-to-last transform: */
749			SHA256_Transform(sha, (sha2_word32*)sha->buffer);
750
751			/* And set-up for the last transform: */
752			MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
753		}
754	} else {
755		/* Set-up for the last transform: */
756		MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
757
758		/* Begin padding with a 1 bit: */
759		*sha->buffer = 0x80;
760	}
761	/* Set the bit count: */
762	*(sha2_word64*)&sha->buffer[SHA256_SHORT_BLOCK_LENGTH] = sha->bitcount;
763
764	/* Final transform: */
765	SHA256_Transform(sha, (sha2_word32*)sha->buffer);
766
767#if BYTE_ORDER == LITTLE_ENDIAN
768	{
769		/* Convert TO host byte order */
770		int		j;
771		sha2_word32*	d = (sha2_word32*)sha->digest;
772		for (j = 0; j < 8; j++) {
773			REVERSE32(sha->state[j],sha->state[j]);
774			*d++ = sha->state[j];
775		}
776	}
777#else
778	MEMCPY_BCOPY(sha->digest, sha->state, SHA256_DIGEST_LENGTH);
779#endif
780
781	/* accumulate the digests */
782	for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
783		sha->digest_sum[i] ^= sha->digest[i];
784
785	/* Clean up state data: */
786	MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha256_t, state));
787	usedspace = 0;
788
789	return 0;
790}
791
792static int
793sha256_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
794{
795	register Sha256_t*	sha = (Sha256_t*)p;
796	register sha2_byte*	d;
797	register sha2_byte*	e;
798
799	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
800	e = d + SHA256_DIGEST_LENGTH;
801	while (d < e)
802		sfprintf(sp, "%02x", *d++);
803	return 0;
804}
805
806static int
807sha256_data(Sum_t* p, Sumdata_t* data)
808{
809	register Sha256_t*	sha = (Sha256_t*)p;
810
811	data->size = SHA256_DIGEST_LENGTH;
812	data->num = 0;
813	data->buf = sha->digest;
814	return 0;
815}
816
817/*** SHA-512: *********************************************************/
818
819#define sha512_description "FIPS SHA-512 secure hash algorithm."
820#define sha512_options	"\
821[+(version)?sha-512 (FIPS) 2000-01-01]\
822[+(author)?Aaron D. Gifford]\
823"
824#define sha512_match	"sha512|sha-512|SHA512|SHA-512"
825#define sha512_scale	0
826
827#define sha512_padding	md5_pad
828
829#define SHA512_CTX	Sha512_t
830
831typedef struct Sha512_s
832{
833	_SUM_PUBLIC_
834	_SUM_PRIVATE_
835	sha2_byte	digest[SHA512_DIGEST_LENGTH];
836	sha2_byte	digest_sum[SHA512_DIGEST_LENGTH];
837	sha2_word64	state[8];
838	sha2_word64	bitcount[2];
839	sha2_byte	buffer[SHA512_BLOCK_LENGTH];
840} Sha512_t;
841
842#ifdef SHA2_UNROLL_TRANSFORM
843
844/* Unrolled SHA-512 round macros: */
845#if BYTE_ORDER == LITTLE_ENDIAN
846
847#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
848	REVERSE64(*data++, W512[j]); \
849	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
850             K512[j] + W512[j]; \
851	(d) += T1, \
852	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
853	j++
854
855
856#else /* BYTE_ORDER == LITTLE_ENDIAN */
857
858#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
859	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
860             K512[j] + (W512[j] = *data++); \
861	(d) += T1; \
862	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
863	j++
864
865#endif /* BYTE_ORDER == LITTLE_ENDIAN */
866
867#define ROUND512(a,b,c,d,e,f,g,h)	\
868	s0 = W512[(j+1)&0x0f]; \
869	s0 = sigma0_512(s0); \
870	s1 = W512[(j+14)&0x0f]; \
871	s1 = sigma1_512(s1); \
872	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
873             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
874	(d) += T1; \
875	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
876	j++
877
878static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
879	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
880	sha2_word64	T1, *W512 = (sha2_word64*)sha->buffer;
881	int		j;
882
883	/* Initialize registers with the prev. intermediate value */
884	a = sha->state[0];
885	b = sha->state[1];
886	c = sha->state[2];
887	d = sha->state[3];
888	e = sha->state[4];
889	f = sha->state[5];
890	g = sha->state[6];
891	h = sha->state[7];
892
893	j = 0;
894	do {
895		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
896		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
897		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
898		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
899		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
900		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
901		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
902		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
903	} while (j < 16);
904
905	/* Now for the remaining rounds up to 79: */
906	do {
907		ROUND512(a,b,c,d,e,f,g,h);
908		ROUND512(h,a,b,c,d,e,f,g);
909		ROUND512(g,h,a,b,c,d,e,f);
910		ROUND512(f,g,h,a,b,c,d,e);
911		ROUND512(e,f,g,h,a,b,c,d);
912		ROUND512(d,e,f,g,h,a,b,c);
913		ROUND512(c,d,e,f,g,h,a,b);
914		ROUND512(b,c,d,e,f,g,h,a);
915	} while (j < 80);
916
917	/* Compute the current intermediate hash value */
918	sha->state[0] += a;
919	sha->state[1] += b;
920	sha->state[2] += c;
921	sha->state[3] += d;
922	sha->state[4] += e;
923	sha->state[5] += f;
924	sha->state[6] += g;
925	sha->state[7] += h;
926
927	/* Clean up */
928	a = b = c = d = e = f = g = h = T1 = 0;
929}
930
931#else /* SHA2_UNROLL_TRANSFORM */
932
933static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
934	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
935	sha2_word64	T1, T2, *W512 = (sha2_word64*)sha->buffer;
936	int		j;
937
938	/* Initialize registers with the prev. intermediate value */
939	a = sha->state[0];
940	b = sha->state[1];
941	c = sha->state[2];
942	d = sha->state[3];
943	e = sha->state[4];
944	f = sha->state[5];
945	g = sha->state[6];
946	h = sha->state[7];
947
948	j = 0;
949	do {
950#if BYTE_ORDER == LITTLE_ENDIAN
951		/* Convert TO host byte order */
952		REVERSE64(*data++, W512[j]);
953		/* Apply the SHA-512 compression function to update a..h */
954		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
955#else /* BYTE_ORDER == LITTLE_ENDIAN */
956		/* Apply the SHA-512 compression function to update a..h with copy */
957		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
958#endif /* BYTE_ORDER == LITTLE_ENDIAN */
959		T2 = Sigma0_512(a) + Maj(a, b, c);
960		h = g;
961		g = f;
962		f = e;
963		e = d + T1;
964		d = c;
965		c = b;
966		b = a;
967		a = T1 + T2;
968
969		j++;
970	} while (j < 16);
971
972	do {
973		/* Part of the message block expansion: */
974		s0 = W512[(j+1)&0x0f];
975		s0 = sigma0_512(s0);
976		s1 = W512[(j+14)&0x0f];
977		s1 =  sigma1_512(s1);
978
979		/* Apply the SHA-512 compression function to update a..h */
980		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
981		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
982		T2 = Sigma0_512(a) + Maj(a, b, c);
983		h = g;
984		g = f;
985		f = e;
986		e = d + T1;
987		d = c;
988		c = b;
989		b = a;
990		a = T1 + T2;
991
992		j++;
993	} while (j < 80);
994
995	/* Compute the current intermediate hash value */
996	sha->state[0] += a;
997	sha->state[1] += b;
998	sha->state[2] += c;
999	sha->state[3] += d;
1000	sha->state[4] += e;
1001	sha->state[5] += f;
1002	sha->state[6] += g;
1003	sha->state[7] += h;
1004
1005	/* Clean up */
1006	a = b = c = d = e = f = g = h = T1 = T2 = 0;
1007}
1008
1009#endif /* SHA2_UNROLL_TRANSFORM */
1010
1011static int
1012sha512_block(register Sum_t* p, const void* s, size_t len)
1013{
1014	Sha512_t*	sha = (Sha512_t*)p;
1015	sha2_byte*	data = (sha2_byte*)s;
1016	unsigned int	freespace, usedspace;
1017
1018	if (!len)
1019		return 0;
1020	usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
1021	if (usedspace > 0) {
1022		/* Calculate how much free space is available in the buffer */
1023		freespace = SHA512_BLOCK_LENGTH - usedspace;
1024
1025		if (len >= freespace) {
1026			/* Fill the buffer completely and process it */
1027			MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
1028			ADDINC128(sha->bitcount, freespace << 3);
1029			len -= freespace;
1030			data += freespace;
1031			SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1032		} else {
1033			/* The buffer is not yet full */
1034			MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
1035			ADDINC128(sha->bitcount, len << 3);
1036			/* Clean up: */
1037			usedspace = freespace = 0;
1038			return 0;
1039		}
1040	}
1041	while (len >= SHA512_BLOCK_LENGTH) {
1042		/* Process as many complete blocks as we can */
1043		SHA512_Transform(sha, (sha2_word64*)data);
1044		ADDINC128(sha->bitcount, SHA512_BLOCK_LENGTH << 3);
1045		len -= SHA512_BLOCK_LENGTH;
1046		data += SHA512_BLOCK_LENGTH;
1047	}
1048	if (len > 0) {
1049		/* There's left-overs, so save 'em */
1050		MEMCPY_BCOPY(sha->buffer, data, len);
1051		ADDINC128(sha->bitcount, len << 3);
1052	}
1053	/* Clean up: */
1054	usedspace = freespace = 0;
1055
1056	return 0;
1057}
1058
1059static int
1060sha512_init(Sum_t* p)
1061{
1062	register Sha512_t*	sha = (Sha512_t*)p;
1063
1064	MEMCPY_BCOPY(sha->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
1065	MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH);
1066	sha->bitcount[0] = sha->bitcount[1] =  0;
1067
1068	return 0;
1069}
1070
1071static Sum_t*
1072sha512_open(const Method_t* method, const char* name)
1073{
1074	Sha512_t*	sha;
1075
1076	if (sha = newof(0, Sha512_t, 1, 0))
1077	{
1078		sha->method = (Method_t*)method;
1079		sha->name = name;
1080		sha512_init((Sum_t*)sha);
1081	}
1082	return (Sum_t*)sha;
1083}
1084
1085static int
1086sha512_done(Sum_t* p)
1087{
1088	Sha512_t*	sha = (Sha512_t*)p;
1089	unsigned int	usedspace;
1090	register int	i;
1091
1092	usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
1093#if BYTE_ORDER == LITTLE_ENDIAN
1094	/* Convert FROM host byte order */
1095	REVERSE64(sha->bitcount[0],sha->bitcount[0]);
1096	REVERSE64(sha->bitcount[1],sha->bitcount[1]);
1097#endif
1098	if (usedspace > 0) {
1099		/* Begin padding with a 1 bit: */
1100		sha->buffer[usedspace++] = 0x80;
1101
1102		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
1103			/* Set-up for the last transform: */
1104			MEMSET_BZERO(&sha->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
1105		} else {
1106			if (usedspace < SHA512_BLOCK_LENGTH) {
1107				MEMSET_BZERO(&sha->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
1108			}
1109			/* Do second-to-last transform: */
1110			SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1111
1112			/* And set-up for the last transform: */
1113			MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH - 2);
1114		}
1115	} else {
1116		/* Prepare for final transform: */
1117		MEMSET_BZERO(sha->buffer, SHA512_SHORT_BLOCK_LENGTH);
1118
1119		/* Begin padding with a 1 bit: */
1120		*sha->buffer = 0x80;
1121	}
1122	/* Store the length of input data (in bits): */
1123	*(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH] = sha->bitcount[1];
1124	*(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = sha->bitcount[0];
1125
1126	/* Final transform: */
1127	SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1128
1129#if BYTE_ORDER == LITTLE_ENDIAN
1130	{
1131		/* Convert TO host byte order */
1132		sha2_word64*	d = (sha2_word64*)sha->digest;
1133		int		j;
1134		for (j = 0; j < 8; j++) {
1135			REVERSE64(sha->state[j],sha->state[j]);
1136			*d++ = sha->state[j];
1137		}
1138	}
1139#else
1140	MEMCPY_BCOPY(sha->digest, sha->state, SHA512_DIGEST_LENGTH);
1141#endif
1142
1143	/* accumulate the digests */
1144	for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
1145		sha->digest_sum[i] ^= sha->digest[i];
1146
1147	/* Clean up state data: */
1148	MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha512_t, state));
1149	usedspace = 0;
1150
1151	return 0;
1152}
1153
1154static int
1155sha512_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
1156{
1157	register Sha512_t*	sha = (Sha512_t*)p;
1158	register sha2_byte*	d;
1159	register sha2_byte*	e;
1160
1161	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
1162	e = d + SHA512_DIGEST_LENGTH;
1163	while (d < e)
1164		sfprintf(sp, "%02x", *d++);
1165	return 0;
1166}
1167
1168static int
1169sha512_data(Sum_t* p, Sumdata_t* data)
1170{
1171	register Sha512_t*	sha = (Sha512_t*)p;
1172
1173	data->size = SHA512_DIGEST_LENGTH;
1174	data->num = 0;
1175	data->buf = sha->digest;
1176	return 0;
1177}
1178
1179/*** SHA-384: *********************************************************/
1180
1181#define sha384_description "FIPS SHA-384 secure hash algorithm."
1182#define sha384_options	"\
1183[+(version)?sha-384 (FIPS) 2000-01-01]\
1184[+(author)?Aaron D. Gifford]\
1185"
1186#define sha384_match	"sha384|sha-384|SHA384|SHA-384"
1187#define sha384_scale	0
1188#define sha384_block	sha512_block
1189#define sha384_done	sha512_done
1190
1191#define sha384_padding	md5_pad
1192
1193#define Sha384_t		Sha512_t
1194#define SHA384_CTX		Sha384_t
1195#define SHA384_DIGEST_LENGTH	48
1196
1197static int
1198sha384_init(Sum_t* p)
1199{
1200	register Sha384_t*	sha = (Sha384_t*)p;
1201
1202	MEMCPY_BCOPY(sha->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
1203	MEMSET_BZERO(sha->buffer, SHA384_BLOCK_LENGTH);
1204	sha->bitcount[0] = sha->bitcount[1] = 0;
1205
1206	return 0;
1207}
1208
1209static Sum_t*
1210sha384_open(const Method_t* method, const char* name)
1211{
1212	Sha384_t*	sha;
1213
1214	if (sha = newof(0, Sha384_t, 1, 0))
1215	{
1216		sha->method = (Method_t*)method;
1217		sha->name = name;
1218		sha384_init((Sum_t*)sha);
1219	}
1220	return (Sum_t*)sha;
1221}
1222
1223static int
1224sha384_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
1225{
1226	register Sha384_t*	sha = (Sha384_t*)p;
1227	register sha2_byte*	d;
1228	register sha2_byte*	e;
1229
1230	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
1231	e = d + SHA384_DIGEST_LENGTH;
1232	while (d < e)
1233		sfprintf(sp, "%02x", *d++);
1234	return 0;
1235}
1236
1237static int
1238sha384_data(Sum_t* p, Sumdata_t* data)
1239{
1240	register Sha384_t*	sha = (Sha384_t*)p;
1241
1242	data->size = SHA384_DIGEST_LENGTH;
1243	data->num = 0;
1244	data->buf = sha->digest;
1245	return 0;
1246}
1247
1248#endif /* _typ_int64_t */
1249