17c2fbfb3SApril Chin #pragma prototyped
27c2fbfb3SApril Chin 
37c2fbfb3SApril Chin #if _typ_int64_t
47c2fbfb3SApril Chin 
57c2fbfb3SApril Chin /*
67c2fbfb3SApril Chin  * Aaron D. Gifford's SHA {256,384,512} code transcribed into a -lsum method
7*b30d1939SAndy Fiddaman  * with bitcount[] order reversed to allow a single noalias buffer copy
87c2fbfb3SApril Chin  */
97c2fbfb3SApril Chin 
107c2fbfb3SApril Chin /*
117c2fbfb3SApril Chin  * Copyright (c) 2000-2001, Aaron D. Gifford
127c2fbfb3SApril Chin  * All rights reserved.
137c2fbfb3SApril Chin  *
147c2fbfb3SApril Chin  * Redistribution and use in source and binary forms, with or without
157c2fbfb3SApril Chin  * modification, are permitted provided that the following conditions
167c2fbfb3SApril Chin  * are met:
177c2fbfb3SApril Chin  * 1. Redistributions of source code must retain the above copyright
187c2fbfb3SApril Chin  *    notice, this list of conditions and the following disclaimer.
197c2fbfb3SApril Chin  * 2. Redistributions in binary form must reproduce the above copyright
207c2fbfb3SApril Chin  *    notice, this list of conditions and the following disclaimer in the
217c2fbfb3SApril Chin  *    documentation and/or other materials provided with the distribution.
227c2fbfb3SApril Chin  * 3. Neither the name of the copyright holder nor the names of contributors
237c2fbfb3SApril Chin  *    may be used to endorse or promote products derived from this software
247c2fbfb3SApril Chin  *    without specific prior written permission.
257c2fbfb3SApril Chin  *
267c2fbfb3SApril Chin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
277c2fbfb3SApril Chin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287c2fbfb3SApril Chin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297c2fbfb3SApril Chin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
307c2fbfb3SApril Chin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
317c2fbfb3SApril Chin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
327c2fbfb3SApril Chin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
337c2fbfb3SApril Chin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
347c2fbfb3SApril Chin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
357c2fbfb3SApril Chin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
367c2fbfb3SApril Chin  * SUCH DAMAGE.
377c2fbfb3SApril Chin  */
387c2fbfb3SApril Chin 
397c2fbfb3SApril Chin /*
407c2fbfb3SApril Chin  * ASSERT NOTE:
417c2fbfb3SApril Chin  * Some sanity checking code is included using assert().  On my FreeBSD
427c2fbfb3SApril Chin  * system, this additional code can be removed by compiling with NDEBUG
437c2fbfb3SApril Chin  * defined.  Check your own systems manpage on assert() to see how to
447c2fbfb3SApril Chin  * compile WITHOUT the sanity checking code on your system.
457c2fbfb3SApril Chin  *
467c2fbfb3SApril Chin  * UNROLLED TRANSFORM LOOP NOTE:
477c2fbfb3SApril Chin  * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
487c2fbfb3SApril Chin  * loop version for the hash transform rounds (defined using macros
497c2fbfb3SApril Chin  * later in this file).  Either define on the command line, for example:
507c2fbfb3SApril Chin  *
517c2fbfb3SApril Chin  *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
527c2fbfb3SApril Chin  *
537c2fbfb3SApril Chin  * or define below:
547c2fbfb3SApril Chin  *
557c2fbfb3SApril Chin  *   #define SHA2_UNROLL_TRANSFORM
567c2fbfb3SApril Chin  *
577c2fbfb3SApril Chin  */
587c2fbfb3SApril Chin 
597c2fbfb3SApril Chin /*** SHA-256/384/512 Machine Architecture Definitions *****************/
607c2fbfb3SApril Chin 
617c2fbfb3SApril Chin #if _PACKAGE_ast
627c2fbfb3SApril Chin 
637c2fbfb3SApril Chin #ifndef __USE_BSD
647c2fbfb3SApril Chin #define __undef__USE_BSD
657c2fbfb3SApril Chin #define __USE_BSD
667c2fbfb3SApril Chin #endif
677c2fbfb3SApril Chin #include <endian.h>
687c2fbfb3SApril Chin #ifdef	__undef__USE_BSD
697c2fbfb3SApril Chin #undef	__undef__USE_BSD
707c2fbfb3SApril Chin #undef	__USE_BSD
717c2fbfb3SApril Chin #endif
727c2fbfb3SApril Chin 
737c2fbfb3SApril Chin typedef  uint8_t sha2_byte;	/* Exactly 1 byte */
747c2fbfb3SApril Chin typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
757c2fbfb3SApril Chin typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
767c2fbfb3SApril Chin 
777c2fbfb3SApril Chin #define assert(x)
787c2fbfb3SApril Chin 
797c2fbfb3SApril Chin #undef	R
807c2fbfb3SApril Chin #undef	S32
817c2fbfb3SApril Chin #undef	S64
827c2fbfb3SApril Chin 
837c2fbfb3SApril Chin #else /* _PACKAGE_ast */
847c2fbfb3SApril Chin 
857c2fbfb3SApril Chin /*
867c2fbfb3SApril Chin  * BYTE_ORDER NOTE:
877c2fbfb3SApril Chin  *
887c2fbfb3SApril Chin  * Please make sure that your system defines BYTE_ORDER.  If your
897c2fbfb3SApril Chin  * architecture is little-endian, make sure it also defines
907c2fbfb3SApril Chin  * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
917c2fbfb3SApril Chin  * equivilent.
927c2fbfb3SApril Chin  *
937c2fbfb3SApril Chin  * If your system does not define the above, then you can do so by
947c2fbfb3SApril Chin  * hand like this:
957c2fbfb3SApril Chin  *
967c2fbfb3SApril Chin  *   #define LITTLE_ENDIAN 1234
977c2fbfb3SApril Chin  *   #define BIG_ENDIAN    4321
987c2fbfb3SApril Chin  *
997c2fbfb3SApril Chin  * And for little-endian machines, add:
1007c2fbfb3SApril Chin  *
1017c2fbfb3SApril Chin  *   #define BYTE_ORDER LITTLE_ENDIAN
1027c2fbfb3SApril Chin  *
1037c2fbfb3SApril Chin  * Or for big-endian machines:
1047c2fbfb3SApril Chin  *
1057c2fbfb3SApril Chin  *   #define BYTE_ORDER BIG_ENDIAN
1067c2fbfb3SApril Chin  *
1077c2fbfb3SApril Chin  * The FreeBSD machine this was written on defines BYTE_ORDER
1087c2fbfb3SApril Chin  * appropriately by including <sys/types.h> (which in turn includes
1097c2fbfb3SApril Chin  * <machine/endian.h> where the appropriate definitions are actually
1107c2fbfb3SApril Chin  * made).
1117c2fbfb3SApril Chin  */
1127c2fbfb3SApril Chin 
1137c2fbfb3SApril Chin #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
1147c2fbfb3SApril Chin #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
1157c2fbfb3SApril Chin #endif
1167c2fbfb3SApril Chin 
1177c2fbfb3SApril Chin /*
1187c2fbfb3SApril Chin  * Define the following sha2_* types to types of the correct length on
1197c2fbfb3SApril Chin  * the native archtecture.   Most BSD systems and Linux define u_intXX_t
1207c2fbfb3SApril Chin  * types.  Machines with very recent ANSI C headers, can use the
1217c2fbfb3SApril Chin  * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
1227c2fbfb3SApril Chin  * during compile or in the sha.h header file.
1237c2fbfb3SApril Chin  *
1247c2fbfb3SApril Chin  * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
1257c2fbfb3SApril Chin  * will need to define these three typedefs below (and the appropriate
1267c2fbfb3SApril Chin  * ones in sha.h too) by hand according to their system architecture.
1277c2fbfb3SApril Chin  *
1287c2fbfb3SApril Chin  * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
1297c2fbfb3SApril Chin  * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
1307c2fbfb3SApril Chin  */
1317c2fbfb3SApril Chin 
1327c2fbfb3SApril Chin #ifdef SHA2_USE_INTTYPES_H
1337c2fbfb3SApril Chin 
1347c2fbfb3SApril Chin typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
1357c2fbfb3SApril Chin typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
1367c2fbfb3SApril Chin typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
1377c2fbfb3SApril Chin 
1387c2fbfb3SApril Chin #else /* SHA2_USE_INTTYPES_H */
1397c2fbfb3SApril Chin 
1407c2fbfb3SApril Chin typedef u_int8_t  sha2_byte;	/* Exactly 1 byte */
1417c2fbfb3SApril Chin typedef u_int32_t sha2_word32;	/* Exactly 4 bytes */
1427c2fbfb3SApril Chin typedef u_int64_t sha2_word64;	/* Exactly 8 bytes */
1437c2fbfb3SApril Chin 
1447c2fbfb3SApril Chin #endif /* SHA2_USE_INTTYPES_H */
1457c2fbfb3SApril Chin 
1467c2fbfb3SApril Chin #endif /* _PACKAGE_ast */
1477c2fbfb3SApril Chin 
1487c2fbfb3SApril Chin /*** SHA-256/384/512 Various Length Definitions ***********************/
1497c2fbfb3SApril Chin 
1507c2fbfb3SApril Chin #define SHA256_BLOCK_LENGTH		64
1517c2fbfb3SApril Chin #define SHA256_DIGEST_LENGTH		32
1527c2fbfb3SApril Chin #define SHA384_BLOCK_LENGTH		128
1537c2fbfb3SApril Chin #define SHA384_DIGEST_LENGTH		48
1547c2fbfb3SApril Chin #define SHA512_BLOCK_LENGTH		128
1557c2fbfb3SApril Chin #define SHA512_DIGEST_LENGTH		64
1567c2fbfb3SApril Chin 
1577c2fbfb3SApril Chin #define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
1587c2fbfb3SApril Chin #define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
1597c2fbfb3SApril Chin #define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
1607c2fbfb3SApril Chin 
1617c2fbfb3SApril Chin /*** ENDIAN REVERSAL MACROS *******************************************/
1627c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
1637c2fbfb3SApril Chin #define REVERSE32(w,x)	{ \
1647c2fbfb3SApril Chin 	sha2_word32 tmp = (w); \
1657c2fbfb3SApril Chin 	tmp = (tmp >> 16) | (tmp << 16); \
1667c2fbfb3SApril Chin 	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
1677c2fbfb3SApril Chin }
1687c2fbfb3SApril Chin #if _ast_LL
1697c2fbfb3SApril Chin #define REVERSE64(w,x)	{ \
1707c2fbfb3SApril Chin 	sha2_word64 tmp = (w); \
1717c2fbfb3SApril Chin 	tmp = (tmp >> 32) | (tmp << 32); \
1727c2fbfb3SApril Chin 	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
1737c2fbfb3SApril Chin 	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
1747c2fbfb3SApril Chin 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
1757c2fbfb3SApril Chin 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
1767c2fbfb3SApril Chin }
1777c2fbfb3SApril Chin #else
1787c2fbfb3SApril Chin #define REVERSE64(w,x)	{ \
1797c2fbfb3SApril Chin 	sha2_word64 tmp = (w); \
1807c2fbfb3SApril Chin 	tmp = (tmp >> 32) | (tmp << 32); \
1817c2fbfb3SApril Chin 	tmp = ((tmp & ((sha2_word64)0xff00ff00ff00ff00)) >> 8) | \
1827c2fbfb3SApril Chin 	      ((tmp & ((sha2_word64)0x00ff00ff00ff00ff)) << 8); \
1837c2fbfb3SApril Chin 	(x) = ((tmp & ((sha2_word64)0xffff0000ffff0000)) >> 16) | \
1847c2fbfb3SApril Chin 	      ((tmp & ((sha2_word64)0x0000ffff0000ffff)) << 16); \
1857c2fbfb3SApril Chin }
1867c2fbfb3SApril Chin #endif
1877c2fbfb3SApril Chin #endif /* BYTE_ORDER == LITTLE_ENDIAN */
1887c2fbfb3SApril Chin 
1897c2fbfb3SApril Chin /*
1907c2fbfb3SApril Chin  * Macro for incrementally adding the unsigned 64-bit integer n to the
1917c2fbfb3SApril Chin  * unsigned 128-bit integer (represented using a two-element array of
1927c2fbfb3SApril Chin  * 64-bit words):
1937c2fbfb3SApril Chin  */
1947c2fbfb3SApril Chin 
1957c2fbfb3SApril Chin #define ADDINC128(w,n)	{ \
196*b30d1939SAndy Fiddaman 	(w)[1] += (sha2_word64)(n); \
197*b30d1939SAndy Fiddaman 	if ((w)[1] < (n)) { \
198*b30d1939SAndy Fiddaman 		(w)[0]++; \
1997c2fbfb3SApril Chin 	} \
2007c2fbfb3SApril Chin }
2017c2fbfb3SApril Chin 
2027c2fbfb3SApril Chin /*
2037c2fbfb3SApril Chin  * Macros for copying blocks of memory and for zeroing out ranges
2047c2fbfb3SApril Chin  * of memory.  Using these macros makes it easy to switch from
2057c2fbfb3SApril Chin  * using memset()/memcpy() and using bzero()/bcopy().
2067c2fbfb3SApril Chin  *
2077c2fbfb3SApril Chin  * Please define either SHA2_USE_MEMSET_MEMCPY or define
2087c2fbfb3SApril Chin  * SHA2_USE_BZERO_BCOPY depending on which function set you
2097c2fbfb3SApril Chin  * choose to use:
2107c2fbfb3SApril Chin  */
2117c2fbfb3SApril Chin 
2127c2fbfb3SApril Chin #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
2137c2fbfb3SApril Chin /* Default to memset()/memcpy() if no option is specified */
2147c2fbfb3SApril Chin #define	SHA2_USE_MEMSET_MEMCPY	1
2157c2fbfb3SApril Chin #endif
2167c2fbfb3SApril Chin #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
2177c2fbfb3SApril Chin /* Abort with an error if BOTH options are defined */
2187c2fbfb3SApril Chin #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
2197c2fbfb3SApril Chin #endif
2207c2fbfb3SApril Chin 
2217c2fbfb3SApril Chin #ifdef SHA2_USE_MEMSET_MEMCPY
2227c2fbfb3SApril Chin #define MEMSET_BZERO(p,l)	memset((p), 0, (l))
2237c2fbfb3SApril Chin #define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
2247c2fbfb3SApril Chin #endif
2257c2fbfb3SApril Chin #ifdef SHA2_USE_BZERO_BCOPY
2267c2fbfb3SApril Chin #define MEMSET_BZERO(p,l)	bzero((p), (l))
2277c2fbfb3SApril Chin #define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
2287c2fbfb3SApril Chin #endif
2297c2fbfb3SApril Chin 
2307c2fbfb3SApril Chin 
2317c2fbfb3SApril Chin /*** THE SIX LOGICAL FUNCTIONS ****************************************/
2327c2fbfb3SApril Chin /*
2337c2fbfb3SApril Chin  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
2347c2fbfb3SApril Chin  *
2357c2fbfb3SApril Chin  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
2367c2fbfb3SApril Chin  *   S is a ROTATION) because the SHA-256/384/512 description document
2377c2fbfb3SApril Chin  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
2387c2fbfb3SApril Chin  *   same "backwards" definition.
2397c2fbfb3SApril Chin  */
2407c2fbfb3SApril Chin 
2417c2fbfb3SApril Chin /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
2427c2fbfb3SApril Chin #define R(b,x) 		((x) >> (b))
2437c2fbfb3SApril Chin /* 32-bit Rotate-right (used in SHA-256): */
2447c2fbfb3SApril Chin #define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
2457c2fbfb3SApril Chin /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
2467c2fbfb3SApril Chin #define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
2477c2fbfb3SApril Chin 
2487c2fbfb3SApril Chin /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
2497c2fbfb3SApril Chin #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
2507c2fbfb3SApril Chin #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
2517c2fbfb3SApril Chin 
2527c2fbfb3SApril Chin /* Four of six logical functions used in SHA-256: */
2537c2fbfb3SApril Chin #define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
2547c2fbfb3SApril Chin #define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
2557c2fbfb3SApril Chin #define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
2567c2fbfb3SApril Chin #define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
2577c2fbfb3SApril Chin 
2587c2fbfb3SApril Chin /* Four of six logical functions used in SHA-384 and SHA-512: */
2597c2fbfb3SApril Chin #define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
2607c2fbfb3SApril Chin #define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
2617c2fbfb3SApril Chin #define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
2627c2fbfb3SApril Chin #define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
2637c2fbfb3SApril Chin 
2647c2fbfb3SApril Chin /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
2657c2fbfb3SApril Chin /* Hash constant words K for SHA-256: */
2667c2fbfb3SApril Chin static const sha2_word32 K256[64] = {
2677c2fbfb3SApril Chin 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
2687c2fbfb3SApril Chin 	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
2697c2fbfb3SApril Chin 	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
2707c2fbfb3SApril Chin 	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
2717c2fbfb3SApril Chin 	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
2727c2fbfb3SApril Chin 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
2737c2fbfb3SApril Chin 	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
2747c2fbfb3SApril Chin 	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
2757c2fbfb3SApril Chin 	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
2767c2fbfb3SApril Chin 	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
2777c2fbfb3SApril Chin 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
2787c2fbfb3SApril Chin 	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
2797c2fbfb3SApril Chin 	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
2807c2fbfb3SApril Chin 	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
2817c2fbfb3SApril Chin 	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
2827c2fbfb3SApril Chin 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
2837c2fbfb3SApril Chin };
2847c2fbfb3SApril Chin 
2857c2fbfb3SApril Chin /* Initial hash value H for SHA-256: */
2867c2fbfb3SApril Chin static const sha2_word32 sha256_initial_hash_value[8] = {
2877c2fbfb3SApril Chin 	0x6a09e667UL,
2887c2fbfb3SApril Chin 	0xbb67ae85UL,
2897c2fbfb3SApril Chin 	0x3c6ef372UL,
2907c2fbfb3SApril Chin 	0xa54ff53aUL,
2917c2fbfb3SApril Chin 	0x510e527fUL,
2927c2fbfb3SApril Chin 	0x9b05688cUL,
2937c2fbfb3SApril Chin 	0x1f83d9abUL,
2947c2fbfb3SApril Chin 	0x5be0cd19UL
2957c2fbfb3SApril Chin };
2967c2fbfb3SApril Chin 
2977c2fbfb3SApril Chin /* Hash constant words K for SHA-384 and SHA-512: */
2987c2fbfb3SApril Chin static const sha2_word64 K512[80] = {
2997c2fbfb3SApril Chin #if _ast_LL
3007c2fbfb3SApril Chin 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
3017c2fbfb3SApril Chin 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
3027c2fbfb3SApril Chin 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
3037c2fbfb3SApril Chin 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
3047c2fbfb3SApril Chin 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
3057c2fbfb3SApril Chin 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
3067c2fbfb3SApril Chin 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
3077c2fbfb3SApril Chin 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
3087c2fbfb3SApril Chin 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
3097c2fbfb3SApril Chin 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
3107c2fbfb3SApril Chin 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
3117c2fbfb3SApril Chin 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
3127c2fbfb3SApril Chin 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
3137c2fbfb3SApril Chin 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
3147c2fbfb3SApril Chin 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
3157c2fbfb3SApril Chin 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
3167c2fbfb3SApril Chin 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
3177c2fbfb3SApril Chin 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
3187c2fbfb3SApril Chin 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
3197c2fbfb3SApril Chin 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
3207c2fbfb3SApril Chin 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
3217c2fbfb3SApril Chin 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
3227c2fbfb3SApril Chin 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
3237c2fbfb3SApril Chin 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
3247c2fbfb3SApril Chin 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
3257c2fbfb3SApril Chin 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
3267c2fbfb3SApril Chin 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
3277c2fbfb3SApril Chin 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
3287c2fbfb3SApril Chin 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
3297c2fbfb3SApril Chin 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
3307c2fbfb3SApril Chin 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
3317c2fbfb3SApril Chin 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
3327c2fbfb3SApril Chin 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
3337c2fbfb3SApril Chin 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
3347c2fbfb3SApril Chin 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
3357c2fbfb3SApril Chin 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
3367c2fbfb3SApril Chin 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
3377c2fbfb3SApril Chin 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
3387c2fbfb3SApril Chin 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
3397c2fbfb3SApril Chin 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
3407c2fbfb3SApril Chin #else
3417c2fbfb3SApril Chin 	((sha2_word64)0x428a2f98d728ae22), ((sha2_word64)0x7137449123ef65cd),
3427c2fbfb3SApril Chin 	((sha2_word64)0xb5c0fbcfec4d3b2f), ((sha2_word64)0xe9b5dba58189dbbc),
3437c2fbfb3SApril Chin 	((sha2_word64)0x3956c25bf348b538), ((sha2_word64)0x59f111f1b605d019),
3447c2fbfb3SApril Chin 	((sha2_word64)0x923f82a4af194f9b), ((sha2_word64)0xab1c5ed5da6d8118),
3457c2fbfb3SApril Chin 	((sha2_word64)0xd807aa98a3030242), ((sha2_word64)0x12835b0145706fbe),
3467c2fbfb3SApril Chin 	((sha2_word64)0x243185be4ee4b28c), ((sha2_word64)0x550c7dc3d5ffb4e2),
3477c2fbfb3SApril Chin 	((sha2_word64)0x72be5d74f27b896f), ((sha2_word64)0x80deb1fe3b1696b1),
3487c2fbfb3SApril Chin 	((sha2_word64)0x9bdc06a725c71235), ((sha2_word64)0xc19bf174cf692694),
3497c2fbfb3SApril Chin 	((sha2_word64)0xe49b69c19ef14ad2), ((sha2_word64)0xefbe4786384f25e3),
3507c2fbfb3SApril Chin 	((sha2_word64)0x0fc19dc68b8cd5b5), ((sha2_word64)0x240ca1cc77ac9c65),
3517c2fbfb3SApril Chin 	((sha2_word64)0x2de92c6f592b0275), ((sha2_word64)0x4a7484aa6ea6e483),
3527c2fbfb3SApril Chin 	((sha2_word64)0x5cb0a9dcbd41fbd4), ((sha2_word64)0x76f988da831153b5),
3537c2fbfb3SApril Chin 	((sha2_word64)0x983e5152ee66dfab), ((sha2_word64)0xa831c66d2db43210),
3547c2fbfb3SApril Chin 	((sha2_word64)0xb00327c898fb213f), ((sha2_word64)0xbf597fc7beef0ee4),
3557c2fbfb3SApril Chin 	((sha2_word64)0xc6e00bf33da88fc2), ((sha2_word64)0xd5a79147930aa725),
3567c2fbfb3SApril Chin 	((sha2_word64)0x06ca6351e003826f), ((sha2_word64)0x142929670a0e6e70),
3577c2fbfb3SApril Chin 	((sha2_word64)0x27b70a8546d22ffc), ((sha2_word64)0x2e1b21385c26c926),
3587c2fbfb3SApril Chin 	((sha2_word64)0x4d2c6dfc5ac42aed), ((sha2_word64)0x53380d139d95b3df),
3597c2fbfb3SApril Chin 	((sha2_word64)0x650a73548baf63de), ((sha2_word64)0x766a0abb3c77b2a8),
3607c2fbfb3SApril Chin 	((sha2_word64)0x81c2c92e47edaee6), ((sha2_word64)0x92722c851482353b),
3617c2fbfb3SApril Chin 	((sha2_word64)0xa2bfe8a14cf10364), ((sha2_word64)0xa81a664bbc423001),
3627c2fbfb3SApril Chin 	((sha2_word64)0xc24b8b70d0f89791), ((sha2_word64)0xc76c51a30654be30),
3637c2fbfb3SApril Chin 	((sha2_word64)0xd192e819d6ef5218), ((sha2_word64)0xd69906245565a910),
3647c2fbfb3SApril Chin 	((sha2_word64)0xf40e35855771202a), ((sha2_word64)0x106aa07032bbd1b8),
3657c2fbfb3SApril Chin 	((sha2_word64)0x19a4c116b8d2d0c8), ((sha2_word64)0x1e376c085141ab53),
3667c2fbfb3SApril Chin 	((sha2_word64)0x2748774cdf8eeb99), ((sha2_word64)0x34b0bcb5e19b48a8),
3677c2fbfb3SApril Chin 	((sha2_word64)0x391c0cb3c5c95a63), ((sha2_word64)0x4ed8aa4ae3418acb),
3687c2fbfb3SApril Chin 	((sha2_word64)0x5b9cca4f7763e373), ((sha2_word64)0x682e6ff3d6b2b8a3),
3697c2fbfb3SApril Chin 	((sha2_word64)0x748f82ee5defb2fc), ((sha2_word64)0x78a5636f43172f60),
3707c2fbfb3SApril Chin 	((sha2_word64)0x84c87814a1f0ab72), ((sha2_word64)0x8cc702081a6439ec),
3717c2fbfb3SApril Chin 	((sha2_word64)0x90befffa23631e28), ((sha2_word64)0xa4506cebde82bde9),
3727c2fbfb3SApril Chin 	((sha2_word64)0xbef9a3f7b2c67915), ((sha2_word64)0xc67178f2e372532b),
3737c2fbfb3SApril Chin 	((sha2_word64)0xca273eceea26619c), ((sha2_word64)0xd186b8c721c0c207),
3747c2fbfb3SApril Chin 	((sha2_word64)0xeada7dd6cde0eb1e), ((sha2_word64)0xf57d4f7fee6ed178),
3757c2fbfb3SApril Chin 	((sha2_word64)0x06f067aa72176fba), ((sha2_word64)0x0a637dc5a2c898a6),
3767c2fbfb3SApril Chin 	((sha2_word64)0x113f9804bef90dae), ((sha2_word64)0x1b710b35131c471b),
3777c2fbfb3SApril Chin 	((sha2_word64)0x28db77f523047d84), ((sha2_word64)0x32caab7b40c72493),
3787c2fbfb3SApril Chin 	((sha2_word64)0x3c9ebe0a15c9bebc), ((sha2_word64)0x431d67c49c100d4c),
3797c2fbfb3SApril Chin 	((sha2_word64)0x4cc5d4becb3e42b6), ((sha2_word64)0x597f299cfc657e2a),
3807c2fbfb3SApril Chin 	((sha2_word64)0x5fcb6fab3ad6faec), ((sha2_word64)0x6c44198c4a475817)
3817c2fbfb3SApril Chin #endif
3827c2fbfb3SApril Chin };
3837c2fbfb3SApril Chin 
3847c2fbfb3SApril Chin /* Initial hash value H for SHA-384 */
3857c2fbfb3SApril Chin static const sha2_word64 sha384_initial_hash_value[8] = {
3867c2fbfb3SApril Chin #if _ast_LL
3877c2fbfb3SApril Chin 	0xcbbb9d5dc1059ed8ULL,
3887c2fbfb3SApril Chin 	0x629a292a367cd507ULL,
3897c2fbfb3SApril Chin 	0x9159015a3070dd17ULL,
3907c2fbfb3SApril Chin 	0x152fecd8f70e5939ULL,
3917c2fbfb3SApril Chin 	0x67332667ffc00b31ULL,
3927c2fbfb3SApril Chin 	0x8eb44a8768581511ULL,
3937c2fbfb3SApril Chin 	0xdb0c2e0d64f98fa7ULL,
3947c2fbfb3SApril Chin 	0x47b5481dbefa4fa4ULL
3957c2fbfb3SApril Chin #else
3967c2fbfb3SApril Chin 	((sha2_word64)0xcbbb9d5dc1059ed8),
3977c2fbfb3SApril Chin 	((sha2_word64)0x629a292a367cd507),
3987c2fbfb3SApril Chin 	((sha2_word64)0x9159015a3070dd17),
3997c2fbfb3SApril Chin 	((sha2_word64)0x152fecd8f70e5939),
4007c2fbfb3SApril Chin 	((sha2_word64)0x67332667ffc00b31),
4017c2fbfb3SApril Chin 	((sha2_word64)0x8eb44a8768581511),
4027c2fbfb3SApril Chin 	((sha2_word64)0xdb0c2e0d64f98fa7),
4037c2fbfb3SApril Chin 	((sha2_word64)0x47b5481dbefa4fa4)
4047c2fbfb3SApril Chin #endif
4057c2fbfb3SApril Chin };
4067c2fbfb3SApril Chin 
4077c2fbfb3SApril Chin /* Initial hash value H for SHA-512 */
4087c2fbfb3SApril Chin static const sha2_word64 sha512_initial_hash_value[8] = {
4097c2fbfb3SApril Chin #if _ast_LL
4107c2fbfb3SApril Chin 	0x6a09e667f3bcc908ULL,
4117c2fbfb3SApril Chin 	0xbb67ae8584caa73bULL,
4127c2fbfb3SApril Chin 	0x3c6ef372fe94f82bULL,
4137c2fbfb3SApril Chin 	0xa54ff53a5f1d36f1ULL,
4147c2fbfb3SApril Chin 	0x510e527fade682d1ULL,
4157c2fbfb3SApril Chin 	0x9b05688c2b3e6c1fULL,
4167c2fbfb3SApril Chin 	0x1f83d9abfb41bd6bULL,
4177c2fbfb3SApril Chin 	0x5be0cd19137e2179ULL
4187c2fbfb3SApril Chin #else
4197c2fbfb3SApril Chin 	((sha2_word64)0x6a09e667f3bcc908),
4207c2fbfb3SApril Chin 	((sha2_word64)0xbb67ae8584caa73b),
4217c2fbfb3SApril Chin 	((sha2_word64)0x3c6ef372fe94f82b),
4227c2fbfb3SApril Chin 	((sha2_word64)0xa54ff53a5f1d36f1),
4237c2fbfb3SApril Chin 	((sha2_word64)0x510e527fade682d1),
4247c2fbfb3SApril Chin 	((sha2_word64)0x9b05688c2b3e6c1f),
4257c2fbfb3SApril Chin 	((sha2_word64)0x1f83d9abfb41bd6b),
4267c2fbfb3SApril Chin 	((sha2_word64)0x5be0cd19137e2179)
4277c2fbfb3SApril Chin #endif
4287c2fbfb3SApril Chin };
4297c2fbfb3SApril Chin 
4307c2fbfb3SApril Chin /*** SHA-256: *********************************************************/
4317c2fbfb3SApril Chin 
4327c2fbfb3SApril Chin #define sha256_description "FIPS SHA-256 secure hash algorithm."
4337c2fbfb3SApril Chin #define sha256_options	"\
4347c2fbfb3SApril Chin [+(version)?sha-256 (FIPS) 2000-01-01]\
4357c2fbfb3SApril Chin [+(author)?Aaron D. Gifford]\
4367c2fbfb3SApril Chin "
4377c2fbfb3SApril Chin #define sha256_match	"sha256|sha-256|SHA256|SHA-256"
4387c2fbfb3SApril Chin #define sha256_scale	0
4397c2fbfb3SApril Chin 
4407c2fbfb3SApril Chin #define sha256_padding	md5_pad
4417c2fbfb3SApril Chin 
4427c2fbfb3SApril Chin #define SHA256_CTX	Sha256_t
4437c2fbfb3SApril Chin 
4447c2fbfb3SApril Chin typedef struct Sha256_s
4457c2fbfb3SApril Chin {
4467c2fbfb3SApril Chin 	_SUM_PUBLIC_
4477c2fbfb3SApril Chin 	_SUM_PRIVATE_
4487c2fbfb3SApril Chin 	sha2_byte	digest[SHA256_DIGEST_LENGTH];
4497c2fbfb3SApril Chin 	sha2_byte	digest_sum[SHA256_DIGEST_LENGTH];
4507c2fbfb3SApril Chin 	sha2_word32	state[8];
4517c2fbfb3SApril Chin 	sha2_word64	bitcount;
4527c2fbfb3SApril Chin 	sha2_byte	buffer[SHA256_BLOCK_LENGTH];
4537c2fbfb3SApril Chin } Sha256_t;
4547c2fbfb3SApril Chin 
4557c2fbfb3SApril Chin #ifdef SHA2_UNROLL_TRANSFORM
4567c2fbfb3SApril Chin 
4577c2fbfb3SApril Chin /* Unrolled SHA-256 round macros: */
4587c2fbfb3SApril Chin 
4597c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
4607c2fbfb3SApril Chin 
4617c2fbfb3SApril Chin #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
4627c2fbfb3SApril Chin 	REVERSE32(*data++, W256[j]); \
4637c2fbfb3SApril Chin 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
4647c2fbfb3SApril Chin              K256[j] + W256[j]; \
4657c2fbfb3SApril Chin 	(d) += T1; \
4667c2fbfb3SApril Chin 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
4677c2fbfb3SApril Chin 	j++
4687c2fbfb3SApril Chin 
4697c2fbfb3SApril Chin 
4707c2fbfb3SApril Chin #else /* BYTE_ORDER == LITTLE_ENDIAN */
4717c2fbfb3SApril Chin 
4727c2fbfb3SApril Chin #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
4737c2fbfb3SApril Chin 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
4747c2fbfb3SApril Chin 	     K256[j] + (W256[j] = *data++); \
4757c2fbfb3SApril Chin 	(d) += T1; \
4767c2fbfb3SApril Chin 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
4777c2fbfb3SApril Chin 	j++
4787c2fbfb3SApril Chin 
4797c2fbfb3SApril Chin #endif /* BYTE_ORDER == LITTLE_ENDIAN */
4807c2fbfb3SApril Chin 
4817c2fbfb3SApril Chin #define ROUND256(a,b,c,d,e,f,g,h)	\
4827c2fbfb3SApril Chin 	s0 = W256[(j+1)&0x0f]; \
4837c2fbfb3SApril Chin 	s0 = sigma0_256(s0); \
4847c2fbfb3SApril Chin 	s1 = W256[(j+14)&0x0f]; \
4857c2fbfb3SApril Chin 	s1 = sigma1_256(s1); \
4867c2fbfb3SApril Chin 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
4877c2fbfb3SApril Chin 	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
4887c2fbfb3SApril Chin 	(d) += T1; \
4897c2fbfb3SApril Chin 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
4907c2fbfb3SApril Chin 	j++
4917c2fbfb3SApril Chin 
SHA256_Transform(SHA256_CTX * sha,const sha2_word32 * data)4927c2fbfb3SApril Chin static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
4937c2fbfb3SApril Chin 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
4947c2fbfb3SApril Chin 	sha2_word32	T1, *W256;
4957c2fbfb3SApril Chin 	int		j;
4967c2fbfb3SApril Chin 
4977c2fbfb3SApril Chin 	W256 = (sha2_word32*)sha->buffer;
4987c2fbfb3SApril Chin 
4997c2fbfb3SApril Chin 	/* Initialize registers with the prev. intermediate value */
5007c2fbfb3SApril Chin 	a = sha->state[0];
5017c2fbfb3SApril Chin 	b = sha->state[1];
5027c2fbfb3SApril Chin 	c = sha->state[2];
5037c2fbfb3SApril Chin 	d = sha->state[3];
5047c2fbfb3SApril Chin 	e = sha->state[4];
5057c2fbfb3SApril Chin 	f = sha->state[5];
5067c2fbfb3SApril Chin 	g = sha->state[6];
5077c2fbfb3SApril Chin 	h = sha->state[7];
5087c2fbfb3SApril Chin 
5097c2fbfb3SApril Chin 	j = 0;
5107c2fbfb3SApril Chin 	do {
5117c2fbfb3SApril Chin 		/* Rounds 0 to 15 (unrolled): */
5127c2fbfb3SApril Chin 		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
5137c2fbfb3SApril Chin 		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
5147c2fbfb3SApril Chin 		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
5157c2fbfb3SApril Chin 		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
5167c2fbfb3SApril Chin 		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
5177c2fbfb3SApril Chin 		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
5187c2fbfb3SApril Chin 		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
5197c2fbfb3SApril Chin 		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
5207c2fbfb3SApril Chin 	} while (j < 16);
5217c2fbfb3SApril Chin 
5227c2fbfb3SApril Chin 	/* Now for the remaining rounds to 64: */
5237c2fbfb3SApril Chin 	do {
5247c2fbfb3SApril Chin 		ROUND256(a,b,c,d,e,f,g,h);
5257c2fbfb3SApril Chin 		ROUND256(h,a,b,c,d,e,f,g);
5267c2fbfb3SApril Chin 		ROUND256(g,h,a,b,c,d,e,f);
5277c2fbfb3SApril Chin 		ROUND256(f,g,h,a,b,c,d,e);
5287c2fbfb3SApril Chin 		ROUND256(e,f,g,h,a,b,c,d);
5297c2fbfb3SApril Chin 		ROUND256(d,e,f,g,h,a,b,c);
5307c2fbfb3SApril Chin 		ROUND256(c,d,e,f,g,h,a,b);
5317c2fbfb3SApril Chin 		ROUND256(b,c,d,e,f,g,h,a);
5327c2fbfb3SApril Chin 	} while (j < 64);
5337c2fbfb3SApril Chin 
5347c2fbfb3SApril Chin 	/* Compute the current intermediate hash value */
5357c2fbfb3SApril Chin 	sha->state[0] += a;
5367c2fbfb3SApril Chin 	sha->state[1] += b;
5377c2fbfb3SApril Chin 	sha->state[2] += c;
5387c2fbfb3SApril Chin 	sha->state[3] += d;
5397c2fbfb3SApril Chin 	sha->state[4] += e;
5407c2fbfb3SApril Chin 	sha->state[5] += f;
5417c2fbfb3SApril Chin 	sha->state[6] += g;
5427c2fbfb3SApril Chin 	sha->state[7] += h;
5437c2fbfb3SApril Chin 
5447c2fbfb3SApril Chin 	/* Clean up */
5457c2fbfb3SApril Chin 	a = b = c = d = e = f = g = h = T1 = 0;
5467c2fbfb3SApril Chin }
5477c2fbfb3SApril Chin 
5487c2fbfb3SApril Chin #else /* SHA2_UNROLL_TRANSFORM */
5497c2fbfb3SApril Chin 
SHA256_Transform(SHA256_CTX * sha,const sha2_word32 * data)5507c2fbfb3SApril Chin static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
5517c2fbfb3SApril Chin 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
5527c2fbfb3SApril Chin 	sha2_word32	T1, T2, *W256;
5537c2fbfb3SApril Chin 	int		j;
5547c2fbfb3SApril Chin 
5557c2fbfb3SApril Chin 	W256 = (sha2_word32*)sha->buffer;
5567c2fbfb3SApril Chin 
5577c2fbfb3SApril Chin 	/* Initialize registers with the prev. intermediate value */
5587c2fbfb3SApril Chin 	a = sha->state[0];
5597c2fbfb3SApril Chin 	b = sha->state[1];
5607c2fbfb3SApril Chin 	c = sha->state[2];
5617c2fbfb3SApril Chin 	d = sha->state[3];
5627c2fbfb3SApril Chin 	e = sha->state[4];
5637c2fbfb3SApril Chin 	f = sha->state[5];
5647c2fbfb3SApril Chin 	g = sha->state[6];
5657c2fbfb3SApril Chin 	h = sha->state[7];
5667c2fbfb3SApril Chin 
5677c2fbfb3SApril Chin 	j = 0;
5687c2fbfb3SApril Chin 	do {
5697c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
5707c2fbfb3SApril Chin 		/* Copy data while converting to host byte order */
5717c2fbfb3SApril Chin 		REVERSE32(*data++,W256[j]);
5727c2fbfb3SApril Chin 		/* Apply the SHA-256 compression function to update a..h */
5737c2fbfb3SApril Chin 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
5747c2fbfb3SApril Chin #else /* BYTE_ORDER == LITTLE_ENDIAN */
5757c2fbfb3SApril Chin 		/* Apply the SHA-256 compression function to update a..h with copy */
5767c2fbfb3SApril Chin 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
5777c2fbfb3SApril Chin #endif /* BYTE_ORDER == LITTLE_ENDIAN */
5787c2fbfb3SApril Chin 		T2 = Sigma0_256(a) + Maj(a, b, c);
5797c2fbfb3SApril Chin 		h = g;
5807c2fbfb3SApril Chin 		g = f;
5817c2fbfb3SApril Chin 		f = e;
5827c2fbfb3SApril Chin 		e = d + T1;
5837c2fbfb3SApril Chin 		d = c;
5847c2fbfb3SApril Chin 		c = b;
5857c2fbfb3SApril Chin 		b = a;
5867c2fbfb3SApril Chin 		a = T1 + T2;
5877c2fbfb3SApril Chin 
5887c2fbfb3SApril Chin 		j++;
5897c2fbfb3SApril Chin 	} while (j < 16);
5907c2fbfb3SApril Chin 
5917c2fbfb3SApril Chin 	do {
5927c2fbfb3SApril Chin 		/* Part of the message block expansion: */
5937c2fbfb3SApril Chin 		s0 = W256[(j+1)&0x0f];
5947c2fbfb3SApril Chin 		s0 = sigma0_256(s0);
5957c2fbfb3SApril Chin 		s1 = W256[(j+14)&0x0f];
5967c2fbfb3SApril Chin 		s1 = sigma1_256(s1);
5977c2fbfb3SApril Chin 
5987c2fbfb3SApril Chin 		/* Apply the SHA-256 compression function to update a..h */
5997c2fbfb3SApril Chin 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
6007c2fbfb3SApril Chin 		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
6017c2fbfb3SApril Chin 		T2 = Sigma0_256(a) + Maj(a, b, c);
6027c2fbfb3SApril Chin 		h = g;
6037c2fbfb3SApril Chin 		g = f;
6047c2fbfb3SApril Chin 		f = e;
6057c2fbfb3SApril Chin 		e = d + T1;
6067c2fbfb3SApril Chin 		d = c;
6077c2fbfb3SApril Chin 		c = b;
6087c2fbfb3SApril Chin 		b = a;
6097c2fbfb3SApril Chin 		a = T1 + T2;
6107c2fbfb3SApril Chin 
6117c2fbfb3SApril Chin 		j++;
6127c2fbfb3SApril Chin 	} while (j < 64);
6137c2fbfb3SApril Chin 
6147c2fbfb3SApril Chin 	/* Compute the current intermediate hash value */
6157c2fbfb3SApril Chin 	sha->state[0] += a;
6167c2fbfb3SApril Chin 	sha->state[1] += b;
6177c2fbfb3SApril Chin 	sha->state[2] += c;
6187c2fbfb3SApril Chin 	sha->state[3] += d;
6197c2fbfb3SApril Chin 	sha->state[4] += e;
6207c2fbfb3SApril Chin 	sha->state[5] += f;
6217c2fbfb3SApril Chin 	sha->state[6] += g;
6227c2fbfb3SApril Chin 	sha->state[7] += h;
6237c2fbfb3SApril Chin 
6247c2fbfb3SApril Chin 	/* Clean up */
6257c2fbfb3SApril Chin 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
6267c2fbfb3SApril Chin }
6277c2fbfb3SApril Chin 
6287c2fbfb3SApril Chin #endif /* SHA2_UNROLL_TRANSFORM */
6297c2fbfb3SApril Chin 
6307c2fbfb3SApril Chin static int
sha256_block(register Sum_t * p,const void * s,size_t len)6317c2fbfb3SApril Chin sha256_block(register Sum_t* p, const void* s, size_t len)
6327c2fbfb3SApril Chin {
6337c2fbfb3SApril Chin 	Sha256_t*	sha = (Sha256_t*)p;
6347c2fbfb3SApril Chin 	sha2_byte*	data = (sha2_byte*)s;
6357c2fbfb3SApril Chin 	unsigned int	freespace, usedspace;
6367c2fbfb3SApril Chin 
6377c2fbfb3SApril Chin 	if (!len)
6387c2fbfb3SApril Chin 		return 0;
6397c2fbfb3SApril Chin 	usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
6407c2fbfb3SApril Chin 	if (usedspace > 0) {
6417c2fbfb3SApril Chin 		/* Calculate how much free space is available in the buffer */
6427c2fbfb3SApril Chin 		freespace = SHA256_BLOCK_LENGTH - usedspace;
6437c2fbfb3SApril Chin 
6447c2fbfb3SApril Chin 		if (len >= freespace) {
6457c2fbfb3SApril Chin 			/* Fill the buffer completely and process it */
6467c2fbfb3SApril Chin 			MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
6477c2fbfb3SApril Chin 			sha->bitcount += freespace << 3;
6487c2fbfb3SApril Chin 			len -= freespace;
6497c2fbfb3SApril Chin 			data += freespace;
6507c2fbfb3SApril Chin 			SHA256_Transform(sha, (sha2_word32*)sha->buffer);
6517c2fbfb3SApril Chin 		} else {
6527c2fbfb3SApril Chin 			/* The buffer is not yet full */
6537c2fbfb3SApril Chin 			MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
6547c2fbfb3SApril Chin 			sha->bitcount += len << 3;
6557c2fbfb3SApril Chin 			/* Clean up: */
6567c2fbfb3SApril Chin 			usedspace = freespace = 0;
6577c2fbfb3SApril Chin 			return 0;
6587c2fbfb3SApril Chin 		}
6597c2fbfb3SApril Chin 	}
6607c2fbfb3SApril Chin 	while (len >= SHA256_BLOCK_LENGTH) {
6617c2fbfb3SApril Chin 		/* Process as many complete blocks as we can */
6627c2fbfb3SApril Chin 		SHA256_Transform(sha, (sha2_word32*)data);
6637c2fbfb3SApril Chin 		sha->bitcount += SHA256_BLOCK_LENGTH << 3;
6647c2fbfb3SApril Chin 		len -= SHA256_BLOCK_LENGTH;
6657c2fbfb3SApril Chin 		data += SHA256_BLOCK_LENGTH;
6667c2fbfb3SApril Chin 	}
6677c2fbfb3SApril Chin 	if (len > 0) {
6687c2fbfb3SApril Chin 		/* There's left-overs, so save 'em */
6697c2fbfb3SApril Chin 		MEMCPY_BCOPY(sha->buffer, data, len);
6707c2fbfb3SApril Chin 		sha->bitcount += len << 3;
6717c2fbfb3SApril Chin 	}
6727c2fbfb3SApril Chin 	/* Clean up: */
6737c2fbfb3SApril Chin 	usedspace = freespace = 0;
6747c2fbfb3SApril Chin 
6757c2fbfb3SApril Chin 	return 0;
6767c2fbfb3SApril Chin }
6777c2fbfb3SApril Chin 
6787c2fbfb3SApril Chin static int
sha256_init(Sum_t * p)6797c2fbfb3SApril Chin sha256_init(Sum_t* p)
6807c2fbfb3SApril Chin {
6817c2fbfb3SApril Chin 	register Sha256_t*	sha = (Sha256_t*)p;
6827c2fbfb3SApril Chin 
6837c2fbfb3SApril Chin 	MEMCPY_BCOPY(sha->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
6847c2fbfb3SApril Chin 	MEMSET_BZERO(sha->buffer, SHA256_BLOCK_LENGTH);
6857c2fbfb3SApril Chin 	sha->bitcount = 0;
6867c2fbfb3SApril Chin 
6877c2fbfb3SApril Chin 	return 0;
6887c2fbfb3SApril Chin }
6897c2fbfb3SApril Chin 
6907c2fbfb3SApril Chin static Sum_t*
sha256_open(const Method_t * method,const char * name)6917c2fbfb3SApril Chin sha256_open(const Method_t* method, const char* name)
6927c2fbfb3SApril Chin {
6937c2fbfb3SApril Chin 	Sha256_t*	sha;
6947c2fbfb3SApril Chin 
6957c2fbfb3SApril Chin 	if (sha = newof(0, Sha256_t, 1, 0))
6967c2fbfb3SApril Chin 	{
6977c2fbfb3SApril Chin 		sha->method = (Method_t*)method;
6987c2fbfb3SApril Chin 		sha->name = name;
6997c2fbfb3SApril Chin 		sha256_init((Sum_t*)sha);
7007c2fbfb3SApril Chin 	}
7017c2fbfb3SApril Chin 	return (Sum_t*)sha;
7027c2fbfb3SApril Chin }
7037c2fbfb3SApril Chin 
7047c2fbfb3SApril Chin static int
sha256_done(Sum_t * p)7057c2fbfb3SApril Chin sha256_done(Sum_t* p)
7067c2fbfb3SApril Chin {
7077c2fbfb3SApril Chin 	Sha256_t*	sha = (Sha256_t*)p;
7087c2fbfb3SApril Chin 	unsigned int	usedspace;
7097c2fbfb3SApril Chin 	register int	i;
7107c2fbfb3SApril Chin 
7117c2fbfb3SApril Chin 	/* Sanity check: */
7127c2fbfb3SApril Chin 	assert(sha != (SHA256_CTX*)0);
7137c2fbfb3SApril Chin 
7147c2fbfb3SApril Chin 	usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
7157c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
7167c2fbfb3SApril Chin 	/* Convert FROM host byte order */
7177c2fbfb3SApril Chin 	REVERSE64(sha->bitcount,sha->bitcount);
7187c2fbfb3SApril Chin #endif
7197c2fbfb3SApril Chin 	if (usedspace > 0) {
7207c2fbfb3SApril Chin 		/* Begin padding with a 1 bit: */
7217c2fbfb3SApril Chin 		sha->buffer[usedspace++] = 0x80;
7227c2fbfb3SApril Chin 
7237c2fbfb3SApril Chin 		if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
7247c2fbfb3SApril Chin 			/* Set-up for the last transform: */
7257c2fbfb3SApril Chin 			MEMSET_BZERO(&sha->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
7267c2fbfb3SApril Chin 		} else {
7277c2fbfb3SApril Chin 			if (usedspace < SHA256_BLOCK_LENGTH) {
7287c2fbfb3SApril Chin 				MEMSET_BZERO(&sha->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
7297c2fbfb3SApril Chin 			}
7307c2fbfb3SApril Chin 			/* Do second-to-last transform: */
7317c2fbfb3SApril Chin 			SHA256_Transform(sha, (sha2_word32*)sha->buffer);
7327c2fbfb3SApril Chin 
7337c2fbfb3SApril Chin 			/* And set-up for the last transform: */
7347c2fbfb3SApril Chin 			MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
7357c2fbfb3SApril Chin 		}
7367c2fbfb3SApril Chin 	} else {
7377c2fbfb3SApril Chin 		/* Set-up for the last transform: */
7387c2fbfb3SApril Chin 		MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
7397c2fbfb3SApril Chin 
7407c2fbfb3SApril Chin 		/* Begin padding with a 1 bit: */
7417c2fbfb3SApril Chin 		*sha->buffer = 0x80;
7427c2fbfb3SApril Chin 	}
743*b30d1939SAndy Fiddaman 	/* Store the length of input data (in bits): */
744*b30d1939SAndy Fiddaman 	MEMCPY_BCOPY(&sha->buffer[SHA256_SHORT_BLOCK_LENGTH], &sha->bitcount, 8);
7457c2fbfb3SApril Chin 
7467c2fbfb3SApril Chin 	/* Final transform: */
7477c2fbfb3SApril Chin 	SHA256_Transform(sha, (sha2_word32*)sha->buffer);
7487c2fbfb3SApril Chin 
7497c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
7507c2fbfb3SApril Chin 	{
7517c2fbfb3SApril Chin 		/* Convert TO host byte order */
7527c2fbfb3SApril Chin 		int		j;
7537c2fbfb3SApril Chin 		sha2_word32*	d = (sha2_word32*)sha->digest;
7547c2fbfb3SApril Chin 		for (j = 0; j < 8; j++) {
7557c2fbfb3SApril Chin 			REVERSE32(sha->state[j],sha->state[j]);
7567c2fbfb3SApril Chin 			*d++ = sha->state[j];
7577c2fbfb3SApril Chin 		}
7587c2fbfb3SApril Chin 	}
7597c2fbfb3SApril Chin #else
7607c2fbfb3SApril Chin 	MEMCPY_BCOPY(sha->digest, sha->state, SHA256_DIGEST_LENGTH);
7617c2fbfb3SApril Chin #endif
7627c2fbfb3SApril Chin 
7637c2fbfb3SApril Chin 	/* accumulate the digests */
7647c2fbfb3SApril Chin 	for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
7657c2fbfb3SApril Chin 		sha->digest_sum[i] ^= sha->digest[i];
7667c2fbfb3SApril Chin 
7677c2fbfb3SApril Chin 	/* Clean up state data: */
7687c2fbfb3SApril Chin 	MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha256_t, state));
7697c2fbfb3SApril Chin 	usedspace = 0;
7707c2fbfb3SApril Chin 
7717c2fbfb3SApril Chin 	return 0;
7727c2fbfb3SApril Chin }
7737c2fbfb3SApril Chin 
7747c2fbfb3SApril Chin static int
sha256_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)7757c2fbfb3SApril Chin sha256_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
7767c2fbfb3SApril Chin {
7777c2fbfb3SApril Chin 	register Sha256_t*	sha = (Sha256_t*)p;
7787c2fbfb3SApril Chin 	register sha2_byte*	d;
7797c2fbfb3SApril Chin 	register sha2_byte*	e;
7807c2fbfb3SApril Chin 
7817c2fbfb3SApril Chin 	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
7827c2fbfb3SApril Chin 	e = d + SHA256_DIGEST_LENGTH;
7837c2fbfb3SApril Chin 	while (d < e)
7847c2fbfb3SApril Chin 		sfprintf(sp, "%02x", *d++);
7857c2fbfb3SApril Chin 	return 0;
7867c2fbfb3SApril Chin }
7877c2fbfb3SApril Chin 
7887c2fbfb3SApril Chin static int
sha256_data(Sum_t * p,Sumdata_t * data)7897c2fbfb3SApril Chin sha256_data(Sum_t* p, Sumdata_t* data)
7907c2fbfb3SApril Chin {
7917c2fbfb3SApril Chin 	register Sha256_t*	sha = (Sha256_t*)p;
7927c2fbfb3SApril Chin 
7937c2fbfb3SApril Chin 	data->size = SHA256_DIGEST_LENGTH;
7947c2fbfb3SApril Chin 	data->num = 0;
7957c2fbfb3SApril Chin 	data->buf = sha->digest;
7967c2fbfb3SApril Chin 	return 0;
7977c2fbfb3SApril Chin }
7987c2fbfb3SApril Chin 
7997c2fbfb3SApril Chin /*** SHA-512: *********************************************************/
8007c2fbfb3SApril Chin 
8017c2fbfb3SApril Chin #define sha512_description "FIPS SHA-512 secure hash algorithm."
8027c2fbfb3SApril Chin #define sha512_options	"\
8037c2fbfb3SApril Chin [+(version)?sha-512 (FIPS) 2000-01-01]\
8047c2fbfb3SApril Chin [+(author)?Aaron D. Gifford]\
8057c2fbfb3SApril Chin "
8067c2fbfb3SApril Chin #define sha512_match	"sha512|sha-512|SHA512|SHA-512"
8077c2fbfb3SApril Chin #define sha512_scale	0
8087c2fbfb3SApril Chin 
8097c2fbfb3SApril Chin #define sha512_padding	md5_pad
8107c2fbfb3SApril Chin 
8117c2fbfb3SApril Chin #define SHA512_CTX	Sha512_t
8127c2fbfb3SApril Chin 
8137c2fbfb3SApril Chin typedef struct Sha512_s
8147c2fbfb3SApril Chin {
8157c2fbfb3SApril Chin 	_SUM_PUBLIC_
8167c2fbfb3SApril Chin 	_SUM_PRIVATE_
8177c2fbfb3SApril Chin 	sha2_byte	digest[SHA512_DIGEST_LENGTH];
8187c2fbfb3SApril Chin 	sha2_byte	digest_sum[SHA512_DIGEST_LENGTH];
8197c2fbfb3SApril Chin 	sha2_word64	state[8];
8207c2fbfb3SApril Chin 	sha2_word64	bitcount[2];
8217c2fbfb3SApril Chin 	sha2_byte	buffer[SHA512_BLOCK_LENGTH];
8227c2fbfb3SApril Chin } Sha512_t;
8237c2fbfb3SApril Chin 
8247c2fbfb3SApril Chin #ifdef SHA2_UNROLL_TRANSFORM
8257c2fbfb3SApril Chin 
8267c2fbfb3SApril Chin /* Unrolled SHA-512 round macros: */
8277c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
8287c2fbfb3SApril Chin 
8297c2fbfb3SApril Chin #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
8307c2fbfb3SApril Chin 	REVERSE64(*data++, W512[j]); \
8317c2fbfb3SApril Chin 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
8327c2fbfb3SApril Chin              K512[j] + W512[j]; \
8337c2fbfb3SApril Chin 	(d) += T1, \
8347c2fbfb3SApril Chin 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
8357c2fbfb3SApril Chin 	j++
8367c2fbfb3SApril Chin 
8377c2fbfb3SApril Chin 
8387c2fbfb3SApril Chin #else /* BYTE_ORDER == LITTLE_ENDIAN */
8397c2fbfb3SApril Chin 
8407c2fbfb3SApril Chin #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
8417c2fbfb3SApril Chin 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
8427c2fbfb3SApril Chin              K512[j] + (W512[j] = *data++); \
8437c2fbfb3SApril Chin 	(d) += T1; \
8447c2fbfb3SApril Chin 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
8457c2fbfb3SApril Chin 	j++
8467c2fbfb3SApril Chin 
8477c2fbfb3SApril Chin #endif /* BYTE_ORDER == LITTLE_ENDIAN */
8487c2fbfb3SApril Chin 
8497c2fbfb3SApril Chin #define ROUND512(a,b,c,d,e,f,g,h)	\
8507c2fbfb3SApril Chin 	s0 = W512[(j+1)&0x0f]; \
8517c2fbfb3SApril Chin 	s0 = sigma0_512(s0); \
8527c2fbfb3SApril Chin 	s1 = W512[(j+14)&0x0f]; \
8537c2fbfb3SApril Chin 	s1 = sigma1_512(s1); \
8547c2fbfb3SApril Chin 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
8557c2fbfb3SApril Chin              (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
8567c2fbfb3SApril Chin 	(d) += T1; \
8577c2fbfb3SApril Chin 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
8587c2fbfb3SApril Chin 	j++
8597c2fbfb3SApril Chin 
SHA512_Transform(SHA512_CTX * sha,const sha2_word64 * data)8607c2fbfb3SApril Chin static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
8617c2fbfb3SApril Chin 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
8627c2fbfb3SApril Chin 	sha2_word64	T1, *W512 = (sha2_word64*)sha->buffer;
8637c2fbfb3SApril Chin 	int		j;
8647c2fbfb3SApril Chin 
8657c2fbfb3SApril Chin 	/* Initialize registers with the prev. intermediate value */
8667c2fbfb3SApril Chin 	a = sha->state[0];
8677c2fbfb3SApril Chin 	b = sha->state[1];
8687c2fbfb3SApril Chin 	c = sha->state[2];
8697c2fbfb3SApril Chin 	d = sha->state[3];
8707c2fbfb3SApril Chin 	e = sha->state[4];
8717c2fbfb3SApril Chin 	f = sha->state[5];
8727c2fbfb3SApril Chin 	g = sha->state[6];
8737c2fbfb3SApril Chin 	h = sha->state[7];
8747c2fbfb3SApril Chin 
8757c2fbfb3SApril Chin 	j = 0;
8767c2fbfb3SApril Chin 	do {
8777c2fbfb3SApril Chin 		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
8787c2fbfb3SApril Chin 		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
8797c2fbfb3SApril Chin 		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
8807c2fbfb3SApril Chin 		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
8817c2fbfb3SApril Chin 		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
8827c2fbfb3SApril Chin 		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
8837c2fbfb3SApril Chin 		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
8847c2fbfb3SApril Chin 		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
8857c2fbfb3SApril Chin 	} while (j < 16);
8867c2fbfb3SApril Chin 
8877c2fbfb3SApril Chin 	/* Now for the remaining rounds up to 79: */
8887c2fbfb3SApril Chin 	do {
8897c2fbfb3SApril Chin 		ROUND512(a,b,c,d,e,f,g,h);
8907c2fbfb3SApril Chin 		ROUND512(h,a,b,c,d,e,f,g);
8917c2fbfb3SApril Chin 		ROUND512(g,h,a,b,c,d,e,f);
8927c2fbfb3SApril Chin 		ROUND512(f,g,h,a,b,c,d,e);
8937c2fbfb3SApril Chin 		ROUND512(e,f,g,h,a,b,c,d);
8947c2fbfb3SApril Chin 		ROUND512(d,e,f,g,h,a,b,c);
8957c2fbfb3SApril Chin 		ROUND512(c,d,e,f,g,h,a,b);
8967c2fbfb3SApril Chin 		ROUND512(b,c,d,e,f,g,h,a);
8977c2fbfb3SApril Chin 	} while (j < 80);
8987c2fbfb3SApril Chin 
8997c2fbfb3SApril Chin 	/* Compute the current intermediate hash value */
9007c2fbfb3SApril Chin 	sha->state[0] += a;
9017c2fbfb3SApril Chin 	sha->state[1] += b;
9027c2fbfb3SApril Chin 	sha->state[2] += c;
9037c2fbfb3SApril Chin 	sha->state[3] += d;
9047c2fbfb3SApril Chin 	sha->state[4] += e;
9057c2fbfb3SApril Chin 	sha->state[5] += f;
9067c2fbfb3SApril Chin 	sha->state[6] += g;
9077c2fbfb3SApril Chin 	sha->state[7] += h;
9087c2fbfb3SApril Chin 
9097c2fbfb3SApril Chin 	/* Clean up */
9107c2fbfb3SApril Chin 	a = b = c = d = e = f = g = h = T1 = 0;
9117c2fbfb3SApril Chin }
9127c2fbfb3SApril Chin 
9137c2fbfb3SApril Chin #else /* SHA2_UNROLL_TRANSFORM */
9147c2fbfb3SApril Chin 
SHA512_Transform(SHA512_CTX * sha,const sha2_word64 * data)9157c2fbfb3SApril Chin static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
9167c2fbfb3SApril Chin 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
9177c2fbfb3SApril Chin 	sha2_word64	T1, T2, *W512 = (sha2_word64*)sha->buffer;
9187c2fbfb3SApril Chin 	int		j;
9197c2fbfb3SApril Chin 
9207c2fbfb3SApril Chin 	/* Initialize registers with the prev. intermediate value */
9217c2fbfb3SApril Chin 	a = sha->state[0];
9227c2fbfb3SApril Chin 	b = sha->state[1];
9237c2fbfb3SApril Chin 	c = sha->state[2];
9247c2fbfb3SApril Chin 	d = sha->state[3];
9257c2fbfb3SApril Chin 	e = sha->state[4];
9267c2fbfb3SApril Chin 	f = sha->state[5];
9277c2fbfb3SApril Chin 	g = sha->state[6];
9287c2fbfb3SApril Chin 	h = sha->state[7];
9297c2fbfb3SApril Chin 
9307c2fbfb3SApril Chin 	j = 0;
9317c2fbfb3SApril Chin 	do {
9327c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
9337c2fbfb3SApril Chin 		/* Convert TO host byte order */
9347c2fbfb3SApril Chin 		REVERSE64(*data++, W512[j]);
9357c2fbfb3SApril Chin 		/* Apply the SHA-512 compression function to update a..h */
9367c2fbfb3SApril Chin 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
9377c2fbfb3SApril Chin #else /* BYTE_ORDER == LITTLE_ENDIAN */
9387c2fbfb3SApril Chin 		/* Apply the SHA-512 compression function to update a..h with copy */
9397c2fbfb3SApril Chin 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
9407c2fbfb3SApril Chin #endif /* BYTE_ORDER == LITTLE_ENDIAN */
9417c2fbfb3SApril Chin 		T2 = Sigma0_512(a) + Maj(a, b, c);
9427c2fbfb3SApril Chin 		h = g;
9437c2fbfb3SApril Chin 		g = f;
9447c2fbfb3SApril Chin 		f = e;
9457c2fbfb3SApril Chin 		e = d + T1;
9467c2fbfb3SApril Chin 		d = c;
9477c2fbfb3SApril Chin 		c = b;
9487c2fbfb3SApril Chin 		b = a;
9497c2fbfb3SApril Chin 		a = T1 + T2;
9507c2fbfb3SApril Chin 
9517c2fbfb3SApril Chin 		j++;
9527c2fbfb3SApril Chin 	} while (j < 16);
9537c2fbfb3SApril Chin 
9547c2fbfb3SApril Chin 	do {
9557c2fbfb3SApril Chin 		/* Part of the message block expansion: */
9567c2fbfb3SApril Chin 		s0 = W512[(j+1)&0x0f];
9577c2fbfb3SApril Chin 		s0 = sigma0_512(s0);
9587c2fbfb3SApril Chin 		s1 = W512[(j+14)&0x0f];
9597c2fbfb3SApril Chin 		s1 =  sigma1_512(s1);
9607c2fbfb3SApril Chin 
9617c2fbfb3SApril Chin 		/* Apply the SHA-512 compression function to update a..h */
9627c2fbfb3SApril Chin 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
9637c2fbfb3SApril Chin 		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
9647c2fbfb3SApril Chin 		T2 = Sigma0_512(a) + Maj(a, b, c);
9657c2fbfb3SApril Chin 		h = g;
9667c2fbfb3SApril Chin 		g = f;
9677c2fbfb3SApril Chin 		f = e;
9687c2fbfb3SApril Chin 		e = d + T1;
9697c2fbfb3SApril Chin 		d = c;
9707c2fbfb3SApril Chin 		c = b;
9717c2fbfb3SApril Chin 		b = a;
9727c2fbfb3SApril Chin 		a = T1 + T2;
9737c2fbfb3SApril Chin 
9747c2fbfb3SApril Chin 		j++;
9757c2fbfb3SApril Chin 	} while (j < 80);
9767c2fbfb3SApril Chin 
9777c2fbfb3SApril Chin 	/* Compute the current intermediate hash value */
9787c2fbfb3SApril Chin 	sha->state[0] += a;
9797c2fbfb3SApril Chin 	sha->state[1] += b;
9807c2fbfb3SApril Chin 	sha->state[2] += c;
9817c2fbfb3SApril Chin 	sha->state[3] += d;
9827c2fbfb3SApril Chin 	sha->state[4] += e;
9837c2fbfb3SApril Chin 	sha->state[5] += f;
9847c2fbfb3SApril Chin 	sha->state[6] += g;
9857c2fbfb3SApril Chin 	sha->state[7] += h;
9867c2fbfb3SApril Chin 
9877c2fbfb3SApril Chin 	/* Clean up */
9887c2fbfb3SApril Chin 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
9897c2fbfb3SApril Chin }
9907c2fbfb3SApril Chin 
9917c2fbfb3SApril Chin #endif /* SHA2_UNROLL_TRANSFORM */
9927c2fbfb3SApril Chin 
9937c2fbfb3SApril Chin static int
sha512_block(register Sum_t * p,const void * s,size_t len)9947c2fbfb3SApril Chin sha512_block(register Sum_t* p, const void* s, size_t len)
9957c2fbfb3SApril Chin {
9967c2fbfb3SApril Chin 	Sha512_t*	sha = (Sha512_t*)p;
9977c2fbfb3SApril Chin 	sha2_byte*	data = (sha2_byte*)s;
9987c2fbfb3SApril Chin 	unsigned int	freespace, usedspace;
9997c2fbfb3SApril Chin 
10007c2fbfb3SApril Chin 	if (!len)
10017c2fbfb3SApril Chin 		return 0;
1002*b30d1939SAndy Fiddaman 	usedspace = (sha->bitcount[1] >> 3) % SHA512_BLOCK_LENGTH;
10037c2fbfb3SApril Chin 	if (usedspace > 0) {
10047c2fbfb3SApril Chin 		/* Calculate how much free space is available in the buffer */
10057c2fbfb3SApril Chin 		freespace = SHA512_BLOCK_LENGTH - usedspace;
10067c2fbfb3SApril Chin 
10077c2fbfb3SApril Chin 		if (len >= freespace) {
10087c2fbfb3SApril Chin 			/* Fill the buffer completely and process it */
10097c2fbfb3SApril Chin 			MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
10107c2fbfb3SApril Chin 			ADDINC128(sha->bitcount, freespace << 3);
10117c2fbfb3SApril Chin 			len -= freespace;
10127c2fbfb3SApril Chin 			data += freespace;
10137c2fbfb3SApril Chin 			SHA512_Transform(sha, (sha2_word64*)sha->buffer);
10147c2fbfb3SApril Chin 		} else {
10157c2fbfb3SApril Chin 			/* The buffer is not yet full */
10167c2fbfb3SApril Chin 			MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
10177c2fbfb3SApril Chin 			ADDINC128(sha->bitcount, len << 3);
10187c2fbfb3SApril Chin 			/* Clean up: */
10197c2fbfb3SApril Chin 			usedspace = freespace = 0;
10207c2fbfb3SApril Chin 			return 0;
10217c2fbfb3SApril Chin 		}
10227c2fbfb3SApril Chin 	}
10237c2fbfb3SApril Chin 	while (len >= SHA512_BLOCK_LENGTH) {
10247c2fbfb3SApril Chin 		/* Process as many complete blocks as we can */
10257c2fbfb3SApril Chin 		SHA512_Transform(sha, (sha2_word64*)data);
10267c2fbfb3SApril Chin 		ADDINC128(sha->bitcount, SHA512_BLOCK_LENGTH << 3);
10277c2fbfb3SApril Chin 		len -= SHA512_BLOCK_LENGTH;
10287c2fbfb3SApril Chin 		data += SHA512_BLOCK_LENGTH;
10297c2fbfb3SApril Chin 	}
10307c2fbfb3SApril Chin 	if (len > 0) {
10317c2fbfb3SApril Chin 		/* There's left-overs, so save 'em */
10327c2fbfb3SApril Chin 		MEMCPY_BCOPY(sha->buffer, data, len);
10337c2fbfb3SApril Chin 		ADDINC128(sha->bitcount, len << 3);
10347c2fbfb3SApril Chin 	}
10357c2fbfb3SApril Chin 	/* Clean up: */
10367c2fbfb3SApril Chin 	usedspace = freespace = 0;
10377c2fbfb3SApril Chin 
10387c2fbfb3SApril Chin 	return 0;
10397c2fbfb3SApril Chin }
10407c2fbfb3SApril Chin 
10417c2fbfb3SApril Chin static int
sha512_init(Sum_t * p)10427c2fbfb3SApril Chin sha512_init(Sum_t* p)
10437c2fbfb3SApril Chin {
10447c2fbfb3SApril Chin 	register Sha512_t*	sha = (Sha512_t*)p;
10457c2fbfb3SApril Chin 
10467c2fbfb3SApril Chin 	MEMCPY_BCOPY(sha->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
10477c2fbfb3SApril Chin 	MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH);
10487c2fbfb3SApril Chin 	sha->bitcount[0] = sha->bitcount[1] =  0;
10497c2fbfb3SApril Chin 
10507c2fbfb3SApril Chin 	return 0;
10517c2fbfb3SApril Chin }
10527c2fbfb3SApril Chin 
10537c2fbfb3SApril Chin static Sum_t*
sha512_open(const Method_t * method,const char * name)10547c2fbfb3SApril Chin sha512_open(const Method_t* method, const char* name)
10557c2fbfb3SApril Chin {
10567c2fbfb3SApril Chin 	Sha512_t*	sha;
10577c2fbfb3SApril Chin 
10587c2fbfb3SApril Chin 	if (sha = newof(0, Sha512_t, 1, 0))
10597c2fbfb3SApril Chin 	{
10607c2fbfb3SApril Chin 		sha->method = (Method_t*)method;
10617c2fbfb3SApril Chin 		sha->name = name;
10627c2fbfb3SApril Chin 		sha512_init((Sum_t*)sha);
10637c2fbfb3SApril Chin 	}
10647c2fbfb3SApril Chin 	return (Sum_t*)sha;
10657c2fbfb3SApril Chin }
10667c2fbfb3SApril Chin 
10677c2fbfb3SApril Chin static int
sha512_done(Sum_t * p)10687c2fbfb3SApril Chin sha512_done(Sum_t* p)
10697c2fbfb3SApril Chin {
10707c2fbfb3SApril Chin 	Sha512_t*	sha = (Sha512_t*)p;
10717c2fbfb3SApril Chin 	unsigned int	usedspace;
10727c2fbfb3SApril Chin 	register int	i;
10737c2fbfb3SApril Chin 
1074*b30d1939SAndy Fiddaman 	usedspace = (sha->bitcount[1] >> 3) % SHA512_BLOCK_LENGTH;
10757c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
10767c2fbfb3SApril Chin 	/* Convert FROM host byte order */
10777c2fbfb3SApril Chin 	REVERSE64(sha->bitcount[0],sha->bitcount[0]);
10787c2fbfb3SApril Chin 	REVERSE64(sha->bitcount[1],sha->bitcount[1]);
10797c2fbfb3SApril Chin #endif
10807c2fbfb3SApril Chin 	if (usedspace > 0) {
10817c2fbfb3SApril Chin 		/* Begin padding with a 1 bit: */
10827c2fbfb3SApril Chin 		sha->buffer[usedspace++] = 0x80;
10837c2fbfb3SApril Chin 
10847c2fbfb3SApril Chin 		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
10857c2fbfb3SApril Chin 			/* Set-up for the last transform: */
10867c2fbfb3SApril Chin 			MEMSET_BZERO(&sha->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
10877c2fbfb3SApril Chin 		} else {
10887c2fbfb3SApril Chin 			if (usedspace < SHA512_BLOCK_LENGTH) {
10897c2fbfb3SApril Chin 				MEMSET_BZERO(&sha->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
10907c2fbfb3SApril Chin 			}
10917c2fbfb3SApril Chin 			/* Do second-to-last transform: */
10927c2fbfb3SApril Chin 			SHA512_Transform(sha, (sha2_word64*)sha->buffer);
10937c2fbfb3SApril Chin 
10947c2fbfb3SApril Chin 			/* And set-up for the last transform: */
10957c2fbfb3SApril Chin 			MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH - 2);
10967c2fbfb3SApril Chin 		}
10977c2fbfb3SApril Chin 	} else {
10987c2fbfb3SApril Chin 		/* Prepare for final transform: */
10997c2fbfb3SApril Chin 		MEMSET_BZERO(sha->buffer, SHA512_SHORT_BLOCK_LENGTH);
11007c2fbfb3SApril Chin 
11017c2fbfb3SApril Chin 		/* Begin padding with a 1 bit: */
11027c2fbfb3SApril Chin 		*sha->buffer = 0x80;
11037c2fbfb3SApril Chin 	}
11047c2fbfb3SApril Chin 	/* Store the length of input data (in bits): */
1105*b30d1939SAndy Fiddaman 	MEMCPY_BCOPY(&sha->buffer[SHA512_SHORT_BLOCK_LENGTH], &sha->bitcount[0], 16);
11067c2fbfb3SApril Chin 
11077c2fbfb3SApril Chin 	/* Final transform: */
11087c2fbfb3SApril Chin 	SHA512_Transform(sha, (sha2_word64*)sha->buffer);
11097c2fbfb3SApril Chin 
11107c2fbfb3SApril Chin #if BYTE_ORDER == LITTLE_ENDIAN
11117c2fbfb3SApril Chin 	{
11127c2fbfb3SApril Chin 		/* Convert TO host byte order */
11137c2fbfb3SApril Chin 		sha2_word64*	d = (sha2_word64*)sha->digest;
11147c2fbfb3SApril Chin 		int		j;
11157c2fbfb3SApril Chin 		for (j = 0; j < 8; j++) {
11167c2fbfb3SApril Chin 			REVERSE64(sha->state[j],sha->state[j]);
11177c2fbfb3SApril Chin 			*d++ = sha->state[j];
11187c2fbfb3SApril Chin 		}
11197c2fbfb3SApril Chin 	}
11207c2fbfb3SApril Chin #else
11217c2fbfb3SApril Chin 	MEMCPY_BCOPY(sha->digest, sha->state, SHA512_DIGEST_LENGTH);
11227c2fbfb3SApril Chin #endif
11237c2fbfb3SApril Chin 
11247c2fbfb3SApril Chin 	/* accumulate the digests */
11257c2fbfb3SApril Chin 	for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
11267c2fbfb3SApril Chin 		sha->digest_sum[i] ^= sha->digest[i];
11277c2fbfb3SApril Chin 
11287c2fbfb3SApril Chin 	/* Clean up state data: */
11297c2fbfb3SApril Chin 	MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha512_t, state));
11307c2fbfb3SApril Chin 	usedspace = 0;
11317c2fbfb3SApril Chin 
11327c2fbfb3SApril Chin 	return 0;
11337c2fbfb3SApril Chin }
11347c2fbfb3SApril Chin 
11357c2fbfb3SApril Chin static int
sha512_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)11367c2fbfb3SApril Chin sha512_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
11377c2fbfb3SApril Chin {
11387c2fbfb3SApril Chin 	register Sha512_t*	sha = (Sha512_t*)p;
11397c2fbfb3SApril Chin 	register sha2_byte*	d;
11407c2fbfb3SApril Chin 	register sha2_byte*	e;
11417c2fbfb3SApril Chin 
11427c2fbfb3SApril Chin 	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
11437c2fbfb3SApril Chin 	e = d + SHA512_DIGEST_LENGTH;
11447c2fbfb3SApril Chin 	while (d < e)
11457c2fbfb3SApril Chin 		sfprintf(sp, "%02x", *d++);
11467c2fbfb3SApril Chin 	return 0;
11477c2fbfb3SApril Chin }
11487c2fbfb3SApril Chin 
11497c2fbfb3SApril Chin static int
sha512_data(Sum_t * p,Sumdata_t * data)11507c2fbfb3SApril Chin sha512_data(Sum_t* p, Sumdata_t* data)
11517c2fbfb3SApril Chin {
11527c2fbfb3SApril Chin 	register Sha512_t*	sha = (Sha512_t*)p;
11537c2fbfb3SApril Chin 
11547c2fbfb3SApril Chin 	data->size = SHA512_DIGEST_LENGTH;
11557c2fbfb3SApril Chin 	data->num = 0;
11567c2fbfb3SApril Chin 	data->buf = sha->digest;
11577c2fbfb3SApril Chin 	return 0;
11587c2fbfb3SApril Chin }
11597c2fbfb3SApril Chin 
11607c2fbfb3SApril Chin /*** SHA-384: *********************************************************/
11617c2fbfb3SApril Chin 
11627c2fbfb3SApril Chin #define sha384_description "FIPS SHA-384 secure hash algorithm."
11637c2fbfb3SApril Chin #define sha384_options	"\
11647c2fbfb3SApril Chin [+(version)?sha-384 (FIPS) 2000-01-01]\
11657c2fbfb3SApril Chin [+(author)?Aaron D. Gifford]\
11667c2fbfb3SApril Chin "
11677c2fbfb3SApril Chin #define sha384_match	"sha384|sha-384|SHA384|SHA-384"
11687c2fbfb3SApril Chin #define sha384_scale	0
11697c2fbfb3SApril Chin #define sha384_block	sha512_block
11707c2fbfb3SApril Chin #define sha384_done	sha512_done
11717c2fbfb3SApril Chin 
11727c2fbfb3SApril Chin #define sha384_padding	md5_pad
11737c2fbfb3SApril Chin 
11747c2fbfb3SApril Chin #define Sha384_t		Sha512_t
11757c2fbfb3SApril Chin #define SHA384_CTX		Sha384_t
11767c2fbfb3SApril Chin #define SHA384_DIGEST_LENGTH	48
11777c2fbfb3SApril Chin 
11787c2fbfb3SApril Chin static int
sha384_init(Sum_t * p)11797c2fbfb3SApril Chin sha384_init(Sum_t* p)
11807c2fbfb3SApril Chin {
11817c2fbfb3SApril Chin 	register Sha384_t*	sha = (Sha384_t*)p;
11827c2fbfb3SApril Chin 
11837c2fbfb3SApril Chin 	MEMCPY_BCOPY(sha->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
11847c2fbfb3SApril Chin 	MEMSET_BZERO(sha->buffer, SHA384_BLOCK_LENGTH);
11857c2fbfb3SApril Chin 	sha->bitcount[0] = sha->bitcount[1] = 0;
11867c2fbfb3SApril Chin 
11877c2fbfb3SApril Chin 	return 0;
11887c2fbfb3SApril Chin }
11897c2fbfb3SApril Chin 
11907c2fbfb3SApril Chin static Sum_t*
sha384_open(const Method_t * method,const char * name)11917c2fbfb3SApril Chin sha384_open(const Method_t* method, const char* name)
11927c2fbfb3SApril Chin {
11937c2fbfb3SApril Chin 	Sha384_t*	sha;
11947c2fbfb3SApril Chin 
11957c2fbfb3SApril Chin 	if (sha = newof(0, Sha384_t, 1, 0))
11967c2fbfb3SApril Chin 	{
11977c2fbfb3SApril Chin 		sha->method = (Method_t*)method;
11987c2fbfb3SApril Chin 		sha->name = name;
11997c2fbfb3SApril Chin 		sha384_init((Sum_t*)sha);
12007c2fbfb3SApril Chin 	}
12017c2fbfb3SApril Chin 	return (Sum_t*)sha;
12027c2fbfb3SApril Chin }
12037c2fbfb3SApril Chin 
12047c2fbfb3SApril Chin static int
sha384_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)12057c2fbfb3SApril Chin sha384_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
12067c2fbfb3SApril Chin {
12077c2fbfb3SApril Chin 	register Sha384_t*	sha = (Sha384_t*)p;
12087c2fbfb3SApril Chin 	register sha2_byte*	d;
12097c2fbfb3SApril Chin 	register sha2_byte*	e;
12107c2fbfb3SApril Chin 
12117c2fbfb3SApril Chin 	d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
12127c2fbfb3SApril Chin 	e = d + SHA384_DIGEST_LENGTH;
12137c2fbfb3SApril Chin 	while (d < e)
12147c2fbfb3SApril Chin 		sfprintf(sp, "%02x", *d++);
12157c2fbfb3SApril Chin 	return 0;
12167c2fbfb3SApril Chin }
12177c2fbfb3SApril Chin 
12187c2fbfb3SApril Chin static int
sha384_data(Sum_t * p,Sumdata_t * data)12197c2fbfb3SApril Chin sha384_data(Sum_t* p, Sumdata_t* data)
12207c2fbfb3SApril Chin {
12217c2fbfb3SApril Chin 	register Sha384_t*	sha = (Sha384_t*)p;
12227c2fbfb3SApril Chin 
12237c2fbfb3SApril Chin 	data->size = SHA384_DIGEST_LENGTH;
12247c2fbfb3SApril Chin 	data->num = 0;
12257c2fbfb3SApril Chin 	data->buf = sha->digest;
12267c2fbfb3SApril Chin 	return 0;
12277c2fbfb3SApril Chin }
12287c2fbfb3SApril Chin 
12297c2fbfb3SApril Chin #endif /* _typ_int64_t */
1230