7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/***********************************************************************
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1996-2010 AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* and is licensed under the *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* A copy of the License is available at *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* http://www.opensource.org/licenses/cpl1.0.txt *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Information and Software Systems Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* AT&T Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Florham Park NJ *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Glenn Fowler <gsf@research.att.com> *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin***********************************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#pragma prototyped
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _typ_int64_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Aaron D. Gifford's SHA {256,384,512} code transcribed into a -lsum method
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Copyright (c) 2000-2001, Aaron D. Gifford
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * All rights reserved.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Redistribution and use in source and binary forms, with or without
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * modification, are permitted provided that the following conditions
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * are met:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * 1. Redistributions of source code must retain the above copyright
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * notice, this list of conditions and the following disclaimer.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * 2. Redistributions in binary form must reproduce the above copyright
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * notice, this list of conditions and the following disclaimer in the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * documentation and/or other materials provided with the distribution.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * 3. Neither the name of the copyright holder nor the names of contributors
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * may be used to endorse or promote products derived from this software
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * without specific prior written permission.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * SUCH DAMAGE.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * ASSERT NOTE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Some sanity checking code is included using assert(). On my FreeBSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * system, this additional code can be removed by compiling with NDEBUG
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * defined. Check your own systems manpage on assert() to see how to
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * compile WITHOUT the sanity checking code on your system.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * UNROLLED TRANSFORM LOOP NOTE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * loop version for the hash transform rounds (defined using macros
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * later in this file). Either define on the command line, for example:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * or define below:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * #define SHA2_UNROLL_TRANSFORM
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-256/384/512 Machine Architecture Definitions *****************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _PACKAGE_ast
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifndef __USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define __undef__USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define __USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <endian.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef __undef__USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef __undef__USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef __USE_BSD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint8_t sha2_byte; /* Exactly 1 byte */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint32_t sha2_word32; /* Exactly 4 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint64_t sha2_word64; /* Exactly 8 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define assert(x)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef R
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef S32
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef S64
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* _PACKAGE_ast */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * BYTE_ORDER NOTE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Please make sure that your system defines BYTE_ORDER. If your
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * architecture is little-endian, make sure it also defines
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * equivilent.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * If your system does not define the above, then you can do so by
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * hand like this:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * #define LITTLE_ENDIAN 1234
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * #define BIG_ENDIAN 4321
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * And for little-endian machines, add:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * #define BYTE_ORDER LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Or for big-endian machines:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * #define BYTE_ORDER BIG_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * The FreeBSD machine this was written on defines BYTE_ORDER
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * appropriately by including <sys/types.h> (which in turn includes
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * <machine/endian.h> where the appropriate definitions are actually
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * made).
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Define the following sha2_* types to types of the correct length on
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * the native archtecture. Most BSD systems and Linux define u_intXX_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * types. Machines with very recent ANSI C headers, can use the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * during compile or in the sha.h header file.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * will need to define these three typedefs below (and the appropriate
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * ones in sha.h too) by hand according to their system architecture.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef SHA2_USE_INTTYPES_H
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint8_t sha2_byte; /* Exactly 1 byte */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint32_t sha2_word32; /* Exactly 4 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint64_t sha2_word64; /* Exactly 8 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* SHA2_USE_INTTYPES_H */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef u_int8_t sha2_byte; /* Exactly 1 byte */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef u_int32_t sha2_word32; /* Exactly 4 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef u_int64_t sha2_word64; /* Exactly 8 bytes */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHA2_USE_INTTYPES_H */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* _PACKAGE_ast */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-256/384/512 Various Length Definitions ***********************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA256_BLOCK_LENGTH 64
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA256_DIGEST_LENGTH 32
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA384_BLOCK_LENGTH 128
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA384_DIGEST_LENGTH 48
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA512_BLOCK_LENGTH 128
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA512_DIGEST_LENGTH 64
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** ENDIAN REVERSAL MACROS *******************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define REVERSE32(w,x) { \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 tmp = (w); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tmp = (tmp >> 16) | (tmp << 16); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _ast_LL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define REVERSE64(w,x) { \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 tmp = (w); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tmp = (tmp >> 32) | (tmp << 32); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((tmp & 0x0000ffff0000ffffULL) << 16); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define REVERSE64(w,x) { \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 tmp = (w); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tmp = (tmp >> 32) | (tmp << 32); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tmp = ((tmp & ((sha2_word64)0xff00ff00ff00ff00)) >> 8) | \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((tmp & ((sha2_word64)0x00ff00ff00ff00ff)) << 8); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (x) = ((tmp & ((sha2_word64)0xffff0000ffff0000)) >> 16) | \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((tmp & ((sha2_word64)0x0000ffff0000ffff)) << 16); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Macro for incrementally adding the unsigned 64-bit integer n to the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * unsigned 128-bit integer (represented using a two-element array of
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * 64-bit words):
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ADDINC128(w,n) { \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (w)[0] += (sha2_word64)(n); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((w)[0] < (n)) { \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (w)[1]++; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Macros for copying blocks of memory and for zeroing out ranges
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * of memory. Using these macros makes it easy to switch from
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * using memset()/memcpy() and using bzero()/bcopy().
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Please define either SHA2_USE_MEMSET_MEMCPY or define
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * SHA2_USE_BZERO_BCOPY depending on which function set you
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * choose to use:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Default to memset()/memcpy() if no option is specified */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA2_USE_MEMSET_MEMCPY 1
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Abort with an error if BOTH options are defined */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef SHA2_USE_MEMSET_MEMCPY
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define MEMSET_BZERO(p,l) memset((p), 0, (l))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef SHA2_USE_BZERO_BCOPY
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define MEMSET_BZERO(p,l) bzero((p), (l))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** THE SIX LOGICAL FUNCTIONS ****************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * S is a ROTATION) because the SHA-256/384/512 description document
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * same "backwards" definition.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define R(b,x) ((x) >> (b))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* 32-bit Rotate-right (used in SHA-256): */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Four of six logical functions used in SHA-256: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Four of six logical functions used in SHA-384 and SHA-512: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Hash constant words K for SHA-256: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const sha2_word32 K256[64] = {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Initial hash value H for SHA-256: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const sha2_word32 sha256_initial_hash_value[8] = {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x6a09e667UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xbb67ae85UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x3c6ef372UL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xa54ff53aUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x510e527fUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x9b05688cUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x1f83d9abUL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x5be0cd19UL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Hash constant words K for SHA-384 and SHA-512: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const sha2_word64 K512[80] = {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _ast_LL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x428a2f98d728ae22), ((sha2_word64)0x7137449123ef65cd),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xb5c0fbcfec4d3b2f), ((sha2_word64)0xe9b5dba58189dbbc),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x3956c25bf348b538), ((sha2_word64)0x59f111f1b605d019),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x923f82a4af194f9b), ((sha2_word64)0xab1c5ed5da6d8118),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xd807aa98a3030242), ((sha2_word64)0x12835b0145706fbe),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x243185be4ee4b28c), ((sha2_word64)0x550c7dc3d5ffb4e2),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x72be5d74f27b896f), ((sha2_word64)0x80deb1fe3b1696b1),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x9bdc06a725c71235), ((sha2_word64)0xc19bf174cf692694),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xe49b69c19ef14ad2), ((sha2_word64)0xefbe4786384f25e3),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x0fc19dc68b8cd5b5), ((sha2_word64)0x240ca1cc77ac9c65),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x2de92c6f592b0275), ((sha2_word64)0x4a7484aa6ea6e483),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x5cb0a9dcbd41fbd4), ((sha2_word64)0x76f988da831153b5),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x983e5152ee66dfab), ((sha2_word64)0xa831c66d2db43210),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xb00327c898fb213f), ((sha2_word64)0xbf597fc7beef0ee4),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xc6e00bf33da88fc2), ((sha2_word64)0xd5a79147930aa725),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x06ca6351e003826f), ((sha2_word64)0x142929670a0e6e70),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x27b70a8546d22ffc), ((sha2_word64)0x2e1b21385c26c926),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x4d2c6dfc5ac42aed), ((sha2_word64)0x53380d139d95b3df),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x650a73548baf63de), ((sha2_word64)0x766a0abb3c77b2a8),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x81c2c92e47edaee6), ((sha2_word64)0x92722c851482353b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xa2bfe8a14cf10364), ((sha2_word64)0xa81a664bbc423001),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xc24b8b70d0f89791), ((sha2_word64)0xc76c51a30654be30),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xd192e819d6ef5218), ((sha2_word64)0xd69906245565a910),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xf40e35855771202a), ((sha2_word64)0x106aa07032bbd1b8),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x19a4c116b8d2d0c8), ((sha2_word64)0x1e376c085141ab53),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x2748774cdf8eeb99), ((sha2_word64)0x34b0bcb5e19b48a8),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x391c0cb3c5c95a63), ((sha2_word64)0x4ed8aa4ae3418acb),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x5b9cca4f7763e373), ((sha2_word64)0x682e6ff3d6b2b8a3),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x748f82ee5defb2fc), ((sha2_word64)0x78a5636f43172f60),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x84c87814a1f0ab72), ((sha2_word64)0x8cc702081a6439ec),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x90befffa23631e28), ((sha2_word64)0xa4506cebde82bde9),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xbef9a3f7b2c67915), ((sha2_word64)0xc67178f2e372532b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xca273eceea26619c), ((sha2_word64)0xd186b8c721c0c207),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xeada7dd6cde0eb1e), ((sha2_word64)0xf57d4f7fee6ed178),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x06f067aa72176fba), ((sha2_word64)0x0a637dc5a2c898a6),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x113f9804bef90dae), ((sha2_word64)0x1b710b35131c471b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x28db77f523047d84), ((sha2_word64)0x32caab7b40c72493),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x3c9ebe0a15c9bebc), ((sha2_word64)0x431d67c49c100d4c),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x4cc5d4becb3e42b6), ((sha2_word64)0x597f299cfc657e2a),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x5fcb6fab3ad6faec), ((sha2_word64)0x6c44198c4a475817)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Initial hash value H for SHA-384 */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const sha2_word64 sha384_initial_hash_value[8] = {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _ast_LL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xcbbb9d5dc1059ed8ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x629a292a367cd507ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x9159015a3070dd17ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x152fecd8f70e5939ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x67332667ffc00b31ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x8eb44a8768581511ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xdb0c2e0d64f98fa7ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x47b5481dbefa4fa4ULL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xcbbb9d5dc1059ed8),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x629a292a367cd507),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x9159015a3070dd17),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x152fecd8f70e5939),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x67332667ffc00b31),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x8eb44a8768581511),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xdb0c2e0d64f98fa7),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x47b5481dbefa4fa4)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Initial hash value H for SHA-512 */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const sha2_word64 sha512_initial_hash_value[8] = {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _ast_LL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x6a09e667f3bcc908ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xbb67ae8584caa73bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x3c6ef372fe94f82bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0xa54ff53a5f1d36f1ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x510e527fade682d1ULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x9b05688c2b3e6c1fULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x1f83d9abfb41bd6bULL,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0x5be0cd19137e2179ULL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x6a09e667f3bcc908),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xbb67ae8584caa73b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x3c6ef372fe94f82b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0xa54ff53a5f1d36f1),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x510e527fade682d1),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x9b05688c2b3e6c1f),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x1f83d9abfb41bd6b),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((sha2_word64)0x5be0cd19137e2179)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-256: *********************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha256_description "FIPS SHA-256 secure hash algorithm."
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha256_options "\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(version)?sha-256 (FIPS) 2000-01-01]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(author)?Aaron D. Gifford]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha256_match "sha256|sha-256|SHA256|SHA-256"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha256_scale 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha256_padding md5_pad
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA256_CTX Sha256_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef struct Sha256_s
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PUBLIC_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PRIVATE_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte digest[SHA256_DIGEST_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte digest_sum[SHA256_DIGEST_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 state[8];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 bitcount;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte buffer[SHA256_BLOCK_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin} Sha256_t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef SHA2_UNROLL_TRANSFORM
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Unrolled SHA-256 round macros: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE32(*data++, W256[j]); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin K256[j] + W256[j]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin K256[j] + (W256[j] = *data++); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND256(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = W256[(j+1)&0x0f]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = sigma0_256(s0); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = W256[(j+14)&0x0f]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = sigma1_256(s1); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 T1, *W256;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin W256 = (sha2_word32*)sha->buffer;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Initialize registers with the prev. intermediate value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = sha->state[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = sha->state[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = sha->state[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = sha->state[3];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = sha->state[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = sha->state[5];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = sha->state[6];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = sha->state[7];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Rounds 0 to 15 (unrolled): */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Now for the remaining rounds to 64: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(a,b,c,d,e,f,g,h);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(h,a,b,c,d,e,f,g);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(g,h,a,b,c,d,e,f);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(f,g,h,a,b,c,d,e);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(e,f,g,h,a,b,c,d);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(d,e,f,g,h,a,b,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(c,d,e,f,g,h,a,b);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND256(b,c,d,e,f,g,h,a);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 64);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Compute the current intermediate hash value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[0] += a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[1] += b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[2] += c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[3] += d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[4] += e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[5] += f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[6] += g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[7] += h;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = b = c = d = e = f = g = h = T1 = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* SHA2_UNROLL_TRANSFORM */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32 T1, T2, *W256;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin W256 = (sha2_word32*)sha->buffer;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Initialize registers with the prev. intermediate value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = sha->state[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = sha->state[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = sha->state[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = sha->state[3];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = sha->state[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = sha->state[5];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = sha->state[6];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = sha->state[7];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Copy data while converting to host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE32(*data++,W256[j]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-256 compression function to update a..h */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-256 compression function to update a..h with copy */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T2 = Sigma0_256(a) + Maj(a, b, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + T1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = T1 + T2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Part of the message block expansion: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = W256[(j+1)&0x0f];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = sigma0_256(s0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = W256[(j+14)&0x0f];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = sigma1_256(s1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-256 compression function to update a..h */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T2 = Sigma0_256(a) + Maj(a, b, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + T1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = T1 + T2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 64);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Compute the current intermediate hash value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[0] += a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[1] += b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[2] += c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[3] += d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[4] += e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[5] += f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[6] += g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[7] += h;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = b = c = d = e = f = g = h = T1 = T2 = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHA2_UNROLL_TRANSFORM */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_block(register Sum_t* p, const void* s, size_t len)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha256_t* sha = (Sha256_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte* data = (sha2_byte*)s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned int freespace, usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!len)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Calculate how much free space is available in the buffer */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin freespace = SHA256_BLOCK_LENGTH - usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (len >= freespace) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Fill the buffer completely and process it */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount += freespace << 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin len -= freespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data += freespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA256_Transform(sha, (sha2_word32*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* The buffer is not yet full */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount += len << 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = freespace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (len >= SHA256_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Process as many complete blocks as we can */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA256_Transform(sha, (sha2_word32*)data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount += SHA256_BLOCK_LENGTH << 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin len -= SHA256_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data += SHA256_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (len > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* There's left-overs, so save 'em */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->buffer, data, len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount += len << 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = freespace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_init(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha256_t* sha = (Sha256_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA256_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sum_t*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_open(const Method_t* method, const char* name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha256_t* sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (sha = newof(0, Sha256_t, 1, 0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->method = (Method_t*)method;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->name = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha256_init((Sum_t*)sha);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return (Sum_t*)sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_done(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha256_t* sha = (Sha256_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned int usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Sanity check: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin assert(sha != (SHA256_CTX*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Convert FROM host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(sha->bitcount,sha->bitcount);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Begin padding with a 1 bit: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->buffer[usedspace++] = 0x80;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Set-up for the last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace < SHA256_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Do second-to-last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA256_Transform(sha, (sha2_word32*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* And set-up for the last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Set-up for the last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Begin padding with a 1 bit: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *sha->buffer = 0x80;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Set the bit count: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *(sha2_word64*)&sha->buffer[SHA256_SHORT_BLOCK_LENGTH] = sha->bitcount;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Final transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA256_Transform(sha, (sha2_word32*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Convert TO host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word32* d = (sha2_word32*)sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (j = 0; j < 8; j++) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE32(sha->state[j],sha->state[j]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *d++ = sha->state[j];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->digest, sha->state, SHA256_DIGEST_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* accumulate the digests */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->digest_sum[i] ^= sha->digest[i];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up state data: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha256_t, state));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha256_t* sha = (Sha256_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + SHA256_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (d < e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sp, "%02x", *d++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha256_data(Sum_t* p, Sumdata_t* data)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha256_t* sha = (Sha256_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->size = SHA256_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->num = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->buf = sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-512: *********************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha512_description "FIPS SHA-512 secure hash algorithm."
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha512_options "\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(version)?sha-512 (FIPS) 2000-01-01]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(author)?Aaron D. Gifford]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha512_match "sha512|sha-512|SHA512|SHA-512"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha512_scale 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha512_padding md5_pad
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA512_CTX Sha512_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef struct Sha512_s
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PUBLIC_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PRIVATE_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte digest[SHA512_DIGEST_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte digest_sum[SHA512_DIGEST_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 state[8];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 bitcount[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte buffer[SHA512_BLOCK_LENGTH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin} Sha512_t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef SHA2_UNROLL_TRANSFORM
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Unrolled SHA-512 round macros: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(*data++, W512[j]); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin K512[j] + W512[j]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1, \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin K512[j] + (W512[j] = *data++); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define ROUND512(a,b,c,d,e,f,g,h) \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = W512[(j+1)&0x0f]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = sigma0_512(s0); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = W512[(j+14)&0x0f]; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = sigma1_512(s1); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (d) += T1; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 T1, *W512 = (sha2_word64*)sha->buffer;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Initialize registers with the prev. intermediate value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = sha->state[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = sha->state[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = sha->state[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = sha->state[3];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = sha->state[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = sha->state[5];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = sha->state[6];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = sha->state[7];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Now for the remaining rounds up to 79: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(a,b,c,d,e,f,g,h);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(h,a,b,c,d,e,f,g);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(g,h,a,b,c,d,e,f);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(f,g,h,a,b,c,d,e);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(e,f,g,h,a,b,c,d);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(d,e,f,g,h,a,b,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(c,d,e,f,g,h,a,b);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ROUND512(b,c,d,e,f,g,h,a);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 80);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Compute the current intermediate hash value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[0] += a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[1] += b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[2] += c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[3] += d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[4] += e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[5] += f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[6] += g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[7] += h;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = b = c = d = e = f = g = h = T1 = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* SHA2_UNROLL_TRANSFORM */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64 T1, T2, *W512 = (sha2_word64*)sha->buffer;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Initialize registers with the prev. intermediate value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = sha->state[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = sha->state[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = sha->state[2];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = sha->state[3];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = sha->state[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = sha->state[5];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = sha->state[6];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = sha->state[7];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Convert TO host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(*data++, W512[j]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-512 compression function to update a..h */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-512 compression function to update a..h with copy */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* BYTE_ORDER == LITTLE_ENDIAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T2 = Sigma0_512(a) + Maj(a, b, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + T1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = T1 + T2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Part of the message block expansion: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = W512[(j+1)&0x0f];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s0 = sigma0_512(s0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = W512[(j+14)&0x0f];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s1 = sigma1_512(s1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Apply the SHA-512 compression function to update a..h */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin T2 = Sigma0_512(a) + Maj(a, b, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin h = g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin g = f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + T1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = T1 + T2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin j++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } while (j < 80);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Compute the current intermediate hash value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[0] += a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[1] += b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[2] += c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[3] += d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[4] += e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[5] += f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[6] += g;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->state[7] += h;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = b = c = d = e = f = g = h = T1 = T2 = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHA2_UNROLL_TRANSFORM */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_block(register Sum_t* p, const void* s, size_t len)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha512_t* sha = (Sha512_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_byte* data = (sha2_byte*)s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned int freespace, usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!len)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Calculate how much free space is available in the buffer */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin freespace = SHA512_BLOCK_LENGTH - usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (len >= freespace) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Fill the buffer completely and process it */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ADDINC128(sha->bitcount, freespace << 3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin len -= freespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data += freespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA512_Transform(sha, (sha2_word64*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* The buffer is not yet full */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ADDINC128(sha->bitcount, len << 3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = freespace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (len >= SHA512_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Process as many complete blocks as we can */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA512_Transform(sha, (sha2_word64*)data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ADDINC128(sha->bitcount, SHA512_BLOCK_LENGTH << 3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin len -= SHA512_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data += SHA512_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (len > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* There's left-overs, so save 'em */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->buffer, data, len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ADDINC128(sha->bitcount, len << 3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = freespace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_init(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha512_t* sha = (Sha512_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount[0] = sha->bitcount[1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sum_t*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_open(const Method_t* method, const char* name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha512_t* sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (sha = newof(0, Sha512_t, 1, 0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->method = (Method_t*)method;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->name = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha512_init((Sum_t*)sha);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return (Sum_t*)sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_done(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha512_t* sha = (Sha512_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned int usedspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Convert FROM host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(sha->bitcount[0],sha->bitcount[0]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(sha->bitcount[1],sha->bitcount[1]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace > 0) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Begin padding with a 1 bit: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->buffer[usedspace++] = 0x80;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Set-up for the last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (usedspace < SHA512_BLOCK_LENGTH) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Do second-to-last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA512_Transform(sha, (sha2_word64*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* And set-up for the last transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH - 2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } else {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Prepare for final transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA512_SHORT_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Begin padding with a 1 bit: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *sha->buffer = 0x80;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Store the length of input data (in bits): */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH] = sha->bitcount[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = sha->bitcount[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Final transform: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SHA512_Transform(sha, (sha2_word64*)sha->buffer);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if BYTE_ORDER == LITTLE_ENDIAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Convert TO host byte order */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha2_word64* d = (sha2_word64*)sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int j;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (j = 0; j < 8; j++) {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin REVERSE64(sha->state[j],sha->state[j]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *d++ = sha->state[j];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->digest, sha->state, SHA512_DIGEST_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* accumulate the digests */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->digest_sum[i] ^= sha->digest[i];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* Clean up state data: */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha512_t, state));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin usedspace = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha512_t* sha = (Sha512_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + SHA512_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (d < e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sp, "%02x", *d++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha512_data(Sum_t* p, Sumdata_t* data)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha512_t* sha = (Sha512_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->size = SHA512_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->num = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->buf = sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*** SHA-384: *********************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_description "FIPS SHA-384 secure hash algorithm."
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_options "\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(version)?sha-384 (FIPS) 2000-01-01]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+(author)?Aaron D. Gifford]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_match "sha384|sha-384|SHA384|SHA-384"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_scale 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_block sha512_block
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_done sha512_done
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sha384_padding md5_pad
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Sha384_t Sha512_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA384_CTX Sha384_t
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SHA384_DIGEST_LENGTH 48
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha384_init(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha384_t* sha = (Sha384_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMCPY_BCOPY(sha->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin MEMSET_BZERO(sha->buffer, SHA384_BLOCK_LENGTH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->bitcount[0] = sha->bitcount[1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sum_t*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha384_open(const Method_t* method, const char* name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sha384_t* sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (sha = newof(0, Sha384_t, 1, 0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->method = (Method_t*)method;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha->name = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sha384_init((Sum_t*)sha);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return (Sum_t*)sha;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha384_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha384_t* sha = (Sha384_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register sha2_byte* e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin e = d + SHA384_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (d < e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sp, "%02x", *d++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsha384_data(Sum_t* p, Sumdata_t* data)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sha384_t* sha = (Sha384_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->size = SHA384_DIGEST_LENGTH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->num = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data->buf = sha->digest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* _typ_int64_t */