Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of GSwifi_old by
sha1.cpp
00001 /* 00002 * source from http://www.ipa.go.jp/security/rfc/RFC3174JA.html 00003 */ 00004 #include "sha1.h" 00005 00006 /* 00007 * Define the SHA1 circular left shift macro 00008 */ 00009 #define SHA1CircularShift(bits,word) \ 00010 (((word) << (bits)) | ((word) >> (32-(bits)))) 00011 00012 /* Local Function Prototyptes */ 00013 void SHA1PadMessage(SHA1Context *); 00014 void SHA1ProcessMessageBlock(SHA1Context *); 00015 00016 /* 00017 * SHA1Reset 00018 * 00019 * Description: 00020 * This function will initialize the SHA1Context in preparation 00021 * for computing a new SHA1 message digest. 00022 * 00023 * Parameters: 00024 * context: [in/out] 00025 * The context to reset. 00026 * 00027 * Returns: 00028 * sha Error Code. 00029 * 00030 */ 00031 int SHA1Reset(SHA1Context *context) 00032 { 00033 if (!context) 00034 { 00035 return shaNull; 00036 } 00037 00038 context->Length_Low = 0; 00039 context->Length_High = 0; 00040 context->Message_Block_Index = 0; 00041 00042 context->Intermediate_Hash[0] = 0x67452301; 00043 context->Intermediate_Hash[1] = 0xEFCDAB89; 00044 context->Intermediate_Hash[2] = 0x98BADCFE; 00045 context->Intermediate_Hash[3] = 0x10325476; 00046 context->Intermediate_Hash[4] = 0xC3D2E1F0; 00047 00048 context->Computed = 0; 00049 context->Corrupted = 0; 00050 00051 return shaSuccess; 00052 } 00053 00054 /* 00055 * SHA1Result 00056 * 00057 * Description: 00058 * This function will return the 160-bit message digest into the 00059 * Message_Digest array provided by the caller. 00060 * NOTE: The first octet of hash is stored in the 0th element, 00061 * the last octet of hash in the 19th element. 00062 * 00063 * Parameters: 00064 * context: [in/out] 00065 * The context to use to calculate the SHA-1 hash. 00066 * Message_Digest: [out] 00067 * Where the digest is returned. 00068 * 00069 * Returns: 00070 * sha Error Code. 00071 * 00072 */ 00073 int SHA1Result( SHA1Context *context, 00074 uint8_t Message_Digest[SHA1HashSize]) 00075 { 00076 int i; 00077 00078 if (!context || !Message_Digest) 00079 { 00080 return shaNull; 00081 } 00082 00083 if (context->Corrupted) 00084 { 00085 return context->Corrupted; 00086 } 00087 00088 if (!context->Computed) 00089 { 00090 SHA1PadMessage(context); 00091 for(i=0; i<64; ++i) 00092 { 00093 /* message may be sensitive, clear it out */ 00094 context->Message_Block[i] = 0; 00095 } 00096 context->Length_Low = 0; /* and clear length */ 00097 context->Length_High = 0; 00098 context->Computed = 1; 00099 } 00100 00101 for(i = 0; i < SHA1HashSize; ++i) 00102 { 00103 Message_Digest[i] = context->Intermediate_Hash[i>>2] 00104 >> 8 * ( 3 - ( i & 0x03 ) ); 00105 } 00106 00107 return shaSuccess; 00108 } 00109 00110 /* 00111 * SHA1Input 00112 * 00113 * Description: 00114 * This function accepts an array of octets as the next portion 00115 * of the message. 00116 * 00117 * Parameters: 00118 * context: [in/out] 00119 * The SHA context to update 00120 * message_array: [in] 00121 * An array of characters representing the next portion of 00122 * the message. 00123 * length: [in] 00124 * The length of the message in message_array 00125 * 00126 * Returns: 00127 * sha Error Code. 00128 * 00129 */ 00130 int SHA1Input( SHA1Context *context, 00131 const uint8_t *message_array, 00132 unsigned length) 00133 { 00134 if (!length) 00135 { 00136 return shaSuccess; 00137 } 00138 00139 if (!context || !message_array) 00140 { 00141 return shaNull; 00142 } 00143 00144 if (context->Computed) 00145 { 00146 context->Corrupted = shaStateError; 00147 return shaStateError; 00148 } 00149 00150 if (context->Corrupted) 00151 { 00152 return context->Corrupted; 00153 } 00154 while(length-- && !context->Corrupted) 00155 { 00156 context->Message_Block[context->Message_Block_Index++] = 00157 (*message_array & 0xFF); 00158 00159 context->Length_Low += 8; 00160 if (context->Length_Low == 0) 00161 { 00162 context->Length_High++; 00163 if (context->Length_High == 0) 00164 { 00165 /* Message is too long */ 00166 context->Corrupted = 1; 00167 } 00168 } 00169 00170 if (context->Message_Block_Index == 64) 00171 { 00172 SHA1ProcessMessageBlock(context); 00173 } 00174 00175 message_array++; 00176 } 00177 00178 return shaSuccess; 00179 } 00180 00181 /* 00182 * SHA1ProcessMessageBlock 00183 * 00184 * Description: 00185 * This function will process the next 512 bits of the message 00186 * stored in the Message_Block array. 00187 * 00188 * Parameters: 00189 * None. 00190 * 00191 * Returns: 00192 * Nothing. 00193 * 00194 * Comments: 00195 * Many of the variable names in this code, especially the 00196 * single character names, were used because those were the 00197 * names used in the publication. 00198 * 00199 * 00200 */ 00201 void SHA1ProcessMessageBlock(SHA1Context *context) 00202 { 00203 const uint32_t K[] = { /* Constants defined in SHA-1 */ 00204 0x5A827999, 00205 0x6ED9EBA1, 00206 0x8F1BBCDC, 00207 0xCA62C1D6 00208 }; 00209 int t; /* Loop counter */ 00210 uint32_t temp; /* Temporary word value */ 00211 uint32_t W[80]; /* Word sequence */ 00212 uint32_t A, B, C, D, E; /* Word buffers */ 00213 00214 /* 00215 * Initialize the first 16 words in the array W 00216 */ 00217 for(t = 0; t < 16; t++) 00218 { 00219 W[t] = context->Message_Block[t * 4] << 24; 00220 W[t] |= context->Message_Block[t * 4 + 1] << 16; 00221 W[t] |= context->Message_Block[t * 4 + 2] << 8; 00222 W[t] |= context->Message_Block[t * 4 + 3]; 00223 } 00224 00225 for(t = 16; t < 80; t++) 00226 { 00227 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00228 } 00229 00230 A = context->Intermediate_Hash[0]; 00231 B = context->Intermediate_Hash[1]; 00232 C = context->Intermediate_Hash[2]; 00233 D = context->Intermediate_Hash[3]; 00234 E = context->Intermediate_Hash[4]; 00235 00236 for(t = 0; t < 20; t++) 00237 { 00238 temp = SHA1CircularShift(5,A) + 00239 ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 00240 E = D; 00241 D = C; 00242 C = SHA1CircularShift(30,B); 00243 B = A; 00244 A = temp; 00245 } 00246 00247 for(t = 20; t < 40; t++) 00248 { 00249 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 00250 E = D; 00251 D = C; 00252 C = SHA1CircularShift(30,B); 00253 B = A; 00254 A = temp; 00255 } 00256 00257 for(t = 40; t < 60; t++) 00258 { 00259 temp = SHA1CircularShift(5,A) + 00260 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 00261 E = D; 00262 D = C; 00263 C = SHA1CircularShift(30,B); 00264 B = A; 00265 A = temp; 00266 } 00267 00268 for(t = 60; t < 80; t++) 00269 { 00270 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 00271 E = D; 00272 D = C; 00273 C = SHA1CircularShift(30,B); 00274 B = A; 00275 A = temp; 00276 } 00277 00278 context->Intermediate_Hash[0] += A; 00279 context->Intermediate_Hash[1] += B; 00280 context->Intermediate_Hash[2] += C; 00281 context->Intermediate_Hash[3] += D; 00282 context->Intermediate_Hash[4] += E; 00283 00284 context->Message_Block_Index = 0; 00285 } 00286 00287 00288 /* 00289 * SHA1PadMessage 00290 * 00291 * Description: 00292 * According to the standard, the message must be padded to an even 00293 * 512 bits. The first padding bit must be a '1'. The last 64 00294 * bits represent the length of the original message. All bits in 00295 * between should be 0. This function will pad the message 00296 * according to those rules by filling the Message_Block array 00297 * accordingly. It will also call the ProcessMessageBlock function 00298 * provided appropriately. When it returns, it can be assumed that 00299 * the message digest has been computed. 00300 * 00301 * Parameters: 00302 * context: [in/out] 00303 * The context to pad 00304 * ProcessMessageBlock: [in] 00305 * The appropriate SHA*ProcessMessageBlock function 00306 * Returns: 00307 * Nothing. 00308 * 00309 */ 00310 00311 void SHA1PadMessage(SHA1Context *context) 00312 { 00313 /* 00314 * Check to see if the current message block is too small to hold 00315 * the initial padding bits and length. If so, we will pad the 00316 * block, process it, and then continue padding into a second 00317 * block. 00318 */ 00319 if (context->Message_Block_Index > 55) 00320 { 00321 context->Message_Block[context->Message_Block_Index++] = 0x80; 00322 while(context->Message_Block_Index < 64) 00323 { 00324 context->Message_Block[context->Message_Block_Index++] = 0; 00325 } 00326 00327 SHA1ProcessMessageBlock(context); 00328 00329 while(context->Message_Block_Index < 56) 00330 { 00331 context->Message_Block[context->Message_Block_Index++] = 0; 00332 } 00333 } 00334 else 00335 { 00336 context->Message_Block[context->Message_Block_Index++] = 0x80; 00337 while(context->Message_Block_Index < 56) 00338 { 00339 context->Message_Block[context->Message_Block_Index++] = 0; 00340 } 00341 } 00342 00343 /* 00344 * Store the message length as the last 8 octets 00345 */ 00346 context->Message_Block[56] = context->Length_High >> 24; 00347 context->Message_Block[57] = context->Length_High >> 16; 00348 context->Message_Block[58] = context->Length_High >> 8; 00349 context->Message_Block[59] = context->Length_High; 00350 context->Message_Block[60] = context->Length_Low >> 24; 00351 context->Message_Block[61] = context->Length_Low >> 16; 00352 context->Message_Block[62] = context->Length_Low >> 8; 00353 context->Message_Block[63] = context->Length_Low; 00354 00355 SHA1ProcessMessageBlock(context); 00356 } 00357 00358 void sha1 (const char *input, int len, char *output) { 00359 SHA1Context sha; 00360 00361 SHA1Reset(&sha); 00362 SHA1Input(&sha, (unsigned char*)input, len); 00363 SHA1Result(&sha, (uint8_t*)output); 00364 }
Generated on Mon Jul 18 2022 14:21:01 by
