]> git.saurik.com Git - apple/security.git/blob - AppleCSP/MiscCSPAlgs/SHA1_priv.c
Security-163.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 <string.h>
32
33 /* The SHS f()-functions */
34
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 */
39
40 /* The SHS Mysterious Constants */
41
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 */
46
47 /* SHS initial values */
48
49 #define h0init 0x67452301L
50 #define h1init 0xEFCDAB89L
51 #define h2init 0x98BADCFEL
52 #define h3init 0x10325476L
53 #define h4init 0xC3D2E1F0L
54
55 /* 32-bit rotate - kludged with shifts */
56
57 #define S(n,X) ( ( X << n ) | ( X >> ( 32 - n ) ) )
58
59 /* The initial expanding function */
60
61 /*
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.
66 */
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]); \
70 }
71
72 /* The four SHS sub-rounds */
73
74 #define subRound1(count) \
75 { \
76 temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \
77 E = D; \
78 D = C; \
79 C = S( 30, B ); \
80 B = A; \
81 A = temp; \
82 }
83
84 #define subRound2(count) \
85 { \
86 temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \
87 E = D; \
88 D = C; \
89 C = S( 30, B ); \
90 B = A; \
91 A = temp; \
92 }
93
94 #define subRound3(count) \
95 { \
96 temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \
97 E = D; \
98 D = C; \
99 C = S( 30, B ); \
100 B = A; \
101 A = temp; \
102 }
103
104 #define subRound4(count) \
105 { \
106 temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \
107 E = D; \
108 D = C; \
109 C = S( 30, B ); \
110 B = A; \
111 A = temp; \
112 }
113
114 /* Initialize the SHS values */
115
116 void shsInit( SHS_INFO *shsInfo )
117 {
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;
124
125 /* Initialise bit count */
126 shsInfo->countLo = shsInfo->countHi = 0L;
127 }
128
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 */
132
133 static void shsTransform( SHS_INFO *shsInfo )
134 {
135 LONG *W, temp;
136 LONG A, B, C, D, E;
137
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
142 * a pointer here.
143 */
144 W = shsInfo->data;
145
146 /* Step B. Expand the 16 words into 64 temporary data words */
147
148 /*
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.
153 *
154 * Similarly, the set of subRounds, below, runs slower on i486 when
155 * optimized via 4 'for' loops. The "optimized" version of that is
156 * a wash on PPC.
157 *
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
161 */
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 );
175
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 ];
182
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 );
204
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;
211 }
212
213 #ifdef __LITTLE_ENDIAN__
214
215 /* When run on a little-endian CPU we need to perform byte reversal on an
216 array of longwords. It is possible to make the code endianness-
217 independant by fiddling around with data at the byte level, but this
218 makes for very slow code, so we rely on the user to sort out endianness
219 at compile time */
220
221 static void byteReverse( buffer, byteCount )
222 LONG *buffer;
223 int byteCount;
224
225 {
226 LONG value;
227 int count;
228
229 byteCount /= sizeof( LONG );
230 for( count = 0; count < byteCount; count++ )
231 {
232 value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
233 buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
234 }
235 }
236
237 #else /* __LITTLE_ENDIAN__ */
238
239 /*
240 * Nop for big-endian machines
241 */
242 #define byteReverse( buffer, byteCount )
243
244 #endif /* __LITTLE_ENDIAN__ */
245
246
247 /* Update SHS for a block of data. This code assumes that the buffer size
248 is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot
249 more efficient since it does away with the need to handle partial blocks
250 between calls to shsUpdate() */
251
252 void shsUpdate(
253 SHS_INFO *shsInfo,
254 const BYTE *buffer,
255 int count)
256
257 {
258 /* Update bitcount */
259 if( ( shsInfo->countLo + ( ( LONG ) count << 3 ) ) < shsInfo->countLo )
260 shsInfo->countHi++; /* Carry from low to high bitCount */
261 shsInfo->countLo += ( ( LONG ) count << 3 );
262 shsInfo->countHi += ( ( LONG ) count >> 29 );
263
264 /* Process data in SHS_BLOCKSIZE chunks */
265 while( count >= SHS_BLOCKSIZE )
266 {
267 memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );
268 byteReverse( shsInfo->data, SHS_BLOCKSIZE );
269 shsTransform( shsInfo );
270 buffer += SHS_BLOCKSIZE;
271 count -= SHS_BLOCKSIZE;
272 }
273
274 /* Handle any remaining bytes of data. This should only happen once
275 on the final lot of data */
276 memcpy( shsInfo->data, buffer, count );
277 }
278
279 void shsFinal(SHS_INFO *shsInfo)
280 {
281 int count;
282 LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi;
283
284 /* Compute number of bytes mod 64 */
285 count = ( int ) ( ( shsInfo->countLo >> 3 ) & 0x3F );
286
287 /* Set the first char of padding to 0x80. This is safe since there is
288 always at least one byte free */
289 ( ( BYTE * ) shsInfo->data )[ count++ ] = 0x80;
290
291 /* Pad out to 56 mod 64 */
292 if( count > 56 )
293 {
294 /* Two lots of padding: Pad the first block to 64 bytes */
295 memset( ( BYTE * ) &shsInfo->data + count, 0, 64 - count );
296 byteReverse( shsInfo->data, SHS_BLOCKSIZE );
297 shsTransform( shsInfo );
298
299 /* Now fill the next block with 56 bytes */
300 memset( &shsInfo->data, 0, 56 );
301 }
302 else
303 /* Pad block to 56 bytes */
304 memset( ( BYTE * ) &shsInfo->data + count, 0, 56 - count );
305 byteReverse( shsInfo->data, SHS_BLOCKSIZE );
306
307 /* Append length in bits and transform */
308 shsInfo->data[ 14 ] = highBitcount;
309 shsInfo->data[ 15 ] = lowBitcount;
310
311 shsTransform( shsInfo );
312 byteReverse( shsInfo->digest, SHS_DIGESTSIZE );
313 }