]>
Commit | Line | Data |
---|---|---|
d8f41ccd | 1 | /* Copyright (c) 1998,2004 Apple Computer, Inc. All Rights Reserved. |
b1ab9ed8 A |
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 | * | |
d8f41ccd | 11 | * SHA1_priv.c - low-level SHA-1 hash algorithm. |
b1ab9ed8 A |
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 | ||
b1ab9ed8 | 29 | |
d8f41ccd | 30 | #include "SHA1_priv.h" |
b1ab9ed8 A |
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 | ||
d8f41ccd | 213 | #ifdef __LITTLE_ENDIAN__ |
b1ab9ed8 A |
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 ); | |
d8f41ccd | 312 | byteReverse( shsInfo->digest, SHS_DIGESTSIZE ); |
b1ab9ed8 | 313 | } |