1/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. 2 * 3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT 4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE 5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE 6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, 7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 8 * EXPOSE YOU TO LIABILITY. 9 *************************************************************************** 10 * 11 * ckSHA1_priv.c - low-level SHA-1 hash algorithm. 12 * 13 * Revision History 14 * ---------------- 15 * 05 Jan 1998 at Apple 16 * Created, based on source by Peter C. Gutmann. 17 * Mods: made reentrant, added NIST fix to expand(), eliminated 18 * unnecessary copy to local W[] array. 19 */ 20 21 22/* NIST proposed Secure Hash Standard. 23 24 Written 2 September 1992, Peter C. Gutmann. 25 This implementation placed in the public domain. 26 27 Comments to pgut1@cs.aukuni.ac.nz */ 28 29#include "ckconfig.h" 30 31#if !CRYPTKIT_LIBMD_DIGEST 32 33#include "ckSHA1_priv.h" 34#include "platform.h" 35#include <string.h> 36 37/* The SHS f()-functions */ 38 39#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */ 40#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ 41#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */ 42#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ 43 44/* The SHS Mysterious Constants */ 45 46#define K1 0x5A827999L /* Rounds 0-19 */ 47#define K2 0x6ED9EBA1L /* Rounds 20-39 */ 48#define K3 0x8F1BBCDCL /* Rounds 40-59 */ 49#define K4 0xCA62C1D6L /* Rounds 60-79 */ 50 51/* SHS initial values */ 52 53#define h0init 0x67452301L 54#define h1init 0xEFCDAB89L 55#define h2init 0x98BADCFEL 56#define h3init 0x10325476L 57#define h4init 0xC3D2E1F0L 58 59/* 32-bit rotate - kludged with shifts */ 60 61#define S(n,X) ( ( X << n ) | ( X >> ( 32 - n ) ) ) 62 63/* The initial expanding function */ 64 65/* 66 * 06 Jan 1998. Added left circular shift per NIST FIPS-180-1 (at 67 * http://www.nist.gov/itl/div897/pubs/fip180-1.htm). Also see 68 * B. Schneier, Applied Cryptography, Second Edition, section 18.7 69 * for info on this addenda to the original NIST spec. 70 */ 71#define expand(count) { \ 72 W[count] = W[count - 3] ^ W[count - 8] ^ W[count - 14] ^ W[count - 16]; \ 73 W[count] = S(1, W[count]); \ 74} 75 76/* The four SHS sub-rounds */ 77 78#define subRound1(count) \ 79 { \ 80 temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \ 81 E = D; \ 82 D = C; \ 83 C = S( 30, B ); \ 84 B = A; \ 85 A = temp; \ 86 } 87 88#define subRound2(count) \ 89 { \ 90 temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \ 91 E = D; \ 92 D = C; \ 93 C = S( 30, B ); \ 94 B = A; \ 95 A = temp; \ 96 } 97 98#define subRound3(count) \ 99 { \ 100 temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \ 101 E = D; \ 102 D = C; \ 103 C = S( 30, B ); \ 104 B = A; \ 105 A = temp; \ 106 } 107 108#define subRound4(count) \ 109 { \ 110 temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \ 111 E = D; \ 112 D = C; \ 113 C = S( 30, B ); \ 114 B = A; \ 115 A = temp; \ 116 } 117 118/* Initialize the SHS values */ 119 120void shsInit( SHS_INFO *shsInfo ) 121 { 122 /* Set the h-vars to their initial values */ 123 shsInfo->digest[ 0 ] = h0init; 124 shsInfo->digest[ 1 ] = h1init; 125 shsInfo->digest[ 2 ] = h2init; 126 shsInfo->digest[ 3 ] = h3init; 127 shsInfo->digest[ 4 ] = h4init; 128 129 /* Initialise bit count */ 130 shsInfo->countLo = shsInfo->countHi = 0L; 131 } 132 133/* Perform the SHS transformation. Note that this code, like MD5, seems to 134 break some optimizing compilers - it may be necessary to split it into 135 sections, eg based on the four subrounds */ 136 137static void shsTransform( SHS_INFO *shsInfo ) 138{ 139 LONG *W, temp; 140 LONG A, B, C, D, E; 141 142 /* Step A. Copy the data buffer into the local work buffer. */ 143 /* 07 Jan 1998, dmitch: skip this bogus move, and let the caller 144 * copy data directly into the W[] array. To minimize changes, 145 * we'll just increase the size of shsInfo->data[] and make W 146 * a pointer here. 147 */ 148 W = shsInfo->data; 149 150 /* Step B. Expand the 16 words into 64 temporary data words */ 151 152 /* 153 * Note: I tried optimizing this via a for loop, and for some reason, 154 * the "optimized" version ran slower on PPC than the original 155 * unrolled version. The optimized version does run faster on i486 than 156 * the unrolled version. 157 * 158 * Similarly, the set of subRounds, below, runs slower on i486 when 159 * optimized via 4 'for' loops. The "optimized" version of that is 160 * a wash on PPC. 161 * 162 * Conclusion: leave both of 'em unrolled. We could ifdef per machine, 163 * but this would get messy once we had more than two architectures. 164 * We may want to revisit this. --dpm 165 */ 166 expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 ); 167 expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 ); 168 expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 ); 169 expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 ); 170 expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 ); 171 expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 ); 172 expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 ); 173 expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 ); 174 expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 ); 175 expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 ); 176 expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 ); 177 expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 ); 178 expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 ); 179 180 /* Step C. Set up first buffer */ 181 A = shsInfo->digest[ 0 ]; 182 B = shsInfo->digest[ 1 ]; 183 C = shsInfo->digest[ 2 ]; 184 D = shsInfo->digest[ 3 ]; 185 E = shsInfo->digest[ 4 ]; 186 187 /* Step D. Serious mangling, divided into four sub-rounds */ 188 subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 ); 189 subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 ); 190 subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 ); 191 subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 ); 192 subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 ); 193 subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 ); 194 subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 ); 195 subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 ); 196 subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 ); 197 subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 ); 198 subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 ); 199 subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 ); 200 subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 ); 201 subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 ); 202 subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 ); 203 subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 ); 204 subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 ); 205 subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 ); 206 subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 ); 207 subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 ); 208 209 /* Step E. Build message digest */ 210 shsInfo->digest[ 0 ] += A; 211 shsInfo->digest[ 1 ] += B; 212 shsInfo->digest[ 2 ] += C; 213 shsInfo->digest[ 3 ] += D; 214 shsInfo->digest[ 4 ] += E; 215} 216 217/* __LITTLE_ENDIAN__ is in fact #defined on OS X on PPC.... */ 218//#ifdef __LITTLE_ENDIAN__ 219#if 0 220 221/* When run on a little-endian CPU we need to perform byte reversal on an 222 array of longwords. It is possible to make the code endianness- 223 independant by fiddling around with data at the byte level, but this 224 makes for very slow code, so we rely on the user to sort out endianness 225 at compile time */ 226 227static void byteReverse( buffer, byteCount ) 228 LONG *buffer; 229 int byteCount; 230 231 { 232 LONG value; 233 int count; 234 235 byteCount /= sizeof( LONG ); 236 for( count = 0; count < byteCount; count++ ) 237 { 238 value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 ); 239 buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 ); 240 } 241 } 242 243#else /* __LITTLE_ENDIAN__ */ 244 245/* 246 * Nop for big-endian machines 247 */ 248#define byteReverse( buffer, byteCount ) 249 250#endif /* __LITTLE_ENDIAN__ */ 251 252 253/* Update SHS for a block of data. This code assumes that the buffer size 254 is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot 255 more efficient since it does away with the need to handle partial blocks 256 between calls to shsUpdate() */ 257 258void shsUpdate( 259 SHS_INFO *shsInfo, 260 const BYTE *buffer, 261 int count) 262 263 { 264 /* Update bitcount */ 265 if( ( shsInfo->countLo + ( ( LONG ) count << 3 ) ) < shsInfo->countLo ) 266 shsInfo->countHi++; /* Carry from low to high bitCount */ 267 shsInfo->countLo += ( ( LONG ) count << 3 ); 268 shsInfo->countHi += ( ( LONG ) count >> 29 ); 269 270 /* Process data in SHS_BLOCKSIZE chunks */ 271 while( count >= SHS_BLOCKSIZE ) 272 { 273 memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE ); 274 byteReverse( shsInfo->data, SHS_BLOCKSIZE ); 275 shsTransform( shsInfo ); 276 buffer += SHS_BLOCKSIZE; 277 count -= SHS_BLOCKSIZE; 278 } 279 280 /* Handle any remaining bytes of data. This should only happen once 281 on the final lot of data */ 282 memcpy( shsInfo->data, buffer, count ); 283 } 284 285void shsFinal(SHS_INFO *shsInfo) 286 { 287 int count; 288 LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi; 289 290 /* Compute number of bytes mod 64 */ 291 count = ( int ) ( ( shsInfo->countLo >> 3 ) & 0x3F ); 292 293 /* Set the first char of padding to 0x80. This is safe since there is 294 always at least one byte free */ 295 ( ( BYTE * ) shsInfo->data )[ count++ ] = 0x80; 296 297 /* Pad out to 56 mod 64 */ 298 if( count > 56 ) 299 { 300 /* Two lots of padding: Pad the first block to 64 bytes */ 301 memset( ( BYTE * ) &shsInfo->data + count, 0, 64 - count ); 302 byteReverse( shsInfo->data, SHS_BLOCKSIZE ); 303 shsTransform( shsInfo ); 304 305 /* Now fill the next block with 56 bytes */ 306 memset( &shsInfo->data, 0, 56 ); 307 } 308 else 309 /* Pad block to 56 bytes */ 310 memset( ( BYTE * ) &shsInfo->data + count, 0, 56 - count ); 311 byteReverse( shsInfo->data, SHS_BLOCKSIZE ); 312 313 /* Append length in bits and transform */ 314 shsInfo->data[ 14 ] = highBitcount; 315 shsInfo->data[ 15 ] = lowBitcount; 316 317 shsTransform( shsInfo ); 318 byteReverse( shsInfo->data, SHS_DIGESTSIZE ); 319 } 320 321#endif /* CRYPTKIT_LIBMD_DIGEST */ 322