Azure IoT / azure_c_shared_utility

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha384-512.c Source File

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