COOPY » Guide
version 0.6.5
|
00001 00002 // Duplicated from fossil, see ../ssfossil/fossil 00003 00004 /* 00005 ** This implementation of SHA1 is adapted from the example implementation 00006 ** contained in RFC-3174. 00007 */ 00008 /* 00009 * If you do not have the ISO standard stdint.h header file, then you 00010 * must typdef the following: 00011 * name meaning 00012 * */ 00013 #if defined(__DMC__) || defined(_MSC_VER) 00014 typedef unsigned long uint32_t; //unsigned 32 bit integer 00015 typedef unsigned char uint8_t; //unsigned 8 bit integer (i.e., unsigned char) 00016 #else 00017 # include <stdint.h> 00018 #endif 00019 #include <sys/types.h> 00020 //#include "config.h" 00021 #include <coopy/Sha1Generator.h> 00022 #include <string.h> 00023 00024 #define SHA1HashSize 20 00025 #define shaSuccess 0 00026 #define shaInputTooLong 1 00027 #define shaStateError 2 00028 00029 /* 00030 * This structure will hold context information for the SHA-1 00031 * hashing operation 00032 */ 00033 typedef struct SHA1Context SHA1Context; 00034 struct SHA1Context { 00035 uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ 00036 00037 uint32_t Length_Low; /* Message length in bits */ 00038 uint32_t Length_High; /* Message length in bits */ 00039 00040 int Message_Block_Index; /* Index into message block array */ 00041 uint8_t Message_Block[64]; /* 512-bit message blocks */ 00042 00043 int Computed; /* Is the digest computed? */ 00044 int Corrupted; /* Is the message digest corrupted? */ 00045 }; 00046 00047 /* 00048 * sha1.c 00049 * 00050 * Description: 00051 * This file implements the Secure Hashing Algorithm 1 as 00052 * defined in FIPS PUB 180-1 published April 17, 1995. 00053 * 00054 * The SHA-1, produces a 160-bit message digest for a given 00055 * data stream. It should take about 2**n steps to find a 00056 * message with the same digest as a given message and 00057 * 2**(n/2) to find any two messages with the same digest, 00058 * when n is the digest size in bits. Therefore, this 00059 * algorithm can serve as a means of providing a 00060 * "fingerprint" for a message. 00061 * 00062 * Portability Issues: 00063 * SHA-1 is defined in terms of 32-bit "words". This code 00064 * uses <stdint.h> (included via "sha1.h" to define 32 and 8 00065 * bit unsigned integer types. If your C compiler does not 00066 * support 32 bit unsigned integers, this code is not 00067 * appropriate. 00068 * 00069 * Caveats: 00070 * SHA-1 is designed to work with messages less than 2^64 bits 00071 * long. Although SHA-1 allows a message digest to be generated 00072 * for messages of any number of bits less than 2^64, this 00073 * implementation only works with messages with a length that is 00074 * a multiple of the size of an 8-bit character. 00075 * 00076 */ 00077 00078 /* 00079 * Define the SHA1 circular left shift macro 00080 */ 00081 #define SHA1CircularShift(bits,word) \ 00082 (((word) << (bits)) | ((word) >> (32-(bits)))) 00083 00084 /* Local Function Prototyptes */ 00085 static void SHA1PadMessage(SHA1Context *); 00086 static void SHA1ProcessMessageBlock(SHA1Context *); 00087 00088 /* 00089 * SHA1Reset 00090 * 00091 * Description: 00092 * This function will initialize the SHA1Context in preparation 00093 * for computing a new SHA1 message digest. 00094 * 00095 * Parameters: 00096 * context: [in/out] 00097 * The context to reset. 00098 * 00099 * Returns: 00100 * sha Error Code. 00101 * 00102 */ 00103 static int SHA1Reset(SHA1Context *context) 00104 { 00105 context->Length_Low = 0; 00106 context->Length_High = 0; 00107 context->Message_Block_Index = 0; 00108 00109 context->Intermediate_Hash[0] = 0x67452301; 00110 context->Intermediate_Hash[1] = 0xEFCDAB89; 00111 context->Intermediate_Hash[2] = 0x98BADCFE; 00112 context->Intermediate_Hash[3] = 0x10325476; 00113 context->Intermediate_Hash[4] = 0xC3D2E1F0; 00114 00115 context->Computed = 0; 00116 context->Corrupted = 0; 00117 00118 return shaSuccess; 00119 } 00120 00121 /* 00122 * SHA1Result 00123 * 00124 * Description: 00125 * This function will return the 160-bit message digest into the 00126 * Message_Digest array provided by the caller. 00127 * NOTE: The first octet of hash is stored in the 0th element, 00128 * the last octet of hash in the 19th element. 00129 * 00130 * Parameters: 00131 * context: [in/out] 00132 * The context to use to calculate the SHA-1 hash. 00133 * Message_Digest: [out] 00134 * Where the digest is returned. 00135 * 00136 * Returns: 00137 * sha Error Code. 00138 * 00139 */ 00140 static int SHA1Result( SHA1Context *context, 00141 uint8_t Message_Digest[SHA1HashSize]) 00142 { 00143 int i; 00144 00145 if (context->Corrupted) 00146 { 00147 return context->Corrupted; 00148 } 00149 00150 if (!context->Computed) 00151 { 00152 SHA1PadMessage(context); 00153 for(i=0; i<64; ++i) 00154 { 00155 /* message may be sensitive, clear it out */ 00156 context->Message_Block[i] = 0; 00157 } 00158 context->Length_Low = 0; /* and clear length */ 00159 context->Length_High = 0; 00160 context->Computed = 1; 00161 00162 } 00163 00164 for(i = 0; i < SHA1HashSize; ++i) 00165 { 00166 Message_Digest[i] = context->Intermediate_Hash[i>>2] 00167 >> 8 * ( 3 - ( i & 0x03 ) ); 00168 } 00169 00170 return shaSuccess; 00171 } 00172 00173 /* 00174 * SHA1Input 00175 * 00176 * Description: 00177 * This function accepts an array of octets as the next portion 00178 * of the message. 00179 * 00180 * Parameters: 00181 * context: [in/out] 00182 * The SHA context to update 00183 * message_array: [in] 00184 * An array of characters representing the next portion of 00185 * the message. 00186 * length: [in] 00187 * The length of the message in message_array 00188 * 00189 * Returns: 00190 * sha Error Code. 00191 * 00192 */ 00193 static 00194 int SHA1Input( SHA1Context *context, 00195 const uint8_t *message_array, 00196 unsigned length) 00197 { 00198 if (!length) 00199 { 00200 return shaSuccess; 00201 } 00202 00203 if (context->Computed) 00204 { 00205 context->Corrupted = shaStateError; 00206 00207 return shaStateError; 00208 } 00209 00210 if (context->Corrupted) 00211 { 00212 return context->Corrupted; 00213 } 00214 while(length-- && !context->Corrupted) 00215 { 00216 context->Message_Block[context->Message_Block_Index++] = 00217 (*message_array & 0xFF); 00218 00219 context->Length_Low += 8; 00220 if (context->Length_Low == 0) 00221 { 00222 context->Length_High++; 00223 if (context->Length_High == 0) 00224 { 00225 /* Message is too long */ 00226 context->Corrupted = 1; 00227 } 00228 } 00229 00230 if (context->Message_Block_Index == 64) 00231 { 00232 SHA1ProcessMessageBlock(context); 00233 } 00234 00235 message_array++; 00236 } 00237 00238 return shaSuccess; 00239 } 00240 00241 /* 00242 * SHA1ProcessMessageBlock 00243 * 00244 * Description: 00245 * This function will process the next 512 bits of the message 00246 * stored in the Message_Block array. 00247 * 00248 * Parameters: 00249 * None. 00250 * 00251 * Returns: 00252 * Nothing. 00253 * 00254 * Comments: 00255 * Many of the variable names in this code, especially the 00256 * single character names, were used because those were the 00257 * names used in the publication. 00258 * 00259 * 00260 */ 00261 static void SHA1ProcessMessageBlock(SHA1Context *context) 00262 { 00263 const uint32_t K[] = { /* Constants defined in SHA-1 */ 00264 0x5A827999, 00265 0x6ED9EBA1, 00266 0x8F1BBCDC, 00267 0xCA62C1D6 00268 }; 00269 int t; /* Loop counter */ 00270 uint32_t temp; /* Temporary word value */ 00271 uint32_t W[80]; /* Word sequence */ 00272 uint32_t A, B, C, D, E; /* Word buffers */ 00273 00274 /* 00275 * Initialize the first 16 words in the array W 00276 */ 00277 for(t = 0; t < 16; t++) 00278 { 00279 W[t] = context->Message_Block[t * 4] << 24; 00280 W[t] |= context->Message_Block[t * 4 + 1] << 16; 00281 W[t] |= context->Message_Block[t * 4 + 2] << 8; 00282 W[t] |= context->Message_Block[t * 4 + 3]; 00283 } 00284 00285 for(t = 16; t < 80; t++) 00286 { 00287 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00288 } 00289 00290 A = context->Intermediate_Hash[0]; 00291 B = context->Intermediate_Hash[1]; 00292 C = context->Intermediate_Hash[2]; 00293 D = context->Intermediate_Hash[3]; 00294 E = context->Intermediate_Hash[4]; 00295 00296 for(t = 0; t < 20; t++) 00297 { 00298 temp = SHA1CircularShift(5,A) + 00299 ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 00300 E = D; 00301 D = C; 00302 C = SHA1CircularShift(30,B); 00303 00304 B = A; 00305 A = temp; 00306 } 00307 00308 for(t = 20; t < 40; t++) 00309 { 00310 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 00311 E = D; 00312 D = C; 00313 C = SHA1CircularShift(30,B); 00314 B = A; 00315 A = temp; 00316 } 00317 00318 for(t = 40; t < 60; t++) 00319 { 00320 temp = SHA1CircularShift(5,A) + 00321 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 00322 E = D; 00323 D = C; 00324 C = SHA1CircularShift(30,B); 00325 B = A; 00326 A = temp; 00327 } 00328 00329 for(t = 60; t < 80; t++) 00330 { 00331 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 00332 E = D; 00333 D = C; 00334 C = SHA1CircularShift(30,B); 00335 B = A; 00336 A = temp; 00337 } 00338 00339 context->Intermediate_Hash[0] += A; 00340 context->Intermediate_Hash[1] += B; 00341 context->Intermediate_Hash[2] += C; 00342 context->Intermediate_Hash[3] += D; 00343 context->Intermediate_Hash[4] += E; 00344 00345 context->Message_Block_Index = 0; 00346 } 00347 00348 /* 00349 * SHA1PadMessage 00350 * 00351 00352 * Description: 00353 * According to the standard, the message must be padded to an even 00354 * 512 bits. The first padding bit must be a '1'. The last 64 00355 * bits represent the length of the original message. All bits in 00356 * between should be 0. This function will pad the message 00357 * according to those rules by filling the Message_Block array 00358 * accordingly. It will also call the ProcessMessageBlock function 00359 * provided appropriately. When it returns, it can be assumed that 00360 * the message digest has been computed. 00361 * 00362 * Parameters: 00363 * context: [in/out] 00364 * The context to pad 00365 * ProcessMessageBlock: [in] 00366 * The appropriate SHA*ProcessMessageBlock function 00367 * Returns: 00368 * Nothing. 00369 * 00370 */ 00371 static void SHA1PadMessage(SHA1Context *context) 00372 { 00373 /* 00374 * Check to see if the current message block is too small to hold 00375 * the initial padding bits and length. If so, we will pad the 00376 * block, process it, and then continue padding into a second 00377 * block. 00378 */ 00379 if (context->Message_Block_Index > 55) 00380 { 00381 context->Message_Block[context->Message_Block_Index++] = 0x80; 00382 while(context->Message_Block_Index < 64) 00383 { 00384 context->Message_Block[context->Message_Block_Index++] = 0; 00385 } 00386 00387 SHA1ProcessMessageBlock(context); 00388 00389 while(context->Message_Block_Index < 56) 00390 { 00391 context->Message_Block[context->Message_Block_Index++] = 0; 00392 } 00393 } 00394 else 00395 { 00396 context->Message_Block[context->Message_Block_Index++] = 0x80; 00397 while(context->Message_Block_Index < 56) 00398 { 00399 00400 context->Message_Block[context->Message_Block_Index++] = 0; 00401 } 00402 } 00403 00404 /* 00405 * Store the message length as the last 8 octets 00406 */ 00407 context->Message_Block[56] = context->Length_High >> 24; 00408 context->Message_Block[57] = context->Length_High >> 16; 00409 context->Message_Block[58] = context->Length_High >> 8; 00410 context->Message_Block[59] = context->Length_High; 00411 context->Message_Block[60] = context->Length_Low >> 24; 00412 context->Message_Block[61] = context->Length_Low >> 16; 00413 context->Message_Block[62] = context->Length_Low >> 8; 00414 context->Message_Block[63] = context->Length_Low; 00415 00416 SHA1ProcessMessageBlock(context); 00417 } 00418 00419 00420 /* 00421 ** Convert a digest into base-16. digest should be declared as 00422 ** "unsigned char digest[20]" in the calling function. The SHA1 00423 ** digest is stored in the first 20 bytes. zBuf should 00424 ** be "char zBuf[41]". 00425 */ 00426 static void DigestToBase16(unsigned char *digest, char *zBuf){ 00427 static char const zEncode[] = "0123456789abcdef"; 00428 int i, j; 00429 00430 for(j=i=0; i<20; i++){ 00431 int a = digest[i]; 00432 zBuf[j++] = zEncode[(a>>4)&0xf]; 00433 zBuf[j++] = zEncode[a & 0xf]; 00434 } 00435 zBuf[j] = 0; 00436 } 00437 00438 /* 00439 ** The state of a incremental SHA1 checksum computation. Only one 00440 ** such computation can be underway at a time, of course. 00441 */ 00442 static SHA1Context incrCtx; 00443 static int incrInit = 0; 00444 00445 static int hashLen = 0; 00446 00447 /* 00448 ** Add more text to the incremental SHA1 checksum. 00449 */ 00450 void sha1sum_step_text(const char *zText, int nBytes){ 00451 if( !incrInit ){ 00452 SHA1Reset(&incrCtx); 00453 incrInit = 1; 00454 } 00455 if( nBytes<=0 ){ 00456 if( nBytes==0 ) return; 00457 nBytes = strlen(zText); 00458 } 00459 hashLen += nBytes; 00460 SHA1Input(&incrCtx, (unsigned char*)zText, nBytes); 00461 } 00462 00463 /* 00464 ** Finish the incremental SHA1 checksum. Store the result in blob pOut 00465 ** if pOut!=0. Also return a pointer to the result. 00466 ** 00467 ** This resets the incremental checksum preparing for the next round 00468 ** of computation. The return pointer points to a static buffer that 00469 ** is overwritten by subsequent calls to this function. 00470 */ 00471 char *sha1sum_finish(){ 00472 unsigned char zResult[20]; 00473 static char zOut[41]; 00474 sha1sum_step_text(0,0); 00475 SHA1Result(&incrCtx, zResult); 00476 incrInit = 0; 00477 DigestToBase16(zResult, zOut); 00478 if (hashLen!=0) { 00479 //printf("Length %d\n", hashLen); 00480 } 00481 hashLen = 0; 00482 return zOut; 00483 } 00484