xref: /titanic_41/usr/src/lib/libsum/common/sum-sha2.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
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 
91 typedef  uint8_t sha2_byte;	/* Exactly 1 byte */
92 typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
93 typedef 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 
152 typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
153 typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
154 typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
155 
156 #else /* SHA2_USE_INTTYPES_H */
157 
158 typedef u_int8_t  sha2_byte;	/* Exactly 1 byte */
159 typedef u_int32_t sha2_word32;	/* Exactly 4 bytes */
160 typedef 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: */
284 static 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: */
304 static 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: */
316 static 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 */
403 static 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 */
426 static 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 
462 typedef 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 
SHA256_Transform(SHA256_CTX * sha,const sha2_word32 * data)510 static 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 
SHA256_Transform(SHA256_CTX * sha,const sha2_word32 * data)568 static 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 
648 static int
sha256_block(register Sum_t * p,const void * s,size_t len)649 sha256_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 
696 static int
sha256_init(Sum_t * p)697 sha256_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 
708 static Sum_t*
sha256_open(const Method_t * method,const char * name)709 sha256_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 
722 static int
sha256_done(Sum_t * p)723 sha256_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 
792 static int
sha256_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)793 sha256_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 
806 static int
sha256_data(Sum_t * p,Sumdata_t * data)807 sha256_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 
831 typedef 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 
SHA512_Transform(SHA512_CTX * sha,const sha2_word64 * data)878 static 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 
SHA512_Transform(SHA512_CTX * sha,const sha2_word64 * data)933 static 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 
1011 static int
sha512_block(register Sum_t * p,const void * s,size_t len)1012 sha512_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 
1059 static int
sha512_init(Sum_t * p)1060 sha512_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 
1071 static Sum_t*
sha512_open(const Method_t * method,const char * name)1072 sha512_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 
1085 static int
sha512_done(Sum_t * p)1086 sha512_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 
1154 static int
sha512_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)1155 sha512_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 
1168 static int
sha512_data(Sum_t * p,Sumdata_t * data)1169 sha512_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 
1197 static int
sha384_init(Sum_t * p)1198 sha384_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 
1209 static Sum_t*
sha384_open(const Method_t * method,const char * name)1210 sha384_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 
1223 static int
sha384_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)1224 sha384_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 
1237 static int
sha384_data(Sum_t * p,Sumdata_t * data)1238 sha384_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