1 | /* |
2 | * sha1.c |
3 | * |
4 | * Description: |
5 | * This file implements the Secure Hashing Algorithm 1 as |
6 | * defined in FIPS PUB 180-1 published April 17, 1995. |
7 | * |
8 | * The SHA-1, produces a 160-bit message digest for a given |
9 | * data stream. It should take about 2**n steps to find a |
10 | * message with the same digest as a given message and |
11 | * 2**(n/2) to find any two messages with the same digest, |
12 | * when n is the digest size in bits. Therefore, this |
13 | * algorithm can serve as a means of providing a |
14 | * "fingerprint" for a message. |
15 | * |
16 | * Portability Issues: |
17 | * SHA-1 is defined in terms of 32-bit "words". This code |
18 | * uses <stdint.h> (included via "sha1.h" to define 32 and 8 |
19 | * bit unsigned integer types. If your C compiler does not |
20 | * support 32 bit unsigned integers, this code is not |
21 | * appropriate. |
22 | * |
23 | * Caveats: |
24 | * SHA-1 is designed to work with messages less than 2^64 bits |
25 | * long. Although SHA-1 allows a message digest to be generated |
26 | * for messages of any number of bits less than 2^64, this |
27 | * implementation only works with messages with a length that is |
28 | * a multiple of the size of an 8-bit character. |
29 | * |
30 | */ |
31 | |
32 | #ifdef HAVE_CONFIG_H |
33 | #include "config.h" |
34 | #endif |
35 | #include "base/ints.h" |
36 | #include "base/sha1_rfc3174.h" |
37 | |
38 | /* |
39 | * Define the SHA1 circular left shift macro |
40 | */ |
41 | #define SHA1CircularShift(bits,word) \ |
42 | (((word) << (bits)) | ((word) >> (32-(bits)))) |
43 | |
44 | /* Local Function Prototyptes */ |
45 | void SHA1PadMessage(SHA1Context *); |
46 | void SHA1ProcessMessageBlock(SHA1Context *); |
47 | |
48 | /* |
49 | * SHA1Reset |
50 | * |
51 | * Description: |
52 | * This function will initialize the SHA1Context in preparation |
53 | * for computing a new SHA1 message digest. |
54 | * |
55 | * Parameters: |
56 | * context: [in/out] |
57 | * The context to reset. |
58 | * |
59 | * Returns: |
60 | * sha Error Code. |
61 | * |
62 | */ |
63 | int SHA1Reset(SHA1Context *context) |
64 | { |
65 | if (!context) |
66 | { |
67 | return shaNull; |
68 | } |
69 | |
70 | context->Length_Low = 0; |
71 | context->Length_High = 0; |
72 | context->Message_Block_Index = 0; |
73 | |
74 | context->Intermediate_Hash[0] = 0x67452301; |
75 | context->Intermediate_Hash[1] = 0xEFCDAB89; |
76 | context->Intermediate_Hash[2] = 0x98BADCFE; |
77 | context->Intermediate_Hash[3] = 0x10325476; |
78 | context->Intermediate_Hash[4] = 0xC3D2E1F0; |
79 | |
80 | context->Computed = 0; |
81 | context->Corrupted = 0; |
82 | |
83 | return shaSuccess; |
84 | } |
85 | |
86 | /* |
87 | * SHA1Result |
88 | * |
89 | * Description: |
90 | * This function will return the 160-bit message digest into the |
91 | * Message_Digest array provided by the caller. |
92 | * NOTE: The first octet of hash is stored in the 0th element, |
93 | * the last octet of hash in the 19th element. |
94 | * |
95 | * Parameters: |
96 | * context: [in/out] |
97 | * The context to use to calculate the SHA-1 hash. |
98 | * Message_Digest: [out] |
99 | * Where the digest is returned. |
100 | * |
101 | * Returns: |
102 | * sha Error Code. |
103 | * |
104 | */ |
105 | int SHA1Result( SHA1Context *context, |
106 | uint8_t Message_Digest[SHA1HashSize]) |
107 | { |
108 | int i; |
109 | |
110 | if (!context || !Message_Digest) |
111 | { |
112 | return shaNull; |
113 | } |
114 | |
115 | if (context->Corrupted) |
116 | { |
117 | return context->Corrupted; |
118 | } |
119 | |
120 | if (!context->Computed) |
121 | { |
122 | SHA1PadMessage(context); |
123 | for(i=0; i<64; ++i) |
124 | { |
125 | /* message may be sensitive, clear it out */ |
126 | context->Message_Block[i] = 0; |
127 | } |
128 | context->Length_Low = 0; /* and clear length */ |
129 | context->Length_High = 0; |
130 | context->Computed = 1; |
131 | |
132 | } |
133 | |
134 | for(i = 0; i < SHA1HashSize; ++i) |
135 | { |
136 | Message_Digest[i] = context->Intermediate_Hash[i>>2] |
137 | >> 8 * ( 3 - ( i & 0x03 ) ); |
138 | } |
139 | |
140 | return shaSuccess; |
141 | } |
142 | |
143 | /* |
144 | * SHA1Input |
145 | * |
146 | * Description: |
147 | * This function accepts an array of octets as the next portion |
148 | * of the message. |
149 | * |
150 | * Parameters: |
151 | * context: [in/out] |
152 | * The SHA context to update |
153 | * message_array: [in] |
154 | * An array of characters representing the next portion of |
155 | * the message. |
156 | * length: [in] |
157 | * The length of the message in message_array |
158 | * |
159 | * Returns: |
160 | * sha Error Code. |
161 | * |
162 | */ |
163 | int SHA1Input( SHA1Context *context, |
164 | const uint8_t *message_array, |
165 | unsigned int length) |
166 | { |
167 | if (!length) |
168 | { |
169 | return shaSuccess; |
170 | } |
171 | |
172 | if (!context || !message_array) |
173 | { |
174 | return shaNull; |
175 | } |
176 | |
177 | if (context->Computed) |
178 | { |
179 | context->Corrupted = shaStateError; |
180 | |
181 | return shaStateError; |
182 | } |
183 | |
184 | if (context->Corrupted) |
185 | { |
186 | return context->Corrupted; |
187 | } |
188 | while(length-- && !context->Corrupted) |
189 | { |
190 | context->Message_Block[context->Message_Block_Index++] = |
191 | (*message_array & 0xFF); |
192 | |
193 | context->Length_Low += 8; |
194 | if (context->Length_Low == 0) |
195 | { |
196 | context->Length_High++; |
197 | if (context->Length_High == 0) |
198 | { |
199 | /* Message is too long */ |
200 | context->Corrupted = 1; |
201 | } |
202 | } |
203 | |
204 | if (context->Message_Block_Index == 64) |
205 | { |
206 | SHA1ProcessMessageBlock(context); |
207 | } |
208 | |
209 | message_array++; |
210 | } |
211 | |
212 | return shaSuccess; |
213 | } |
214 | |
215 | /* |
216 | * SHA1ProcessMessageBlock |
217 | * |
218 | * Description: |
219 | * This function will process the next 512 bits of the message |
220 | * stored in the Message_Block array. |
221 | * |
222 | * Parameters: |
223 | * None. |
224 | * |
225 | * Returns: |
226 | * Nothing. |
227 | * |
228 | * Comments: |
229 | |
230 | * Many of the variable names in this code, especially the |
231 | * single character names, were used because those were the |
232 | * names used in the publication. |
233 | * |
234 | * |
235 | */ |
236 | void SHA1ProcessMessageBlock(SHA1Context *context) |
237 | { |
238 | const uint32_t K[] = { /* Constants defined in SHA-1 */ |
239 | 0x5A827999, |
240 | 0x6ED9EBA1, |
241 | 0x8F1BBCDC, |
242 | 0xCA62C1D6 |
243 | }; |
244 | int t; /* Loop counter */ |
245 | uint32_t temp; /* Temporary word value */ |
246 | uint32_t W[80]; /* Word sequence */ |
247 | uint32_t A, B, C, D, E; /* Word buffers */ |
248 | |
249 | /* |
250 | * Initialize the first 16 words in the array W |
251 | */ |
252 | for(t = 0; t < 16; t++) |
253 | { |
254 | W[t] = context->Message_Block[t * 4] << 24; |
255 | W[t] |= context->Message_Block[t * 4 + 1] << 16; |
256 | W[t] |= context->Message_Block[t * 4 + 2] << 8; |
257 | W[t] |= context->Message_Block[t * 4 + 3]; |
258 | } |
259 | |
260 | for(t = 16; t < 80; t++) |
261 | { |
262 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); |
263 | } |
264 | |
265 | A = context->Intermediate_Hash[0]; |
266 | B = context->Intermediate_Hash[1]; |
267 | C = context->Intermediate_Hash[2]; |
268 | D = context->Intermediate_Hash[3]; |
269 | E = context->Intermediate_Hash[4]; |
270 | |
271 | for(t = 0; t < 20; t++) |
272 | { |
273 | temp = SHA1CircularShift(5,A) + |
274 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; |
275 | E = D; |
276 | D = C; |
277 | C = SHA1CircularShift(30,B); |
278 | |
279 | B = A; |
280 | A = temp; |
281 | } |
282 | |
283 | for(t = 20; t < 40; t++) |
284 | { |
285 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; |
286 | E = D; |
287 | D = C; |
288 | C = SHA1CircularShift(30,B); |
289 | B = A; |
290 | A = temp; |
291 | } |
292 | |
293 | for(t = 40; t < 60; t++) |
294 | { |
295 | temp = SHA1CircularShift(5,A) + |
296 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; |
297 | E = D; |
298 | D = C; |
299 | C = SHA1CircularShift(30,B); |
300 | B = A; |
301 | A = temp; |
302 | } |
303 | |
304 | for(t = 60; t < 80; t++) |
305 | { |
306 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; |
307 | E = D; |
308 | D = C; |
309 | C = SHA1CircularShift(30,B); |
310 | B = A; |
311 | A = temp; |
312 | } |
313 | |
314 | context->Intermediate_Hash[0] += A; |
315 | context->Intermediate_Hash[1] += B; |
316 | context->Intermediate_Hash[2] += C; |
317 | context->Intermediate_Hash[3] += D; |
318 | context->Intermediate_Hash[4] += E; |
319 | |
320 | context->Message_Block_Index = 0; |
321 | } |
322 | |
323 | /* |
324 | * SHA1PadMessage |
325 | * |
326 | |
327 | * Description: |
328 | * According to the standard, the message must be padded to an even |
329 | * 512 bits. The first padding bit must be a '1'. The last 64 |
330 | * bits represent the length of the original message. All bits in |
331 | * between should be 0. This function will pad the message |
332 | * according to those rules by filling the Message_Block array |
333 | * accordingly. It will also call the ProcessMessageBlock function |
334 | * provided appropriately. When it returns, it can be assumed that |
335 | * the message digest has been computed. |
336 | * |
337 | * Parameters: |
338 | * context: [in/out] |
339 | * The context to pad |
340 | * ProcessMessageBlock: [in] |
341 | * The appropriate SHA*ProcessMessageBlock function |
342 | * Returns: |
343 | * Nothing. |
344 | * |
345 | */ |
346 | |
347 | void SHA1PadMessage(SHA1Context *context) |
348 | { |
349 | /* |
350 | * Check to see if the current message block is too small to hold |
351 | * the initial padding bits and length. If so, we will pad the |
352 | * block, process it, and then continue padding into a second |
353 | * block. |
354 | */ |
355 | if (context->Message_Block_Index > 55) |
356 | { |
357 | context->Message_Block[context->Message_Block_Index++] = 0x80; |
358 | while(context->Message_Block_Index < 64) |
359 | { |
360 | context->Message_Block[context->Message_Block_Index++] = 0; |
361 | } |
362 | |
363 | SHA1ProcessMessageBlock(context); |
364 | |
365 | while(context->Message_Block_Index < 56) |
366 | { |
367 | context->Message_Block[context->Message_Block_Index++] = 0; |
368 | } |
369 | } |
370 | else |
371 | { |
372 | context->Message_Block[context->Message_Block_Index++] = 0x80; |
373 | while(context->Message_Block_Index < 56) |
374 | { |
375 | |
376 | context->Message_Block[context->Message_Block_Index++] = 0; |
377 | } |
378 | } |
379 | |
380 | /* |
381 | * Store the message length as the last 8 octets |
382 | */ |
383 | context->Message_Block[56] = context->Length_High >> 24; |
384 | context->Message_Block[57] = context->Length_High >> 16; |
385 | context->Message_Block[58] = context->Length_High >> 8; |
386 | context->Message_Block[59] = context->Length_High; |
387 | context->Message_Block[60] = context->Length_Low >> 24; |
388 | context->Message_Block[61] = context->Length_Low >> 16; |
389 | context->Message_Block[62] = context->Length_Low >> 8; |
390 | context->Message_Block[63] = context->Length_Low; |
391 | |
392 | SHA1ProcessMessageBlock(context); |
393 | } |
394 | |