DOSBox-X
|
00001 /* 00002 * sha1.cpp 00003 * 00004 * Copyright (C) 1998, 2009 00005 * Paul E. Jones <paulej@packetizer.com> 00006 * All Rights Reserved. 00007 * 00008 ***************************************************************************** 00009 * $Id: sha1.cpp 12 2009-06-22 19:34:25Z paulej $ 00010 ***************************************************************************** 00011 * 00012 * Description: 00013 * This class implements the Secure Hashing Standard as defined 00014 * in FIPS PUB 180-1 published April 17, 1995. 00015 * 00016 * The Secure Hashing Standard, which uses the Secure Hashing 00017 * Algorithm (SHA), produces a 160-bit message digest for a 00018 * given data stream. In theory, it is highly improbable that 00019 * two messages will produce the same message digest. Therefore, 00020 * this algorithm can serve as a means of providing a "fingerprint" 00021 * for a message. 00022 * 00023 * Portability Issues: 00024 * SHA-1 is defined in terms of 32-bit "words". This code was 00025 * written with the expectation that the processor has at least 00026 * a 32-bit machine word size. If the machine word size is larger, 00027 * the code should still function properly. One caveat to that 00028 * is that the input functions taking characters and character arrays 00029 * assume that only 8 bits of information are stored in each character. 00030 * 00031 * Caveats: 00032 * SHA-1 is designed to work with messages less than 2^64 bits long. 00033 * Although SHA-1 allows a message digest to be generated for 00034 * messages of any number of bits less than 2^64, this implementation 00035 * only works with messages with a length that is a multiple of 8 00036 * bits. 00037 * 00038 */ 00039 00040 00041 #include "sha1.h" 00042 00043 /* 00044 * SHA1 00045 * 00046 * Description: 00047 * This is the constructor for the sha1 class. 00048 * 00049 * Parameters: 00050 * None. 00051 * 00052 * Returns: 00053 * Nothing. 00054 * 00055 * Comments: 00056 * 00057 */ 00058 SHA1::SHA1() 00059 { 00060 Reset(); 00061 } 00062 00063 /* 00064 * ~SHA1 00065 * 00066 * Description: 00067 * This is the destructor for the sha1 class 00068 * 00069 * Parameters: 00070 * None. 00071 * 00072 * Returns: 00073 * Nothing. 00074 * 00075 * Comments: 00076 * 00077 */ 00078 SHA1::~SHA1() 00079 { 00080 // The destructor does nothing 00081 } 00082 00083 /* 00084 * Reset 00085 * 00086 * Description: 00087 * This function will initialize the sha1 class member variables 00088 * in preparation for computing a new message digest. 00089 * 00090 * Parameters: 00091 * None. 00092 * 00093 * Returns: 00094 * Nothing. 00095 * 00096 * Comments: 00097 * 00098 */ 00099 void SHA1::Reset() 00100 { 00101 Length_Low = 0; 00102 Length_High = 0; 00103 Message_Block_Index = 0; 00104 00105 H[0] = 0x67452301; 00106 H[1] = 0xEFCDAB89; 00107 H[2] = 0x98BADCFE; 00108 H[3] = 0x10325476; 00109 H[4] = 0xC3D2E1F0; 00110 00111 Computed = false; 00112 Corrupted = false; 00113 } 00114 00115 /* 00116 * Result 00117 * 00118 * Description: 00119 * This function will return the 160-bit message digest into the 00120 * array provided. 00121 * 00122 * Parameters: 00123 * message_digest_array: [out] 00124 * This is an array of five unsigned integers which will be filled 00125 * with the message digest that has been computed. 00126 * 00127 * Returns: 00128 * True if successful, false if it failed. 00129 * 00130 * Comments: 00131 * 00132 */ 00133 bool SHA1::Result(unsigned *message_digest_array) 00134 { 00135 int i; // Counter 00136 00137 if (Corrupted) 00138 { 00139 return false; 00140 } 00141 00142 if (!Computed) 00143 { 00144 PadMessage(); 00145 Computed = true; 00146 } 00147 00148 for(i = 0; i < 5; i++) 00149 { 00150 message_digest_array[i] = H[i]; 00151 } 00152 00153 return true; 00154 } 00155 00156 /* 00157 * Input 00158 * 00159 * Description: 00160 * This function accepts an array of octets as the next portion of 00161 * the message. 00162 * 00163 * Parameters: 00164 * message_array: [in] 00165 * An array of characters representing the next portion of the 00166 * message. 00167 * 00168 * Returns: 00169 * Nothing. 00170 * 00171 * Comments: 00172 * 00173 */ 00174 void SHA1::Input( const unsigned char *message_array, 00175 unsigned length) 00176 { 00177 if (!length) 00178 { 00179 return; 00180 } 00181 00182 if (Computed || Corrupted) 00183 { 00184 Corrupted = true; 00185 return; 00186 } 00187 00188 while(length-- && !Corrupted) 00189 { 00190 Message_Block[Message_Block_Index++] = (*message_array & 0xFF); 00191 00192 Length_Low += 8; 00193 Length_Low &= 0xFFFFFFFF; // Force it to 32 bits 00194 if (Length_Low == 0) 00195 { 00196 Length_High++; 00197 Length_High &= 0xFFFFFFFF; // Force it to 32 bits 00198 if (Length_High == 0) 00199 { 00200 Corrupted = true; // Message is too long 00201 } 00202 } 00203 00204 if (Message_Block_Index == 64) 00205 { 00206 ProcessMessageBlock(); 00207 } 00208 00209 message_array++; 00210 } 00211 } 00212 00213 /* 00214 * Input 00215 * 00216 * Description: 00217 * This function accepts an array of octets as the next portion of 00218 * the message. 00219 * 00220 * Parameters: 00221 * message_array: [in] 00222 * An array of characters representing the next portion of the 00223 * message. 00224 * length: [in] 00225 * The length of the message_array 00226 * 00227 * Returns: 00228 * Nothing. 00229 * 00230 * Comments: 00231 * 00232 */ 00233 void SHA1::Input( const char *message_array, 00234 unsigned length) 00235 { 00236 Input((unsigned char *) message_array, length); 00237 } 00238 00239 /* 00240 * Input 00241 * 00242 * Description: 00243 * This function accepts a single octets as the next message element. 00244 * 00245 * Parameters: 00246 * message_element: [in] 00247 * The next octet in the message. 00248 * 00249 * Returns: 00250 * Nothing. 00251 * 00252 * Comments: 00253 * 00254 */ 00255 void SHA1::Input(unsigned char message_element) 00256 { 00257 Input(&message_element, 1); 00258 } 00259 00260 /* 00261 * Input 00262 * 00263 * Description: 00264 * This function accepts a single octet as the next message element. 00265 * 00266 * Parameters: 00267 * message_element: [in] 00268 * The next octet in the message. 00269 * 00270 * Returns: 00271 * Nothing. 00272 * 00273 * Comments: 00274 * 00275 */ 00276 void SHA1::Input(char message_element) 00277 { 00278 Input((unsigned char *) &message_element, 1); 00279 } 00280 00281 /* 00282 * operator<< 00283 * 00284 * Description: 00285 * This operator makes it convenient to provide character strings to 00286 * the SHA1 object for processing. 00287 * 00288 * Parameters: 00289 * message_array: [in] 00290 * The character array to take as input. 00291 * 00292 * Returns: 00293 * A reference to the SHA1 object. 00294 * 00295 * Comments: 00296 * Each character is assumed to hold 8 bits of information. 00297 * 00298 */ 00299 SHA1& SHA1::operator<<(const char *message_array) 00300 { 00301 const char *p = message_array; 00302 00303 while(*p) 00304 { 00305 Input(*p); 00306 p++; 00307 } 00308 00309 return *this; 00310 } 00311 00312 /* 00313 * operator<< 00314 * 00315 * Description: 00316 * This operator makes it convenient to provide character strings to 00317 * the SHA1 object for processing. 00318 * 00319 * Parameters: 00320 * message_array: [in] 00321 * The character array to take as input. 00322 * 00323 * Returns: 00324 * A reference to the SHA1 object. 00325 * 00326 * Comments: 00327 * Each character is assumed to hold 8 bits of information. 00328 * 00329 */ 00330 SHA1& SHA1::operator<<(const unsigned char *message_array) 00331 { 00332 const unsigned char *p = message_array; 00333 00334 while(*p) 00335 { 00336 Input(*p); 00337 p++; 00338 } 00339 00340 return *this; 00341 } 00342 00343 /* 00344 * operator<< 00345 * 00346 * Description: 00347 * This function provides the next octet in the message. 00348 * 00349 * Parameters: 00350 * message_element: [in] 00351 * The next octet in the message 00352 * 00353 * Returns: 00354 * A reference to the SHA1 object. 00355 * 00356 * Comments: 00357 * The character is assumed to hold 8 bits of information. 00358 * 00359 */ 00360 SHA1& SHA1::operator<<(const char message_element) 00361 { 00362 Input((unsigned char *) &message_element, 1); 00363 00364 return *this; 00365 } 00366 00367 /* 00368 * operator<< 00369 * 00370 * Description: 00371 * This function provides the next octet in the message. 00372 * 00373 * Parameters: 00374 * message_element: [in] 00375 * The next octet in the message 00376 * 00377 * Returns: 00378 * A reference to the SHA1 object. 00379 * 00380 * Comments: 00381 * The character is assumed to hold 8 bits of information. 00382 * 00383 */ 00384 SHA1& SHA1::operator<<(const unsigned char message_element) 00385 { 00386 Input(&message_element, 1); 00387 00388 return *this; 00389 } 00390 00391 /* 00392 * ProcessMessageBlock 00393 * 00394 * Description: 00395 * This function will process the next 512 bits of the message 00396 * stored in the Message_Block array. 00397 * 00398 * Parameters: 00399 * None. 00400 * 00401 * Returns: 00402 * Nothing. 00403 * 00404 * Comments: 00405 * Many of the variable names in this function, especially the single 00406 * character names, were used because those were the names used 00407 * in the publication. 00408 * 00409 */ 00410 void SHA1::ProcessMessageBlock() 00411 { 00412 const unsigned K[] = { // Constants defined for SHA-1 00413 0x5A827999, 00414 0x6ED9EBA1, 00415 0x8F1BBCDC, 00416 0xCA62C1D6 00417 }; 00418 int t; // Loop counter 00419 unsigned temp; // Temporary word value 00420 unsigned W[80]; // Word sequence 00421 unsigned A, B, C, D, E; // Word buffers 00422 00423 /* 00424 * Initialize the first 16 words in the array W 00425 */ 00426 for(t = 0; t < 16; t++) 00427 { 00428 W[t] = ((unsigned) Message_Block[t * 4]) << 24; 00429 W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16; 00430 W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8; 00431 W[t] |= ((unsigned) Message_Block[t * 4 + 3]); 00432 } 00433 00434 for(t = 16; t < 80; t++) 00435 { 00436 W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00437 } 00438 00439 A = H[0]; 00440 B = H[1]; 00441 C = H[2]; 00442 D = H[3]; 00443 E = H[4]; 00444 00445 for(t = 0; t < 20; t++) 00446 { 00447 temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 00448 temp &= 0xFFFFFFFF; 00449 E = D; 00450 D = C; 00451 C = CircularShift(30,B); 00452 B = A; 00453 A = temp; 00454 } 00455 00456 for(t = 20; t < 40; t++) 00457 { 00458 temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 00459 temp &= 0xFFFFFFFF; 00460 E = D; 00461 D = C; 00462 C = CircularShift(30,B); 00463 B = A; 00464 A = temp; 00465 } 00466 00467 for(t = 40; t < 60; t++) 00468 { 00469 temp = CircularShift(5,A) + 00470 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 00471 temp &= 0xFFFFFFFF; 00472 E = D; 00473 D = C; 00474 C = CircularShift(30,B); 00475 B = A; 00476 A = temp; 00477 } 00478 00479 for(t = 60; t < 80; t++) 00480 { 00481 temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 00482 temp &= 0xFFFFFFFF; 00483 E = D; 00484 D = C; 00485 C = CircularShift(30,B); 00486 B = A; 00487 A = temp; 00488 } 00489 00490 H[0] = (H[0] + A) & 0xFFFFFFFF; 00491 H[1] = (H[1] + B) & 0xFFFFFFFF; 00492 H[2] = (H[2] + C) & 0xFFFFFFFF; 00493 H[3] = (H[3] + D) & 0xFFFFFFFF; 00494 H[4] = (H[4] + E) & 0xFFFFFFFF; 00495 00496 Message_Block_Index = 0; 00497 } 00498 00499 /* 00500 * PadMessage 00501 * 00502 * Description: 00503 * According to the standard, the message must be padded to an even 00504 * 512 bits. The first padding bit must be a '1'. The last 64 bits 00505 * represent the length of the original message. All bits in between 00506 * should be 0. This function will pad the message according to those 00507 * rules by filling the message_block array accordingly. It will also 00508 * call ProcessMessageBlock() appropriately. When it returns, it 00509 * can be assumed that the message digest has been computed. 00510 * 00511 * Parameters: 00512 * None. 00513 * 00514 * Returns: 00515 * Nothing. 00516 * 00517 * Comments: 00518 * 00519 */ 00520 void SHA1::PadMessage() 00521 { 00522 /* 00523 * Check to see if the current message block is too small to hold 00524 * the initial padding bits and length. If so, we will pad the 00525 * block, process it, and then continue padding into a second block. 00526 */ 00527 if (Message_Block_Index > 55) 00528 { 00529 Message_Block[Message_Block_Index++] = 0x80; 00530 while(Message_Block_Index < 64) 00531 { 00532 Message_Block[Message_Block_Index++] = 0; 00533 } 00534 00535 ProcessMessageBlock(); 00536 00537 while(Message_Block_Index < 56) 00538 { 00539 Message_Block[Message_Block_Index++] = 0; 00540 } 00541 } 00542 else 00543 { 00544 Message_Block[Message_Block_Index++] = 0x80; 00545 while(Message_Block_Index < 56) 00546 { 00547 Message_Block[Message_Block_Index++] = 0; 00548 } 00549 00550 } 00551 00552 /* 00553 * Store the message length as the last 8 octets 00554 */ 00555 Message_Block[56] = (Length_High >> 24) & 0xFF; 00556 Message_Block[57] = (Length_High >> 16) & 0xFF; 00557 Message_Block[58] = (Length_High >> 8) & 0xFF; 00558 Message_Block[59] = (Length_High) & 0xFF; 00559 Message_Block[60] = (Length_Low >> 24) & 0xFF; 00560 Message_Block[61] = (Length_Low >> 16) & 0xFF; 00561 Message_Block[62] = (Length_Low >> 8) & 0xFF; 00562 Message_Block[63] = (Length_Low) & 0xFF; 00563 00564 ProcessMessageBlock(); 00565 } 00566 00567 00568 /* 00569 * CircularShift 00570 * 00571 * Description: 00572 * This member function will perform a circular shifting operation. 00573 * 00574 * Parameters: 00575 * bits: [in] 00576 * The number of bits to shift (1-31) 00577 * word: [in] 00578 * The value to shift (assumes a 32-bit integer) 00579 * 00580 * Returns: 00581 * The shifted value. 00582 * 00583 * Comments: 00584 * 00585 */ 00586 unsigned SHA1::CircularShift(int bits, unsigned word) 00587 { 00588 return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits)); 00589 }