]>
git.saurik.com Git - apple/security.git/blob - AppleCSP/MiscCSPAlgs/SHA1_priv.c
1 /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
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 COMPUTER, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
11 * SHA1_priv.c - low-level SHA-1 hash algorithm.
15 * 05 Jan 1998 Doug Mitchell 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.
22 /* NIST proposed Secure Hash Standard.
24 Written 2 September 1992, Peter C. Gutmann.
25 This implementation placed in the public domain.
27 Comments to pgut1@cs.aukuni.ac.nz */
30 #include "SHA1_priv.h"
33 /* The SHS f()-functions */
35 #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */
36 #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
37 #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */
38 #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
40 /* The SHS Mysterious Constants */
42 #define K1 0x5A827999L /* Rounds 0-19 */
43 #define K2 0x6ED9EBA1L /* Rounds 20-39 */
44 #define K3 0x8F1BBCDCL /* Rounds 40-59 */
45 #define K4 0xCA62C1D6L /* Rounds 60-79 */
47 /* SHS initial values */
49 #define h0init 0x67452301L
50 #define h1init 0xEFCDAB89L
51 #define h2init 0x98BADCFEL
52 #define h3init 0x10325476L
53 #define h4init 0xC3D2E1F0L
55 /* 32-bit rotate - kludged with shifts */
57 #define S(n,X) ( ( X << n ) | ( X >> ( 32 - n ) ) )
59 /* The initial expanding function */
62 * 06 Jan 1998. Added left circular shift per NIST FIPS-180-1 (at
63 * http://www.nist.gov/itl/div897/pubs/fip180-1.htm). Also see
64 * B. Schneier, Applied Cryptography, Second Edition, section 18.7
65 * for info on this addenda to the original NIST spec.
67 #define expand(count) { \
68 W[count] = W[count - 3] ^ W[count - 8] ^ W[count - 14] ^ W[count - 16]; \
69 W[count] = S(1, W[count]); \
72 /* The four SHS sub-rounds */
74 #define subRound1(count) \
76 temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \
84 #define subRound2(count) \
86 temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \
94 #define subRound3(count) \
96 temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \
104 #define subRound4(count) \
106 temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \
114 /* Initialize the SHS values */
116 void shsInit( SHS_INFO
*shsInfo
)
118 /* Set the h-vars to their initial values */
119 shsInfo
->digest
[ 0 ] = h0init
;
120 shsInfo
->digest
[ 1 ] = h1init
;
121 shsInfo
->digest
[ 2 ] = h2init
;
122 shsInfo
->digest
[ 3 ] = h3init
;
123 shsInfo
->digest
[ 4 ] = h4init
;
125 /* Initialise bit count */
126 shsInfo
->countLo
= shsInfo
->countHi
= 0L;
129 /* Perform the SHS transformation. Note that this code, like MD5, seems to
130 break some optimizing compilers - it may be necessary to split it into
131 sections, eg based on the four subrounds */
133 static void shsTransform( SHS_INFO
*shsInfo
)
138 /* Step A. Copy the data buffer into the local work buffer. */
139 /* 07 Jan 1998, dmitch: skip this bogus move, and let the caller
140 * copy data directly into the W[] array. To minimize changes,
141 * we'll just increase the size of shsInfo->data[] and make W
146 /* Step B. Expand the 16 words into 64 temporary data words */
149 * Note: I tried optimizing this via a for loop, and for some reason,
150 * the "optimized" version ran slower on PPC than the original
151 * unrolled version. The optimized version does run faster on i486 than
152 * the unrolled version.
154 * Similarly, the set of subRounds, below, runs slower on i486 when
155 * optimized via 4 'for' loops. The "optimized" version of that is
158 * Conclusion: leave both of 'em unrolled. We could ifdef per machine,
159 * but this would get messy once we had more than two architectures.
160 * We may want to revisit this. --dpm
162 expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
163 expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 );
164 expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 );
165 expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 );
166 expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 );
167 expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 );
168 expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 );
169 expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 );
170 expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 );
171 expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 );
172 expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 );
173 expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 );
174 expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 );
176 /* Step C. Set up first buffer */
177 A
= shsInfo
->digest
[ 0 ];
178 B
= shsInfo
->digest
[ 1 ];
179 C
= shsInfo
->digest
[ 2 ];
180 D
= shsInfo
->digest
[ 3 ];
181 E
= shsInfo
->digest
[ 4 ];
183 /* Step D. Serious mangling, divided into four sub-rounds */
184 subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 );
185 subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 );
186 subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 );
187 subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 );
188 subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 );
189 subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 );
190 subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 );
191 subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 );
192 subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 );
193 subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 );
194 subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 );
195 subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 );
196 subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 );
197 subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 );
198 subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 );
199 subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 );
200 subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 );
201 subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 );
202 subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 );
203 subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 );
205 /* Step E. Build message digest */
206 shsInfo
->digest
[ 0 ] += A
;
207 shsInfo
->digest
[ 1 ] += B
;
208 shsInfo
->digest
[ 2 ] += C
;
209 shsInfo
->digest
[ 3 ] += D
;
210 shsInfo
->digest
[ 4 ] += E
;
213 /* __LITTLE_ENDIAN__ is in fact #defined on OS X on PPC.... */
214 //#ifdef __LITTLE_ENDIAN__
217 /* When run on a little-endian CPU we need to perform byte reversal on an
218 array of longwords. It is possible to make the code endianness-
219 independant by fiddling around with data at the byte level, but this
220 makes for very slow code, so we rely on the user to sort out endianness
223 static void byteReverse( buffer
, byteCount
)
231 byteCount
/= sizeof( LONG
);
232 for( count
= 0; count
< byteCount
; count
++ )
234 value
= ( buffer
[ count
] << 16 ) | ( buffer
[ count
] >> 16 );
235 buffer
[ count
] = ( ( value
& 0xFF00FF00L
) >> 8 ) | ( ( value
& 0x00FF00FFL
) << 8 );
239 #else /* __LITTLE_ENDIAN__ */
242 * Nop for big-endian machines
244 #define byteReverse( buffer, byteCount )
246 #endif /* __LITTLE_ENDIAN__ */
249 /* Update SHS for a block of data. This code assumes that the buffer size
250 is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot
251 more efficient since it does away with the need to handle partial blocks
252 between calls to shsUpdate() */
260 /* Update bitcount */
261 if( ( shsInfo
->countLo
+ ( ( LONG
) count
<< 3 ) ) < shsInfo
->countLo
)
262 shsInfo
->countHi
++; /* Carry from low to high bitCount */
263 shsInfo
->countLo
+= ( ( LONG
) count
<< 3 );
264 shsInfo
->countHi
+= ( ( LONG
) count
>> 29 );
266 /* Process data in SHS_BLOCKSIZE chunks */
267 while( count
>= SHS_BLOCKSIZE
)
269 memcpy( shsInfo
->data
, buffer
, SHS_BLOCKSIZE
);
270 byteReverse( shsInfo
->data
, SHS_BLOCKSIZE
);
271 shsTransform( shsInfo
);
272 buffer
+= SHS_BLOCKSIZE
;
273 count
-= SHS_BLOCKSIZE
;
276 /* Handle any remaining bytes of data. This should only happen once
277 on the final lot of data */
278 memcpy( shsInfo
->data
, buffer
, count
);
281 void shsFinal(SHS_INFO
*shsInfo
)
284 LONG lowBitcount
= shsInfo
->countLo
, highBitcount
= shsInfo
->countHi
;
286 /* Compute number of bytes mod 64 */
287 count
= ( int ) ( ( shsInfo
->countLo
>> 3 ) & 0x3F );
289 /* Set the first char of padding to 0x80. This is safe since there is
290 always at least one byte free */
291 ( ( BYTE
* ) shsInfo
->data
)[ count
++ ] = 0x80;
293 /* Pad out to 56 mod 64 */
296 /* Two lots of padding: Pad the first block to 64 bytes */
297 memset( ( BYTE
* ) &shsInfo
->data
+ count
, 0, 64 - count
);
298 byteReverse( shsInfo
->data
, SHS_BLOCKSIZE
);
299 shsTransform( shsInfo
);
301 /* Now fill the next block with 56 bytes */
302 memset( &shsInfo
->data
, 0, 56 );
305 /* Pad block to 56 bytes */
306 memset( ( BYTE
* ) &shsInfo
->data
+ count
, 0, 56 - count
);
307 byteReverse( shsInfo
->data
, SHS_BLOCKSIZE
);
309 /* Append length in bits and transform */
310 shsInfo
->data
[ 14 ] = highBitcount
;
311 shsInfo
->data
[ 15 ] = lowBitcount
;
313 shsTransform( shsInfo
);
314 byteReverse( shsInfo
->data
, SHS_DIGESTSIZE
);