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