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