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