libmoost
|
00001 /************************* sha384-512.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 Algorithms SHA-384 and 00010 * SHA-512 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-384 and SHA-512 algorithms produce 384-bit and 512-bit 00021 * message digests for a given data stream. It should take about 00022 * 2**n steps to find a message with the same digest as a given 00023 * message and 2**(n/2) to find any two messages with the same 00024 * digest, when n is the digest size in bits. Therefore, this 00025 * algorithm can serve as a means of providing a 00026 * "fingerprint" for a message. 00027 * 00028 * Portability Issues: 00029 * SHA-384 and SHA-512 are defined in terms of 64-bit "words", 00030 * but if USE_32BIT_ONLY is #defined, this code is implemented in 00031 * terms of 32-bit "words". This code uses <stdint.h> (included 00032 * via "sha.h") to define the 64-, 32- and 8-bit unsigned integer 00033 * types. If your C compiler does not support 64-bit unsigned 00034 * integers and you do not #define USE_32BIT_ONLY, this code is 00035 * not appropriate. 00036 * 00037 * Caveats: 00038 * SHA-384 and SHA-512 are designed to work with messages less 00039 * than 2^128 bits long. This implementation uses SHA384/512Input() 00040 * to hash the bits that are a multiple of the size of an 8-bit 00041 * octet, and then optionally uses SHA384/256FinalBits() 00042 * to hash the final few bits of the input. 00043 * 00044 */ 00045 00046 #include "sha.h" 00047 00048 #ifdef USE_32BIT_ONLY 00049 /* 00050 * Define 64-bit arithmetic in terms of 32-bit arithmetic. 00051 * Each 64-bit number is represented in a 2-word array. 00052 * All macros are defined such that the result is the last parameter. 00053 */ 00054 00055 /* 00056 * Define shift, rotate left, and rotate right functions 00057 */ 00058 #define SHA512_SHR(bits, word, ret) ( \ 00059 /* (((uint64_t)((word))) >> (bits)) */ \ 00060 (ret)[0] = (((bits) < 32) && ((bits) >= 0)) ? \ 00061 ((word)[0] >> (bits)) : 0, \ 00062 (ret)[1] = ((bits) > 32) ? ((word)[0] >> ((bits) - 32)) : \ 00063 ((bits) == 32) ? (word)[0] : \ 00064 ((bits) >= 0) ? \ 00065 (((word)[0] << (32 - (bits))) | \ 00066 ((word)[1] >> (bits))) : 0 ) 00067 00068 #define SHA512_SHL(bits, word, ret) ( \ 00069 /* (((uint64_t)(word)) << (bits)) */ \ 00070 (ret)[0] = ((bits) > 32) ? ((word)[1] << ((bits) - 32)) : \ 00071 ((bits) == 32) ? (word)[1] : \ 00072 ((bits) >= 0) ? \ 00073 (((word)[0] << (bits)) | \ 00074 ((word)[1] >> (32 - (bits)))) : \ 00075 0, \ 00076 (ret)[1] = (((bits) < 32) && ((bits) >= 0)) ? \ 00077 ((word)[1] << (bits)) : 0 ) 00078 00079 /* 00080 * Define 64-bit OR 00081 */ 00082 #define SHA512_OR(word1, word2, ret) ( \ 00083 (ret)[0] = (word1)[0] | (word2)[0], \ 00084 (ret)[1] = (word1)[1] | (word2)[1] ) 00085 00086 /* 00087 * Define 64-bit XOR 00088 */ 00089 #define SHA512_XOR(word1, word2, ret) ( \ 00090 (ret)[0] = (word1)[0] ^ (word2)[0], \ 00091 (ret)[1] = (word1)[1] ^ (word2)[1] ) 00092 00093 /* 00094 * Define 64-bit AND 00095 */ 00096 #define SHA512_AND(word1, word2, ret) ( \ 00097 (ret)[0] = (word1)[0] & (word2)[0], \ 00098 (ret)[1] = (word1)[1] & (word2)[1] ) 00099 00100 /* 00101 * Define 64-bit TILDA 00102 */ 00103 #define SHA512_TILDA(word, ret) \ 00104 ( (ret)[0] = ~(word)[0], (ret)[1] = ~(word)[1] ) 00105 00106 /* 00107 * Define 64-bit ADD 00108 */ 00109 #define SHA512_ADD(word1, word2, ret) ( \ 00110 (ret)[1] = (word1)[1], (ret)[1] += (word2)[1], \ 00111 (ret)[0] = (word1)[0] + (word2)[0] + ((ret)[1] < (word1)[1]) ) 00112 00113 /* 00114 * Add the 4word value in word2 to word1. 00115 */ 00116 static uint32_t ADDTO4_temp, ADDTO4_temp2; 00117 #define SHA512_ADDTO4(word1, word2) ( \ 00118 ADDTO4_temp = (word1)[3], \ 00119 (word1)[3] += (word2)[3], \ 00120 ADDTO4_temp2 = (word1)[2], \ 00121 (word1)[2] += (word2)[2] + ((word1)[3] < ADDTO4_temp), \ 00122 ADDTO4_temp = (word1)[1], \ 00123 (word1)[1] += (word2)[1] + ((word1)[2] < ADDTO4_temp2), \ 00124 (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO4_temp) ) 00125 00126 /* 00127 * Add the 2word value in word2 to word1. 00128 */ 00129 static uint32_t ADDTO2_temp; 00130 #define SHA512_ADDTO2(word1, word2) ( \ 00131 ADDTO2_temp = (word1)[1], \ 00132 (word1)[1] += (word2)[1], \ 00133 (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO2_temp) ) 00134 00135 /* 00136 * SHA rotate ((word >> bits) | (word << (64-bits))) 00137 */ 00138 static uint32_t ROTR_temp1[2], ROTR_temp2[2]; 00139 #define SHA512_ROTR(bits, word, ret) ( \ 00140 SHA512_SHR((bits), (word), ROTR_temp1), \ 00141 SHA512_SHL(64-(bits), (word), ROTR_temp2), \ 00142 SHA512_OR(ROTR_temp1, ROTR_temp2, (ret)) ) 00143 00144 /* 00145 * Define the SHA SIGMA and sigma macros 00146 * 00147 * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word) 00148 */ 00149 static uint32_t SIGMA0_temp1[2], SIGMA0_temp2[2], 00150 SIGMA0_temp3[2], SIGMA0_temp4[2]; 00151 #define SHA512_SIGMA0(word, ret) ( \ 00152 SHA512_ROTR(28, (word), SIGMA0_temp1), \ 00153 SHA512_ROTR(34, (word), SIGMA0_temp2), \ 00154 SHA512_ROTR(39, (word), SIGMA0_temp3), \ 00155 SHA512_XOR(SIGMA0_temp2, SIGMA0_temp3, SIGMA0_temp4), \ 00156 SHA512_XOR(SIGMA0_temp1, SIGMA0_temp4, (ret)) ) 00157 00158 /* 00159 * SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word) 00160 */ 00161 static uint32_t SIGMA1_temp1[2], SIGMA1_temp2[2], 00162 SIGMA1_temp3[2], SIGMA1_temp4[2]; 00163 #define SHA512_SIGMA1(word, ret) ( \ 00164 SHA512_ROTR(14, (word), SIGMA1_temp1), \ 00165 SHA512_ROTR(18, (word), SIGMA1_temp2), \ 00166 SHA512_ROTR(41, (word), SIGMA1_temp3), \ 00167 SHA512_XOR(SIGMA1_temp2, SIGMA1_temp3, SIGMA1_temp4), \ 00168 SHA512_XOR(SIGMA1_temp1, SIGMA1_temp4, (ret)) ) 00169 00170 /* 00171 * (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) 00172 */ 00173 static uint32_t sigma0_temp1[2], sigma0_temp2[2], 00174 sigma0_temp3[2], sigma0_temp4[2]; 00175 #define SHA512_sigma0(word, ret) ( \ 00176 SHA512_ROTR( 1, (word), sigma0_temp1), \ 00177 SHA512_ROTR( 8, (word), sigma0_temp2), \ 00178 SHA512_SHR( 7, (word), sigma0_temp3), \ 00179 SHA512_XOR(sigma0_temp2, sigma0_temp3, sigma0_temp4), \ 00180 SHA512_XOR(sigma0_temp1, sigma0_temp4, (ret)) ) 00181 00182 /* 00183 * (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word)) 00184 */ 00185 static uint32_t sigma1_temp1[2], sigma1_temp2[2], 00186 sigma1_temp3[2], sigma1_temp4[2]; 00187 #define SHA512_sigma1(word, ret) ( \ 00188 SHA512_ROTR(19, (word), sigma1_temp1), \ 00189 SHA512_ROTR(61, (word), sigma1_temp2), \ 00190 SHA512_SHR( 6, (word), sigma1_temp3), \ 00191 SHA512_XOR(sigma1_temp2, sigma1_temp3, sigma1_temp4), \ 00192 SHA512_XOR(sigma1_temp1, sigma1_temp4, (ret)) ) 00193 00194 #ifndef USE_MODIFIED_MACROS 00195 /* 00196 * These definitions are the ones used in FIPS 180-3, section 4.1.3 00197 * Ch(x,y,z) ((x & y) ^ (~x & z)) 00198 */ 00199 static uint32_t Ch_temp1[2], Ch_temp2[2], Ch_temp3[2]; 00200 #define SHA_Ch(x, y, z, ret) ( \ 00201 SHA512_AND(x, y, Ch_temp1), \ 00202 SHA512_TILDA(x, Ch_temp2), \ 00203 SHA512_AND(Ch_temp2, z, Ch_temp3), \ 00204 SHA512_XOR(Ch_temp1, Ch_temp3, (ret)) ) 00205 00206 /* 00207 * Maj(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z))) 00208 */ 00209 static uint32_t Maj_temp1[2], Maj_temp2[2], 00210 Maj_temp3[2], Maj_temp4[2]; 00211 #define SHA_Maj(x, y, z, ret) ( \ 00212 SHA512_AND(x, y, Maj_temp1), \ 00213 SHA512_AND(x, z, Maj_temp2), \ 00214 SHA512_AND(y, z, Maj_temp3), \ 00215 SHA512_XOR(Maj_temp2, Maj_temp3, Maj_temp4), \ 00216 SHA512_XOR(Maj_temp1, Maj_temp4, (ret)) ) 00217 #else /* !USE_MODIFIED_MACROS */ 00218 /* 00219 * These definitions are potentially faster equivalents for the ones 00220 * used in FIPS 180-3, section 4.1.3. 00221 * ((x & y) ^ (~x & z)) becomes 00222 * ((x & (y ^ z)) ^ z) 00223 */ 00224 #define SHA_Ch(x, y, z, ret) ( \ 00225 (ret)[0] = (((x)[0] & ((y)[0] ^ (z)[0])) ^ (z)[0]), \ 00226 (ret)[1] = (((x)[1] & ((y)[1] ^ (z)[1])) ^ (z)[1]) ) 00227 00228 /* 00229 * ((x & y) ^ (x & z) ^ (y & z)) becomes 00230 * ((x & (y | z)) | (y & z)) 00231 */ 00232 #define SHA_Maj(x, y, z, ret) ( \ 00233 ret[0] = (((x)[0] & ((y)[0] | (z)[0])) | ((y)[0] & (z)[0])), \ 00234 ret[1] = (((x)[1] & ((y)[1] | (z)[1])) | ((y)[1] & (z)[1])) ) 00235 #endif /* USE_MODIFIED_MACROS */ 00236 00237 /* 00238 * Add "length" to the length. 00239 * Set Corrupted when overflow has occurred. 00240 */ 00241 static uint32_t addTemp[4] = { 0, 0, 0, 0 }; 00242 #define SHA384_512AddLength(context, length) ( \ 00243 addTemp[3] = (length), SHA512_ADDTO4((context)->Length, addTemp), \ 00244 (context)->Corrupted = (((context)->Length[3] < (length)) && \ 00245 ((context)->Length[2] == 0) && ((context)->Length[1] == 0) && \ 00246 ((context)->Length[0] == 0)) ? shaInputTooLong : \ 00247 (context)->Corrupted ) 00248 00249 /* Local Function Prototypes */ 00250 static int SHA384_512Reset(SHA512Context *context, 00251 uint32_t H0[SHA512HashSize/4]); 00252 static void SHA384_512ProcessMessageBlock(SHA512Context *context); 00253 static void SHA384_512Finalize(SHA512Context *context, 00254 uint8_t Pad_Byte); 00255 static void SHA384_512PadMessage(SHA512Context *context, 00256 uint8_t Pad_Byte); 00257 static int SHA384_512ResultN( SHA512Context *context, 00258 uint8_t Message_Digest[ ], int HashSize); 00259 00260 /* Initial Hash Values: FIPS 180-3 sections 5.3.4 and 5.3.5 */ 00261 static uint32_t SHA384_H0[SHA512HashSize/4] = { 00262 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A, 00263 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31, 00264 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, 00265 0xBEFA4FA4 00266 }; 00267 static uint32_t SHA512_H0[SHA512HashSize/4] = { 00268 0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B, 0x3C6EF372, 00269 0xFE94F82B, 0xA54FF53A, 0x5F1D36F1, 0x510E527F, 0xADE682D1, 00270 0x9B05688C, 0x2B3E6C1F, 0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19, 00271 0x137E2179 00272 }; 00273 00274 #else /* !USE_32BIT_ONLY */ 00275 00276 #include "sha-private.h" 00277 00278 /* Define the SHA shift, rotate left and rotate right macros */ 00279 #define SHA512_SHR(bits,word) (((uint64_t)(word)) >> (bits)) 00280 #define SHA512_ROTR(bits,word) ((((uint64_t)(word)) >> (bits)) | \ 00281 (((uint64_t)(word)) << (64-(bits)))) 00282 00283 /* 00284 * Define the SHA SIGMA and sigma macros 00285 * 00286 * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word) 00287 */ 00288 #define SHA512_SIGMA0(word) \ 00289 (SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word)) 00290 #define SHA512_SIGMA1(word) \ 00291 (SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word)) 00292 #define SHA512_sigma0(word) \ 00293 (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) 00294 #define SHA512_sigma1(word) \ 00295 (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word)) 00296 00297 /* 00298 * Add "length" to the length. 00299 * Set Corrupted when overflow has occurred. 00300 */ 00301 static uint64_t addTemp; 00302 #define SHA384_512AddLength(context, length) \ 00303 (addTemp = context->Length_Low, context->Corrupted = \ 00304 ((context->Length_Low += length) < addTemp) && \ 00305 (++context->Length_High == 0) ? shaInputTooLong : \ 00306 (context)->Corrupted) 00307 00308 /* Local Function Prototypes */ 00309 static int SHA384_512Reset(SHA512Context *context, 00310 uint64_t H0[SHA512HashSize/8]); 00311 static void SHA384_512ProcessMessageBlock(SHA512Context *context); 00312 static void SHA384_512Finalize(SHA512Context *context, 00313 uint8_t Pad_Byte); 00314 static void SHA384_512PadMessage(SHA512Context *context, 00315 uint8_t Pad_Byte); 00316 static int SHA384_512ResultN(SHA512Context *context, 00317 uint8_t Message_Digest[ ], int HashSize); 00318 00319 /* Initial Hash Values: FIPS 180-3 sections 5.3.4 and 5.3.5 */ 00320 static uint64_t SHA384_H0[ ] = { 00321 0xCBBB9D5DC1059ED8ll, 0x629A292A367CD507ll, 0x9159015A3070DD17ll, 00322 0x152FECD8F70E5939ll, 0x67332667FFC00B31ll, 0x8EB44A8768581511ll, 00323 0xDB0C2E0D64F98FA7ll, 0x47B5481DBEFA4FA4ll 00324 }; 00325 static uint64_t SHA512_H0[ ] = { 00326 0x6A09E667F3BCC908ll, 0xBB67AE8584CAA73Bll, 0x3C6EF372FE94F82Bll, 00327 0xA54FF53A5F1D36F1ll, 0x510E527FADE682D1ll, 0x9B05688C2B3E6C1Fll, 00328 0x1F83D9ABFB41BD6Bll, 0x5BE0CD19137E2179ll 00329 }; 00330 00331 #endif /* USE_32BIT_ONLY */ 00332 00333 /* 00334 * SHA384Reset 00335 * 00336 * Description: 00337 * This function will initialize the SHA384Context in preparation 00338 * for computing a new SHA384 message digest. 00339 * 00340 * Parameters: 00341 * context: [in/out] 00342 * The context to reset. 00343 * 00344 * Returns: 00345 * sha Error Code. 00346 * 00347 */ 00348 int SHA384Reset(SHA384Context *context) 00349 { 00350 return SHA384_512Reset(context, SHA384_H0); 00351 } 00352 00353 /* 00354 * SHA384Input 00355 * 00356 * Description: 00357 * This function accepts an array of octets as the next portion 00358 * of the message. 00359 * 00360 * Parameters: 00361 * context: [in/out] 00362 * The SHA context to update. 00363 * message_array[ ]: [in] 00364 * An array of octets representing the next portion of 00365 * the message. 00366 * length: [in] 00367 * The length of the message in message_array. 00368 * 00369 * Returns: 00370 * sha Error Code. 00371 * 00372 */ 00373 int SHA384Input(SHA384Context *context, 00374 const uint8_t *message_array, unsigned int length) 00375 { 00376 return SHA512Input(context, message_array, length); 00377 } 00378 00379 /* 00380 * SHA384FinalBits 00381 * 00382 * Description: 00383 * This function will add in any final bits of the message. 00384 * 00385 * Parameters: 00386 * context: [in/out] 00387 * The SHA context to update. 00388 * message_bits: [in] 00389 * The final bits of the message, in the upper portion of the 00390 * byte. (Use 0b###00000 instead of 0b00000### to input the 00391 * three bits ###.) 00392 * length: [in] 00393 * The number of bits in message_bits, between 1 and 7. 00394 * 00395 * Returns: 00396 * sha Error Code. 00397 * 00398 */ 00399 int SHA384FinalBits(SHA384Context *context, 00400 uint8_t message_bits, unsigned int length) 00401 { 00402 return SHA512FinalBits(context, message_bits, length); 00403 } 00404 00405 /* 00406 * SHA384Result 00407 * 00408 * Description: 00409 * This function will return the 384-bit message digest 00410 * into the Message_Digest array provided by the caller. 00411 * NOTE: 00412 * The first octet of hash is stored in the element with index 0, 00413 * the last octet of hash in the element with index 47. 00414 * 00415 * Parameters: 00416 * context: [in/out] 00417 * The context to use to calculate the SHA hash. 00418 * Message_Digest[ ]: [out] 00419 * Where the digest is returned. 00420 * 00421 * Returns: 00422 * sha Error Code. 00423 * 00424 */ 00425 int SHA384Result(SHA384Context *context, 00426 uint8_t Message_Digest[SHA384HashSize]) 00427 { 00428 return SHA384_512ResultN(context, Message_Digest, SHA384HashSize); 00429 } 00430 00431 /* 00432 * SHA512Reset 00433 * 00434 * Description: 00435 * This function will initialize the SHA512Context in preparation 00436 * for computing a new SHA512 message digest. 00437 * 00438 * Parameters: 00439 * context: [in/out] 00440 * The context to reset. 00441 * 00442 * Returns: 00443 * sha Error Code. 00444 * 00445 */ 00446 int SHA512Reset(SHA512Context *context) 00447 { 00448 return SHA384_512Reset(context, SHA512_H0); 00449 } 00450 00451 /* 00452 * SHA512Input 00453 * 00454 * Description: 00455 * This function accepts an array of octets as the next portion 00456 * of the message. 00457 * 00458 * Parameters: 00459 * context: [in/out] 00460 * The SHA context to update. 00461 * message_array[ ]: [in] 00462 * An array of octets representing the next portion of 00463 * the message. 00464 * length: [in] 00465 * The length of the message in message_array. 00466 * 00467 * Returns: 00468 * sha Error Code. 00469 * 00470 */ 00471 int SHA512Input(SHA512Context *context, 00472 const uint8_t *message_array, 00473 unsigned int length) 00474 { 00475 if (!context) return shaNull; 00476 if (!length) return shaSuccess; 00477 if (!message_array) return shaNull; 00478 if (context->Computed) return context->Corrupted = shaStateError; 00479 if (context->Corrupted) return context->Corrupted; 00480 00481 while (length--) { 00482 context->Message_Block[context->Message_Block_Index++] = 00483 *message_array; 00484 00485 if ((SHA384_512AddLength(context, 8) == shaSuccess) && 00486 (context->Message_Block_Index == SHA512_Message_Block_Size)) 00487 SHA384_512ProcessMessageBlock(context); 00488 00489 message_array++; 00490 } 00491 00492 return context->Corrupted; 00493 } 00494 00495 /* 00496 * SHA512FinalBits 00497 * 00498 * Description: 00499 * This function will add in any final bits of the message. 00500 * 00501 * Parameters: 00502 * context: [in/out] 00503 * The SHA context to update. 00504 * message_bits: [in] 00505 * The final bits of the message, in the upper portion of the 00506 * byte. (Use 0b###00000 instead of 0b00000### to input the 00507 * three bits ###.) 00508 * length: [in] 00509 * The number of bits in message_bits, between 1 and 7. 00510 * 00511 * Returns: 00512 * sha Error Code. 00513 * 00514 */ 00515 int SHA512FinalBits(SHA512Context *context, 00516 uint8_t message_bits, unsigned int length) 00517 { 00518 static uint8_t masks[8] = { 00519 /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, 00520 /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, 00521 /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, 00522 /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE 00523 }; 00524 static uint8_t markbit[8] = { 00525 /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, 00526 /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, 00527 /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, 00528 /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 00529 }; 00530 00531 if (!context) return shaNull; 00532 if (!length) return shaSuccess; 00533 if (context->Corrupted) return context->Corrupted; 00534 if (context->Computed) return context->Corrupted = shaStateError; 00535 if (length >= 8) return context->Corrupted = shaBadParam; 00536 00537 SHA384_512AddLength(context, length); 00538 SHA384_512Finalize(context, (uint8_t) 00539 ((message_bits & masks[length]) | markbit[length])); 00540 00541 return context->Corrupted; 00542 } 00543 00544 /* 00545 * SHA512Result 00546 * 00547 * Description: 00548 * This function will return the 512-bit message digest 00549 * into the Message_Digest array provided by the caller. 00550 * NOTE: 00551 * The first octet of hash is stored in the element with index 0, 00552 * the last octet of hash in the element with index 63. 00553 * 00554 * Parameters: 00555 * context: [in/out] 00556 * The context to use to calculate the SHA hash. 00557 * Message_Digest[ ]: [out] 00558 * Where the digest is returned. 00559 * 00560 * Returns: 00561 * sha Error Code. 00562 * 00563 */ 00564 int SHA512Result(SHA512Context *context, 00565 uint8_t Message_Digest[SHA512HashSize]) 00566 { 00567 return SHA384_512ResultN(context, Message_Digest, SHA512HashSize); 00568 } 00569 00570 /* 00571 * SHA384_512Reset 00572 * 00573 * Description: 00574 * This helper function will initialize the SHA512Context in 00575 * preparation for computing a new SHA384 or SHA512 message 00576 * digest. 00577 * 00578 * Parameters: 00579 * context: [in/out] 00580 * The context to reset. 00581 * H0[ ]: [in] 00582 * The initial hash value array to use. 00583 * 00584 * Returns: 00585 * sha Error Code. 00586 * 00587 */ 00588 #ifdef USE_32BIT_ONLY 00589 static int SHA384_512Reset(SHA512Context *context, 00590 uint32_t H0[SHA512HashSize/4]) 00591 #else /* !USE_32BIT_ONLY */ 00592 static int SHA384_512Reset(SHA512Context *context, 00593 uint64_t H0[SHA512HashSize/8]) 00594 #endif /* USE_32BIT_ONLY */ 00595 { 00596 int i; 00597 if (!context) return shaNull; 00598 context->Message_Block_Index = 0; 00599 00600 #ifdef USE_32BIT_ONLY 00601 context->Length[0] = context->Length[1] = 00602 context->Length[2] = context->Length[3] = 0; 00603 00604 for (i = 0; i < SHA512HashSize/4; i++) 00605 context->Intermediate_Hash[i] = H0[i]; 00606 #else /* !USE_32BIT_ONLY */ 00607 context->Length_High = context->Length_Low = 0; 00608 00609 for (i = 0; i < SHA512HashSize/8; i++) 00610 context->Intermediate_Hash[i] = H0[i]; 00611 #endif /* USE_32BIT_ONLY */ 00612 00613 context->Computed = 0; 00614 context->Corrupted = shaSuccess; 00615 00616 return shaSuccess; 00617 } 00618 00619 /* 00620 * SHA384_512ProcessMessageBlock 00621 * 00622 * Description: 00623 * This helper function will process the next 1024 bits of the 00624 * message stored in the Message_Block array. 00625 * 00626 * Parameters: 00627 * context: [in/out] 00628 * The SHA context to update. 00629 * 00630 * Returns: 00631 * Nothing. 00632 * 00633 * Comments: 00634 * Many of the variable names in this code, especially the 00635 * single character names, were used because those were the 00636 * names used in the Secure Hash Standard. 00637 * 00638 * 00639 */ 00640 static void SHA384_512ProcessMessageBlock(SHA512Context *context) 00641 { 00642 #ifdef USE_32BIT_ONLY 00643 /* Constants defined in FIPS 180-3, section 4.2.3 */ 00644 static const uint32_t K[80*2] = { 00645 0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF, 00646 0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538, 00647 0x59F111F1, 0xB605D019, 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5, 00648 0xDA6D8118, 0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE, 00649 0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, 0x72BE5D74, 00650 0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235, 00651 0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786, 00652 0x384F25E3, 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65, 00653 0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC, 00654 0xBD41FBD4, 0x76F988DA, 0x831153B5, 0x983E5152, 0xEE66DFAB, 00655 0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, 0xBF597FC7, 00656 0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725, 00657 0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85, 00658 0x46D22FFC, 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED, 00659 0x53380D13, 0x9D95B3DF, 0x650A7354, 0x8BAF63DE, 0x766A0ABB, 00660 0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B, 00661 0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, 0xC24B8B70, 00662 0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218, 00663 0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070, 00664 0x32BBD1B8, 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53, 00665 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, 00666 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, 0x5B9CCA4F, 0x7763E373, 00667 0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, 0x78A5636F, 00668 0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC, 00669 0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7, 00670 0xB2C67915, 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C, 00671 0xD186B8C7, 0x21C0C207, 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F, 00672 0xEE6ED178, 0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6, 00673 0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, 0x28DB77F5, 00674 0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC, 00675 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, 00676 0xFC657E2A, 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817 00677 }; 00678 int t, t2, t8; /* Loop counter */ 00679 uint32_t temp1[2], temp2[2], /* Temporary word values */ 00680 temp3[2], temp4[2], temp5[2]; 00681 uint32_t W[2*80]; /* Word sequence */ 00682 uint32_t A[2], B[2], C[2], D[2], /* Word buffers */ 00683 E[2], F[2], G[2], H[2]; 00684 00685 /* Initialize the first 16 words in the array W */ 00686 for (t = t2 = t8 = 0; t < 16; t++, t8 += 8) { 00687 W[t2++] = ((((uint32_t)context->Message_Block[t8 ])) << 24) | 00688 ((((uint32_t)context->Message_Block[t8 + 1])) << 16) | 00689 ((((uint32_t)context->Message_Block[t8 + 2])) << 8) | 00690 ((((uint32_t)context->Message_Block[t8 + 3]))); 00691 W[t2++] = ((((uint32_t)context->Message_Block[t8 + 4])) << 24) | 00692 ((((uint32_t)context->Message_Block[t8 + 5])) << 16) | 00693 ((((uint32_t)context->Message_Block[t8 + 6])) << 8) | 00694 ((((uint32_t)context->Message_Block[t8 + 7]))); 00695 } 00696 00697 for (t = 16; t < 80; t++, t2 += 2) { 00698 /* W[t] = SHA512_sigma1(W[t-2]) + W[t-7] + 00699 SHA512_sigma0(W[t-15]) + W[t-16]; */ 00700 uint32_t *Wt2 = &W[t2-2*2]; 00701 uint32_t *Wt7 = &W[t2-7*2]; 00702 uint32_t *Wt15 = &W[t2-15*2]; 00703 uint32_t *Wt16 = &W[t2-16*2]; 00704 SHA512_sigma1(Wt2, temp1); 00705 SHA512_ADD(temp1, Wt7, temp2); 00706 SHA512_sigma0(Wt15, temp1); 00707 SHA512_ADD(temp1, Wt16, temp3); 00708 SHA512_ADD(temp2, temp3, &W[t2]); 00709 } 00710 00711 A[0] = context->Intermediate_Hash[0]; 00712 A[1] = context->Intermediate_Hash[1]; 00713 B[0] = context->Intermediate_Hash[2]; 00714 B[1] = context->Intermediate_Hash[3]; 00715 C[0] = context->Intermediate_Hash[4]; 00716 C[1] = context->Intermediate_Hash[5]; 00717 D[0] = context->Intermediate_Hash[6]; 00718 D[1] = context->Intermediate_Hash[7]; 00719 E[0] = context->Intermediate_Hash[8]; 00720 E[1] = context->Intermediate_Hash[9]; 00721 F[0] = context->Intermediate_Hash[10]; 00722 F[1] = context->Intermediate_Hash[11]; 00723 G[0] = context->Intermediate_Hash[12]; 00724 G[1] = context->Intermediate_Hash[13]; 00725 H[0] = context->Intermediate_Hash[14]; 00726 H[1] = context->Intermediate_Hash[15]; 00727 00728 for (t = t2 = 0; t < 80; t++, t2 += 2) { 00729 /* 00730 * temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; 00731 */ 00732 SHA512_SIGMA1(E,temp1); 00733 SHA512_ADD(H, temp1, temp2); 00734 SHA_Ch(E,F,G,temp3); 00735 SHA512_ADD(temp2, temp3, temp4); 00736 SHA512_ADD(&K[t2], &W[t2], temp5); 00737 SHA512_ADD(temp4, temp5, temp1); 00738 /* 00739 * temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); 00740 */ 00741 SHA512_SIGMA0(A,temp3); 00742 SHA_Maj(A,B,C,temp4); 00743 SHA512_ADD(temp3, temp4, temp2); 00744 H[0] = G[0]; H[1] = G[1]; 00745 G[0] = F[0]; G[1] = F[1]; 00746 F[0] = E[0]; F[1] = E[1]; 00747 SHA512_ADD(D, temp1, E); 00748 D[0] = C[0]; D[1] = C[1]; 00749 C[0] = B[0]; C[1] = B[1]; 00750 B[0] = A[0]; B[1] = A[1]; 00751 SHA512_ADD(temp1, temp2, A); 00752 } 00753 00754 SHA512_ADDTO2(&context->Intermediate_Hash[0], A); 00755 SHA512_ADDTO2(&context->Intermediate_Hash[2], B); 00756 SHA512_ADDTO2(&context->Intermediate_Hash[4], C); 00757 SHA512_ADDTO2(&context->Intermediate_Hash[6], D); 00758 SHA512_ADDTO2(&context->Intermediate_Hash[8], E); 00759 SHA512_ADDTO2(&context->Intermediate_Hash[10], F); 00760 SHA512_ADDTO2(&context->Intermediate_Hash[12], G); 00761 SHA512_ADDTO2(&context->Intermediate_Hash[14], H); 00762 00763 #else /* !USE_32BIT_ONLY */ 00764 /* Constants defined in FIPS 180-3, section 4.2.3 */ 00765 static const uint64_t K[80] = { 00766 0x428A2F98D728AE22ll, 0x7137449123EF65CDll, 0xB5C0FBCFEC4D3B2Fll, 00767 0xE9B5DBA58189DBBCll, 0x3956C25BF348B538ll, 0x59F111F1B605D019ll, 00768 0x923F82A4AF194F9Bll, 0xAB1C5ED5DA6D8118ll, 0xD807AA98A3030242ll, 00769 0x12835B0145706FBEll, 0x243185BE4EE4B28Cll, 0x550C7DC3D5FFB4E2ll, 00770 0x72BE5D74F27B896Fll, 0x80DEB1FE3B1696B1ll, 0x9BDC06A725C71235ll, 00771 0xC19BF174CF692694ll, 0xE49B69C19EF14AD2ll, 0xEFBE4786384F25E3ll, 00772 0x0FC19DC68B8CD5B5ll, 0x240CA1CC77AC9C65ll, 0x2DE92C6F592B0275ll, 00773 0x4A7484AA6EA6E483ll, 0x5CB0A9DCBD41FBD4ll, 0x76F988DA831153B5ll, 00774 0x983E5152EE66DFABll, 0xA831C66D2DB43210ll, 0xB00327C898FB213Fll, 00775 0xBF597FC7BEEF0EE4ll, 0xC6E00BF33DA88FC2ll, 0xD5A79147930AA725ll, 00776 0x06CA6351E003826Fll, 0x142929670A0E6E70ll, 0x27B70A8546D22FFCll, 00777 0x2E1B21385C26C926ll, 0x4D2C6DFC5AC42AEDll, 0x53380D139D95B3DFll, 00778 0x650A73548BAF63DEll, 0x766A0ABB3C77B2A8ll, 0x81C2C92E47EDAEE6ll, 00779 0x92722C851482353Bll, 0xA2BFE8A14CF10364ll, 0xA81A664BBC423001ll, 00780 0xC24B8B70D0F89791ll, 0xC76C51A30654BE30ll, 0xD192E819D6EF5218ll, 00781 0xD69906245565A910ll, 0xF40E35855771202All, 0x106AA07032BBD1B8ll, 00782 0x19A4C116B8D2D0C8ll, 0x1E376C085141AB53ll, 0x2748774CDF8EEB99ll, 00783 0x34B0BCB5E19B48A8ll, 0x391C0CB3C5C95A63ll, 0x4ED8AA4AE3418ACBll, 00784 0x5B9CCA4F7763E373ll, 0x682E6FF3D6B2B8A3ll, 0x748F82EE5DEFB2FCll, 00785 0x78A5636F43172F60ll, 0x84C87814A1F0AB72ll, 0x8CC702081A6439ECll, 00786 0x90BEFFFA23631E28ll, 0xA4506CEBDE82BDE9ll, 0xBEF9A3F7B2C67915ll, 00787 0xC67178F2E372532Bll, 0xCA273ECEEA26619Cll, 0xD186B8C721C0C207ll, 00788 0xEADA7DD6CDE0EB1Ell, 0xF57D4F7FEE6ED178ll, 0x06F067AA72176FBAll, 00789 0x0A637DC5A2C898A6ll, 0x113F9804BEF90DAEll, 0x1B710B35131C471Bll, 00790 0x28DB77F523047D84ll, 0x32CAAB7B40C72493ll, 0x3C9EBE0A15C9BEBCll, 00791 0x431D67C49C100D4Cll, 0x4CC5D4BECB3E42B6ll, 0x597F299CFC657E2All, 00792 0x5FCB6FAB3AD6FAECll, 0x6C44198C4A475817ll 00793 }; 00794 int t, t8; /* Loop counter */ 00795 uint64_t temp1, temp2; /* Temporary word value */ 00796 uint64_t W[80]; /* Word sequence */ 00797 uint64_t A, B, C, D, E, F, G, H; /* Word buffers */ 00798 00799 /* 00800 * Initialize the first 16 words in the array W 00801 */ 00802 for (t = t8 = 0; t < 16; t++, t8 += 8) 00803 W[t] = ((uint64_t)(context->Message_Block[t8 ]) << 56) | 00804 ((uint64_t)(context->Message_Block[t8 + 1]) << 48) | 00805 ((uint64_t)(context->Message_Block[t8 + 2]) << 40) | 00806 ((uint64_t)(context->Message_Block[t8 + 3]) << 32) | 00807 ((uint64_t)(context->Message_Block[t8 + 4]) << 24) | 00808 ((uint64_t)(context->Message_Block[t8 + 5]) << 16) | 00809 ((uint64_t)(context->Message_Block[t8 + 6]) << 8) | 00810 ((uint64_t)(context->Message_Block[t8 + 7])); 00811 00812 for (t = 16; t < 80; t++) 00813 W[t] = SHA512_sigma1(W[t-2]) + W[t-7] + 00814 SHA512_sigma0(W[t-15]) + W[t-16]; 00815 A = context->Intermediate_Hash[0]; 00816 B = context->Intermediate_Hash[1]; 00817 C = context->Intermediate_Hash[2]; 00818 D = context->Intermediate_Hash[3]; 00819 E = context->Intermediate_Hash[4]; 00820 F = context->Intermediate_Hash[5]; 00821 G = context->Intermediate_Hash[6]; 00822 H = context->Intermediate_Hash[7]; 00823 00824 for (t = 0; t < 80; t++) { 00825 temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; 00826 temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); 00827 H = G; 00828 G = F; 00829 F = E; 00830 E = D + temp1; 00831 D = C; 00832 C = B; 00833 B = A; 00834 A = temp1 + temp2; 00835 } 00836 00837 context->Intermediate_Hash[0] += A; 00838 context->Intermediate_Hash[1] += B; 00839 context->Intermediate_Hash[2] += C; 00840 context->Intermediate_Hash[3] += D; 00841 context->Intermediate_Hash[4] += E; 00842 context->Intermediate_Hash[5] += F; 00843 context->Intermediate_Hash[6] += G; 00844 context->Intermediate_Hash[7] += H; 00845 #endif /* USE_32BIT_ONLY */ 00846 00847 context->Message_Block_Index = 0; 00848 } 00849 00850 /* 00851 * SHA384_512Finalize 00852 * 00853 * Description: 00854 * This helper function finishes off the digest calculations. 00855 * 00856 * Parameters: 00857 * context: [in/out] 00858 * The SHA context to update. 00859 * Pad_Byte: [in] 00860 * The last byte to add to the message block before the 0-padding 00861 * and length. This will contain the last bits of the message 00862 * followed by another single bit. If the message was an 00863 * exact multiple of 8-bits long, Pad_Byte will be 0x80. 00864 * 00865 * Returns: 00866 * sha Error Code. 00867 * 00868 */ 00869 static void SHA384_512Finalize(SHA512Context *context, 00870 uint8_t Pad_Byte) 00871 { 00872 int_least16_t i; 00873 SHA384_512PadMessage(context, Pad_Byte); 00874 /* message may be sensitive, clear it out */ 00875 for (i = 0; i < SHA512_Message_Block_Size; ++i) 00876 context->Message_Block[i] = 0; 00877 #ifdef USE_32BIT_ONLY /* and clear length */ 00878 context->Length[0] = context->Length[1] = 0; 00879 context->Length[2] = context->Length[3] = 0; 00880 #else /* !USE_32BIT_ONLY */ 00881 context->Length_High = context->Length_Low = 0; 00882 #endif /* USE_32BIT_ONLY */ 00883 context->Computed = 1; 00884 } 00885 00886 /* 00887 * SHA384_512PadMessage 00888 * 00889 * Description: 00890 * According to the standard, the message must be padded to the next 00891 * even multiple of 1024 bits. The first padding bit must be a '1'. 00892 * The last 128 bits represent the length of the original message. 00893 * All bits in between should be 0. This helper function will 00894 * pad the message according to those rules by filling the 00895 * Message_Block array accordingly. When it returns, it can be 00896 * assumed that the message digest has been computed. 00897 * 00898 * Parameters: 00899 * context: [in/out] 00900 * The context to pad. 00901 * Pad_Byte: [in] 00902 * The last byte to add to the message block before the 0-padding 00903 * and length. This will contain the last bits of the message 00904 * followed by another single bit. If the message was an 00905 * exact multiple of 8-bits long, Pad_Byte will be 0x80. 00906 * 00907 * Returns: 00908 * Nothing. 00909 * 00910 */ 00911 static void SHA384_512PadMessage(SHA512Context *context, 00912 uint8_t Pad_Byte) 00913 { 00914 /* 00915 * Check to see if the current message block is too small to hold 00916 * the initial padding bits and length. If so, we will pad the 00917 * block, process it, and then continue padding into a second 00918 * block. 00919 */ 00920 if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) { 00921 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00922 while (context->Message_Block_Index < SHA512_Message_Block_Size) 00923 context->Message_Block[context->Message_Block_Index++] = 0; 00924 00925 SHA384_512ProcessMessageBlock(context); 00926 } else 00927 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00928 00929 while (context->Message_Block_Index < (SHA512_Message_Block_Size-16)) 00930 context->Message_Block[context->Message_Block_Index++] = 0; 00931 00932 /* 00933 * Store the message length as the last 16 octets 00934 */ 00935 #ifdef USE_32BIT_ONLY 00936 context->Message_Block[112] = (uint8_t)(context->Length[0] >> 24); 00937 context->Message_Block[113] = (uint8_t)(context->Length[0] >> 16); 00938 context->Message_Block[114] = (uint8_t)(context->Length[0] >> 8); 00939 context->Message_Block[115] = (uint8_t)(context->Length[0]); 00940 context->Message_Block[116] = (uint8_t)(context->Length[1] >> 24); 00941 context->Message_Block[117] = (uint8_t)(context->Length[1] >> 16); 00942 context->Message_Block[118] = (uint8_t)(context->Length[1] >> 8); 00943 context->Message_Block[119] = (uint8_t)(context->Length[1]); 00944 00945 context->Message_Block[120] = (uint8_t)(context->Length[2] >> 24); 00946 context->Message_Block[121] = (uint8_t)(context->Length[2] >> 16); 00947 context->Message_Block[122] = (uint8_t)(context->Length[2] >> 8); 00948 context->Message_Block[123] = (uint8_t)(context->Length[2]); 00949 context->Message_Block[124] = (uint8_t)(context->Length[3] >> 24); 00950 context->Message_Block[125] = (uint8_t)(context->Length[3] >> 16); 00951 context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8); 00952 context->Message_Block[127] = (uint8_t)(context->Length[3]); 00953 #else /* !USE_32BIT_ONLY */ 00954 context->Message_Block[112] = (uint8_t)(context->Length_High >> 56); 00955 context->Message_Block[113] = (uint8_t)(context->Length_High >> 48); 00956 context->Message_Block[114] = (uint8_t)(context->Length_High >> 40); 00957 context->Message_Block[115] = (uint8_t)(context->Length_High >> 32); 00958 context->Message_Block[116] = (uint8_t)(context->Length_High >> 24); 00959 context->Message_Block[117] = (uint8_t)(context->Length_High >> 16); 00960 context->Message_Block[118] = (uint8_t)(context->Length_High >> 8); 00961 context->Message_Block[119] = (uint8_t)(context->Length_High); 00962 00963 context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56); 00964 context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48); 00965 context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40); 00966 context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32); 00967 context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24); 00968 context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16); 00969 context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8); 00970 context->Message_Block[127] = (uint8_t)(context->Length_Low); 00971 #endif /* USE_32BIT_ONLY */ 00972 00973 SHA384_512ProcessMessageBlock(context); 00974 } 00975 00976 /* 00977 * SHA384_512ResultN 00978 * 00979 * Description: 00980 * This helper function will return the 384-bit or 512-bit message 00981 * digest into the Message_Digest array provided by the caller. 00982 * NOTE: 00983 * The first octet of hash is stored in the element with index 0, 00984 * the last octet of hash in the element with index 47/63. 00985 * 00986 * Parameters: 00987 * context: [in/out] 00988 * The context to use to calculate the SHA hash. 00989 * Message_Digest[ ]: [out] 00990 * Where the digest is returned. 00991 * HashSize: [in] 00992 * The size of the hash, either 48 or 64. 00993 * 00994 * Returns: 00995 * sha Error Code. 00996 * 00997 */ 00998 static int SHA384_512ResultN(SHA512Context *context, 00999 uint8_t Message_Digest[ ], int HashSize) 01000 { 01001 int i; 01002 #ifdef USE_32BIT_ONLY 01003 int i2; 01004 #endif /* USE_32BIT_ONLY */ 01005 01006 if (!context) return shaNull; 01007 if (!Message_Digest) return shaNull; 01008 if (context->Corrupted) return context->Corrupted; 01009 01010 if (!context->Computed) 01011 SHA384_512Finalize(context, 0x80); 01012 01013 #ifdef USE_32BIT_ONLY 01014 for (i = i2 = 0; i < HashSize; ) { 01015 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>24); 01016 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>16); 01017 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>8); 01018 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2++]); 01019 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>24); 01020 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>16); 01021 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>8); 01022 Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2++]); 01023 } 01024 #else /* !USE_32BIT_ONLY */ 01025 for (i = 0; i < HashSize; ++i) 01026 Message_Digest[i] = (uint8_t) 01027 (context->Intermediate_Hash[i>>3] >> 8 * ( 7 - ( i % 8 ) )); 01028 #endif /* USE_32BIT_ONLY */ 01029 01030 return shaSuccess; 01031 }