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