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