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