libmoost
|
00001 /**************************** sha1.c ***************************/ 00002 /***************** See RFC 6234 for details. *******************/ 00003 /* Copyright (c) 2011 IETF Trust and the persons identified as */ 00004 /* authors of the code. All rights reserved. */ 00005 /* See sha.h for terms of use and redistribution. */ 00006 00007 /* 00008 * Description: 00009 * This file implements the Secure Hash Algorithm SHA-1 00010 * as defined in the U.S. National Institute of Standards 00011 * and Technology Federal Information Processing Standards 00012 * Publication (FIPS PUB) 180-3 published in October 2008 00013 * and formerly defined in its predecessors, FIPS PUB 180-1 00014 * and FIP PUB 180-2. 00015 * 00016 * A combined document showing all algorithms is available at 00017 * http://csrc.nist.gov/publications/fips/ 00018 * fips180-3/fips180-3_final.pdf 00019 * 00020 * The SHA-1 algorithm produces a 160-bit message digest for a 00021 * given data stream that can serve as a means of providing a 00022 * "fingerprint" for a message. 00023 * 00024 * Portability Issues: 00025 * SHA-1 is defined in terms of 32-bit "words". This code 00026 * uses <stdint.h> (included via "sha.h") to define 32- and 00027 * 8-bit unsigned integer types. If your C compiler does 00028 * not support 32-bit unsigned integers, this code is not 00029 * appropriate. 00030 * 00031 * Caveats: 00032 * SHA-1 is designed to work with messages less than 2^64 bits 00033 * long. This implementation uses SHA1Input() to hash the bits 00034 * that are a multiple of the size of an 8-bit octet, and then 00035 * optionally uses SHA1FinalBits() to hash the final few bits of 00036 * the input. 00037 */ 00038 00039 #include "sha.h" 00040 #include "sha-private.h" 00041 00042 /* 00043 * Define the SHA1 circular left shift macro 00044 */ 00045 #define SHA1_ROTL(bits,word) \ 00046 (((word) << (bits)) | ((word) >> (32-(bits)))) 00047 00048 /* 00049 * Add "length" to the length. 00050 * Set Corrupted when overflow has occurred. 00051 */ 00052 static uint32_t addTemp; 00053 #define SHA1AddLength(context, length) \ 00054 (addTemp = (context)->Length_Low, \ 00055 (context)->Corrupted = \ 00056 (((context)->Length_Low += (length)) < addTemp) && \ 00057 (++(context)->Length_High == 0) ? shaInputTooLong \ 00058 : (context)->Corrupted ) 00059 00060 /* Local Function Prototypes */ 00061 static void SHA1ProcessMessageBlock(SHA1Context *context); 00062 static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte); 00063 static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte); 00064 00065 /* 00066 * SHA1Reset 00067 * 00068 * Description: 00069 * This function will initialize the SHA1Context in preparation 00070 * for computing a new SHA1 message digest. 00071 * 00072 * Parameters: 00073 * context: [in/out] 00074 * The context to reset. 00075 * 00076 * Returns: 00077 * sha Error Code. 00078 * 00079 */ 00080 int SHA1Reset(SHA1Context *context) 00081 { 00082 if (!context) return shaNull; 00083 00084 context->Length_High = context->Length_Low = 0; 00085 context->Message_Block_Index = 0; 00086 00087 /* Initial Hash Values: FIPS 180-3 section 5.3.1 */ 00088 context->Intermediate_Hash[0] = 0x67452301; 00089 context->Intermediate_Hash[1] = 0xEFCDAB89; 00090 context->Intermediate_Hash[2] = 0x98BADCFE; 00091 context->Intermediate_Hash[3] = 0x10325476; 00092 context->Intermediate_Hash[4] = 0xC3D2E1F0; 00093 00094 context->Computed = 0; 00095 context->Corrupted = shaSuccess; 00096 00097 return shaSuccess; 00098 } 00099 00100 /* 00101 * SHA1Input 00102 * 00103 * Description: 00104 * This function accepts an array of octets as the next portion 00105 * of the message. 00106 * 00107 * Parameters: 00108 * context: [in/out] 00109 * The SHA context to update. 00110 * message_array[ ]: [in] 00111 * An array of octets representing the next portion of 00112 * the message. 00113 * length: [in] 00114 * The length of the message in message_array. 00115 * 00116 * Returns: 00117 * sha Error Code. 00118 * 00119 */ 00120 int SHA1Input(SHA1Context *context, 00121 const uint8_t *message_array, unsigned length) 00122 { 00123 if (!context) return shaNull; 00124 if (!length) return shaSuccess; 00125 if (!message_array) return shaNull; 00126 if (context->Computed) return context->Corrupted = shaStateError; 00127 if (context->Corrupted) return context->Corrupted; 00128 00129 while (length--) { 00130 context->Message_Block[context->Message_Block_Index++] = 00131 *message_array; 00132 00133 if ((SHA1AddLength(context, 8) == shaSuccess) && 00134 (context->Message_Block_Index == SHA1_Message_Block_Size)) 00135 SHA1ProcessMessageBlock(context); 00136 00137 message_array++; 00138 } 00139 00140 return context->Corrupted; 00141 } 00142 00143 /* 00144 * SHA1FinalBits 00145 * 00146 * Description: 00147 * This function will add in any final bits of the message. 00148 * 00149 * Parameters: 00150 * context: [in/out] 00151 * The SHA context to update. 00152 * message_bits: [in] 00153 * The final bits of the message, in the upper portion of the 00154 * byte. (Use 0b###00000 instead of 0b00000### to input the 00155 * three bits ###.) 00156 * length: [in] 00157 * The number of bits in message_bits, between 1 and 7. 00158 * 00159 * Returns: 00160 * sha Error Code. 00161 */ 00162 int SHA1FinalBits(SHA1Context *context, uint8_t message_bits, 00163 unsigned int length) 00164 { 00165 static uint8_t masks[8] = { 00166 /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, 00167 /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, 00168 /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, 00169 /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE 00170 }; 00171 00172 static uint8_t markbit[8] = { 00173 /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, 00174 /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, 00175 /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, 00176 /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 00177 }; 00178 00179 if (!context) return shaNull; 00180 if (!length) return shaSuccess; 00181 if (context->Corrupted) return context->Corrupted; 00182 if (context->Computed) return context->Corrupted = shaStateError; 00183 if (length >= 8) return context->Corrupted = shaBadParam; 00184 00185 SHA1AddLength(context, length); 00186 SHA1Finalize(context, 00187 (uint8_t) ((message_bits & masks[length]) | markbit[length])); 00188 00189 return context->Corrupted; 00190 } 00191 00192 /* 00193 * SHA1Result 00194 * 00195 * Description: 00196 * This function will return the 160-bit message digest 00197 * into the Message_Digest array provided by the caller. 00198 * NOTE: 00199 * The first octet of hash is stored in the element with index 0, 00200 * the last octet of hash in the element with index 19. 00201 * 00202 * Parameters: 00203 * context: [in/out] 00204 * The context to use to calculate the SHA-1 hash. 00205 * Message_Digest[ ]: [out] 00206 * Where the digest is returned. 00207 * 00208 * Returns: 00209 * sha Error Code. 00210 * 00211 */ 00212 int SHA1Result(SHA1Context *context, 00213 uint8_t Message_Digest[SHA1HashSize]) 00214 { 00215 int i; 00216 00217 if (!context) return shaNull; 00218 if (!Message_Digest) return shaNull; 00219 if (context->Corrupted) return context->Corrupted; 00220 00221 if (!context->Computed) 00222 SHA1Finalize(context, 0x80); 00223 00224 for (i = 0; i < SHA1HashSize; ++i) 00225 Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2] 00226 >> (8 * ( 3 - ( i & 0x03 ) ))); 00227 00228 return shaSuccess; 00229 } 00230 00231 /* 00232 * SHA1ProcessMessageBlock 00233 * 00234 * Description: 00235 * This helper function will process the next 512 bits of the 00236 * message stored in the Message_Block array. 00237 * 00238 * Parameters: 00239 * context: [in/out] 00240 * The SHA context to update. 00241 * 00242 * Returns: 00243 * Nothing. 00244 * 00245 * Comments: 00246 * Many of the variable names in this code, especially the 00247 * single character names, were used because those were the 00248 * names used in the Secure Hash Standard. 00249 */ 00250 static void SHA1ProcessMessageBlock(SHA1Context *context) 00251 { 00252 /* Constants defined in FIPS 180-3, section 4.2.1 */ 00253 const uint32_t K[4] = { 00254 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 00255 }; 00256 int t; /* Loop counter */ 00257 uint32_t temp; /* Temporary word value */ 00258 uint32_t W[80]; /* Word sequence */ 00259 uint32_t A, B, C, D, E; /* Word buffers */ 00260 00261 /* 00262 * Initialize the first 16 words in the array W 00263 */ 00264 for (t = 0; t < 16; t++) { 00265 W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24; 00266 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16; 00267 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8; 00268 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]); 00269 } 00270 00271 for (t = 16; t < 80; t++) 00272 W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00273 00274 A = context->Intermediate_Hash[0]; 00275 B = context->Intermediate_Hash[1]; 00276 C = context->Intermediate_Hash[2]; 00277 D = context->Intermediate_Hash[3]; 00278 E = context->Intermediate_Hash[4]; 00279 00280 for (t = 0; t < 20; t++) { 00281 temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0]; 00282 E = D; 00283 D = C; 00284 C = SHA1_ROTL(30,B); 00285 B = A; 00286 A = temp; 00287 } 00288 00289 for (t = 20; t < 40; t++) { 00290 temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1]; 00291 E = D; 00292 D = C; 00293 C = SHA1_ROTL(30,B); 00294 B = A; 00295 A = temp; 00296 } 00297 00298 for (t = 40; t < 60; t++) { 00299 temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2]; 00300 E = D; 00301 D = C; 00302 C = SHA1_ROTL(30,B); 00303 B = A; 00304 A = temp; 00305 } 00306 00307 for (t = 60; t < 80; t++) { 00308 temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3]; 00309 E = D; 00310 D = C; 00311 C = SHA1_ROTL(30,B); 00312 B = A; 00313 A = temp; 00314 } 00315 00316 context->Intermediate_Hash[0] += A; 00317 context->Intermediate_Hash[1] += B; 00318 context->Intermediate_Hash[2] += C; 00319 context->Intermediate_Hash[3] += D; 00320 context->Intermediate_Hash[4] += E; 00321 context->Message_Block_Index = 0; 00322 } 00323 00324 /* 00325 * SHA1Finalize 00326 * 00327 * Description: 00328 * This helper function finishes off the digest calculations. 00329 * 00330 * Parameters: 00331 * context: [in/out] 00332 * The SHA context to update. 00333 * Pad_Byte: [in] 00334 * The last byte to add to the message block before the 0-padding 00335 * and length. This will contain the last bits of the message 00336 * followed by another single bit. If the message was an 00337 * exact multiple of 8-bits long, Pad_Byte will be 0x80. 00338 * 00339 * Returns: 00340 * sha Error Code. 00341 * 00342 */ 00343 static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) 00344 { 00345 int i; 00346 SHA1PadMessage(context, Pad_Byte); 00347 /* message may be sensitive, clear it out */ 00348 for (i = 0; i < SHA1_Message_Block_Size; ++i) 00349 context->Message_Block[i] = 0; 00350 context->Length_High = 0; /* and clear length */ 00351 context->Length_Low = 0; 00352 context->Computed = 1; 00353 } 00354 00355 /* 00356 * SHA1PadMessage 00357 * 00358 * Description: 00359 * According to the standard, the message must be padded to the next 00360 * even multiple of 512 bits. The first padding bit must be a '1'. 00361 * The last 64 bits represent the length of the original message. 00362 * All bits in between should be 0. This helper function will pad 00363 * the message according to those rules by filling the Message_Block 00364 * array accordingly. When it returns, it can be assumed that the 00365 * message digest has been computed. 00366 * 00367 * Parameters: 00368 * context: [in/out] 00369 * The context to pad. 00370 * Pad_Byte: [in] 00371 * The last byte to add to the message block before the 0-padding 00372 * and length. This will contain the last bits of the message 00373 * followed by another single bit. If the message was an 00374 * exact multiple of 8-bits long, Pad_Byte will be 0x80. 00375 * 00376 * Returns: 00377 * Nothing. 00378 */ 00379 static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) 00380 { 00381 /* 00382 * Check to see if the current message block is too small to hold 00383 * the initial padding bits and length. If so, we will pad the 00384 * block, process it, and then continue padding into a second 00385 * block. 00386 */ 00387 if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) { 00388 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00389 while (context->Message_Block_Index < SHA1_Message_Block_Size) 00390 context->Message_Block[context->Message_Block_Index++] = 0; 00391 00392 SHA1ProcessMessageBlock(context); 00393 } else 00394 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00395 00396 while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8)) 00397 context->Message_Block[context->Message_Block_Index++] = 0; 00398 00399 /* 00400 * Store the message length as the last 8 octets 00401 */ 00402 context->Message_Block[56] = (uint8_t) (context->Length_High >> 24); 00403 context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); 00404 context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); 00405 context->Message_Block[59] = (uint8_t) (context->Length_High); 00406 context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); 00407 context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); 00408 context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); 00409 context->Message_Block[63] = (uint8_t) (context->Length_Low); 00410 00411 SHA1ProcessMessageBlock(context); 00412 }