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