Fixed compatibility for HTTPClient Library. (HTTPClient by Donatien Garnier)
Dependents: FlashAir_Twitter CyaSSL-Twitter-OAuth4Tw TweetTest NetworkThermometer ... more
Fork of OAuth4Tw by
sha1.c
00001 /* 00002 * sha1.c 00003 * 00004 * Description: 00005 * This file implements the Secure Hashing Algorithm 1 as 00006 * defined in FIPS PUB 180-1 published April 17, 1995. 00007 * 00008 * The SHA-1, produces a 160-bit message digest for a given 00009 * data stream. It should take about 2**n steps to find a 00010 * message with the same digest as a given message and 00011 * 2**(n/2) to find any two messages with the same digest, 00012 * when n is the digest size in bits. Therefore, this 00013 * algorithm can serve as a means of providing a 00014 * "fingerprint" for a message. 00015 * 00016 * Portability Issues: 00017 * SHA-1 is defined in terms of 32-bit "words". This code 00018 * uses <stdint.h> (included via "sha1.h" to define 32 and 8 00019 * bit unsigned integer types. If your C compiler does not 00020 * support 32 bit unsigned integers, this code is not 00021 * appropriate. 00022 * 00023 * Caveats: 00024 * SHA-1 is designed to work with messages less than 2^64 bits 00025 * long. Although SHA-1 allows a message digest to be generated 00026 * for messages of any number of bits less than 2^64, this 00027 * implementation only works with messages with a length that is 00028 * a multiple of the size of an 8-bit character. 00029 * 00030 */ 00031 00032 #include "sha1.h" 00033 00034 //#pragma warning(disable:4244) 00035 00036 /* 00037 * Define the SHA1 circular left shift macro 00038 */ 00039 #define SHA1CircularShift(bits,word) \ 00040 (((word) << (bits)) | ((word) >> (32-(bits)))) 00041 00042 /* Local Function Prototyptes */ 00043 void SHA1PadMessage(SHA1Context *); 00044 void SHA1ProcessMessageBlock(SHA1Context *); 00045 00046 /* 00047 * SHA1Reset 00048 * 00049 * Description: 00050 * This function will initialize the SHA1Context in preparation 00051 * for computing a new SHA1 message digest. 00052 * 00053 * Parameters: 00054 * context: [in/out] 00055 * The context to reset. 00056 * 00057 * Returns: 00058 * sha Error Code. 00059 * 00060 */ 00061 int SHA1Reset(SHA1Context *context) 00062 { 00063 if (!context) 00064 { 00065 return shaNull; 00066 } 00067 00068 context->Length_Low = 0; 00069 context->Length_High = 0; 00070 context->Message_Block_Index = 0; 00071 00072 context->Intermediate_Hash[0] = 0x67452301; 00073 context->Intermediate_Hash[1] = 0xEFCDAB89; 00074 context->Intermediate_Hash[2] = 0x98BADCFE; 00075 context->Intermediate_Hash[3] = 0x10325476; 00076 context->Intermediate_Hash[4] = 0xC3D2E1F0; 00077 00078 context->Computed = 0; 00079 context->Corrupted = 0; 00080 00081 return shaSuccess; 00082 } 00083 00084 /* 00085 * SHA1Result 00086 * 00087 * Description: 00088 * This function will return the 160-bit message digest into the 00089 * Message_Digest array provided by the caller. 00090 * NOTE: The first octet of hash is stored in the 0th element, 00091 * the last octet of hash in the 19th element. 00092 * 00093 * Parameters: 00094 * context: [in/out] 00095 * The context to use to calculate the SHA-1 hash. 00096 * Message_Digest: [out] 00097 * Where the digest is returned. 00098 * 00099 * Returns: 00100 * sha Error Code. 00101 * 00102 */ 00103 int SHA1Result( SHA1Context *context, 00104 uint8_t Message_Digest[SHA1HashSize]) 00105 { 00106 int i; 00107 00108 if (!context || !Message_Digest) 00109 { 00110 return shaNull; 00111 } 00112 00113 if (context->Corrupted) 00114 { 00115 return context->Corrupted; 00116 } 00117 00118 if (!context->Computed) 00119 { 00120 SHA1PadMessage(context); 00121 for(i=0; i<64; ++i) 00122 { 00123 /* message may be sensitive, clear it out */ 00124 context->Message_Block[i] = 0; 00125 } 00126 context->Length_Low = 0; /* and clear length */ 00127 context->Length_High = 0; 00128 context->Computed = 1; 00129 } 00130 00131 for(i = 0; i < SHA1HashSize; ++i) 00132 { 00133 Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); 00134 } 00135 00136 return shaSuccess; 00137 } 00138 00139 /* 00140 * SHA1Input 00141 * 00142 * Description: 00143 * This function accepts an array of octets as the next portion 00144 * of the message. 00145 * 00146 * Parameters: 00147 * context: [in/out] 00148 * The SHA context to update 00149 * message_array: [in] 00150 * An array of characters representing the next portion of 00151 * the message. 00152 * length: [in] 00153 * The length of the message in message_array 00154 * 00155 * Returns: 00156 * sha Error Code. 00157 * 00158 */ 00159 int SHA1Input( SHA1Context *context, 00160 const uint8_t *message_array, 00161 unsigned length) 00162 { 00163 if (!length) 00164 { 00165 return shaSuccess; 00166 } 00167 00168 if (!context || !message_array) 00169 { 00170 return shaNull; 00171 } 00172 00173 if (context->Computed) 00174 { 00175 context->Corrupted = shaStateError; 00176 return shaStateError; 00177 } 00178 00179 if (context->Corrupted) 00180 { 00181 return context->Corrupted; 00182 } 00183 while(length-- && !context->Corrupted) 00184 { 00185 context->Message_Block[context->Message_Block_Index++] = 00186 (*message_array & 0xFF); 00187 00188 context->Length_Low += 8; 00189 if (context->Length_Low == 0) 00190 { 00191 context->Length_High++; 00192 if (context->Length_High == 0) 00193 { 00194 /* Message is too long */ 00195 context->Corrupted = 1; 00196 } 00197 } 00198 00199 if (context->Message_Block_Index == 64) 00200 { 00201 SHA1ProcessMessageBlock(context); 00202 } 00203 00204 message_array++; 00205 } 00206 00207 return shaSuccess; 00208 } 00209 00210 /* 00211 * SHA1ProcessMessageBlock 00212 * 00213 * Description: 00214 * This function will process the next 512 bits of the message 00215 * stored in the Message_Block array. 00216 * 00217 * Parameters: 00218 * None. 00219 * 00220 * Returns: 00221 * Nothing. 00222 * 00223 * Comments: 00224 * Many of the variable names in this code, especially the 00225 * single character names, were used because those were the 00226 * names used in the publication. 00227 * 00228 * 00229 */ 00230 void SHA1ProcessMessageBlock(SHA1Context *context) 00231 { 00232 const uint32_t K[] = { /* Constants defined in SHA-1 */ 00233 0x5A827999, 00234 0x6ED9EBA1, 00235 0x8F1BBCDC, 00236 0xCA62C1D6 00237 }; 00238 int t; /* Loop counter */ 00239 uint32_t temp; /* Temporary word value */ 00240 uint32_t W[80]; /* Word sequence */ 00241 uint32_t A, B, C, D, E; /* Word buffers */ 00242 00243 /* 00244 * Initialize the first 16 words in the array W 00245 */ 00246 for(t = 0; t < 16; t++) 00247 { 00248 W[t] = context->Message_Block[t * 4] << 24; 00249 W[t] |= context->Message_Block[t * 4 + 1] << 16; 00250 W[t] |= context->Message_Block[t * 4 + 2] << 8; 00251 W[t] |= context->Message_Block[t * 4 + 3]; 00252 } 00253 00254 for(t = 16; t < 80; t++) 00255 { 00256 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00257 } 00258 00259 A = context->Intermediate_Hash[0]; 00260 B = context->Intermediate_Hash[1]; 00261 C = context->Intermediate_Hash[2]; 00262 D = context->Intermediate_Hash[3]; 00263 E = context->Intermediate_Hash[4]; 00264 00265 for(t = 0; t < 20; t++) 00266 { 00267 temp = SHA1CircularShift(5,A) + 00268 ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 00269 E = D; 00270 D = C; 00271 C = SHA1CircularShift(30,B); 00272 B = A; 00273 A = temp; 00274 } 00275 00276 for(t = 20; t < 40; t++) 00277 { 00278 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 00279 E = D; 00280 D = C; 00281 C = SHA1CircularShift(30,B); 00282 B = A; 00283 A = temp; 00284 } 00285 00286 for(t = 40; t < 60; t++) 00287 { 00288 temp = SHA1CircularShift(5,A) + 00289 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 00290 E = D; 00291 D = C; 00292 C = SHA1CircularShift(30,B); 00293 B = A; 00294 A = temp; 00295 } 00296 00297 for(t = 60; t < 80; t++) 00298 { 00299 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 00300 E = D; 00301 D = C; 00302 C = SHA1CircularShift(30,B); 00303 B = A; 00304 A = temp; 00305 } 00306 00307 context->Intermediate_Hash[0] += A; 00308 context->Intermediate_Hash[1] += B; 00309 context->Intermediate_Hash[2] += C; 00310 context->Intermediate_Hash[3] += D; 00311 context->Intermediate_Hash[4] += E; 00312 00313 context->Message_Block_Index = 0; 00314 } 00315 00316 00317 /* 00318 * SHA1PadMessage 00319 * 00320 * Description: 00321 * According to the standard, the message must be padded to an even 00322 * 512 bits. The first padding bit must be a '1'. The last 64 00323 * bits represent the length of the original message. All bits in 00324 * between should be 0. This function will pad the message 00325 * according to those rules by filling the Message_Block array 00326 * accordingly. It will also call the ProcessMessageBlock function 00327 * provided appropriately. When it returns, it can be assumed that 00328 * the message digest has been computed. 00329 * 00330 * Parameters: 00331 * context: [in/out] 00332 * The context to pad 00333 * ProcessMessageBlock: [in] 00334 * The appropriate SHA*ProcessMessageBlock function 00335 * Returns: 00336 * Nothing. 00337 * 00338 */ 00339 00340 void SHA1PadMessage(SHA1Context *context) 00341 { 00342 /* 00343 * Check to see if the current message block is too small to hold 00344 * the initial padding bits and length. If so, we will pad the 00345 * block, process it, and then continue padding into a second 00346 * block. 00347 */ 00348 if (context->Message_Block_Index > 55) 00349 { 00350 context->Message_Block[context->Message_Block_Index++] = 0x80; 00351 while(context->Message_Block_Index < 64) 00352 { 00353 context->Message_Block[context->Message_Block_Index++] = 0; 00354 } 00355 00356 SHA1ProcessMessageBlock(context); 00357 00358 while(context->Message_Block_Index < 56) 00359 { 00360 context->Message_Block[context->Message_Block_Index++] = 0; 00361 } 00362 } 00363 else 00364 { 00365 context->Message_Block[context->Message_Block_Index++] = 0x80; 00366 while(context->Message_Block_Index < 56) 00367 { 00368 context->Message_Block[context->Message_Block_Index++] = 0; 00369 } 00370 } 00371 00372 /* 00373 * Store the message length as the last 8 octets 00374 */ 00375 context->Message_Block[56] = context->Length_High >> 24; 00376 context->Message_Block[57] = context->Length_High >> 16; 00377 context->Message_Block[58] = context->Length_High >> 8; 00378 context->Message_Block[59] = context->Length_High; 00379 context->Message_Block[60] = context->Length_Low >> 24; 00380 context->Message_Block[61] = context->Length_Low >> 16; 00381 context->Message_Block[62] = context->Length_Low >> 8; 00382 context->Message_Block[63] = context->Length_Low; 00383 00384 SHA1ProcessMessageBlock(context); 00385 } 00386
Generated on Thu Jul 14 2022 04:27:06 by
![doxygen](doxygen.png)