Mark Radbourne / Mbed 2 deprecated iothub_client_sample_amqp

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

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 #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