libmoost
/home/mhx/git/github/libmoost/src/digest/rfc6234/sha224-256.c
Go to the documentation of this file.
00001 /************************* sha224-256.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-224 and
00010  *   SHA-256 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-224 and SHA-256 algorithms produce 224-bit and 256-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-224 and SHA-256 are defined in terms of 32-bit "words".
00030  *   This code uses <stdint.h> (included via "sha.h") to define 32-
00031  *   and 8-bit unsigned integer types.  If your C compiler does not
00032  *   support 32-bit unsigned integers, this code is not
00033  *   appropriate.
00034  *
00035  * Caveats:
00036  *   SHA-224 and SHA-256 are designed to work with messages less
00037  *   than 2^64 bits long.  This implementation uses SHA224/256Input()
00038  *   to hash the bits that are a multiple of the size of an 8-bit
00039  *   octet, and then optionally uses SHA224/256FinalBits()
00040  *   to hash the final few bits of the input.
00041  */
00042 
00043 #include "sha.h"
00044 #include "sha-private.h"
00045 
00046 /* Define the SHA shift, rotate left, and rotate right macros */
00047 #define SHA256_SHR(bits,word)      ((word) >> (bits))
00048 #define SHA256_ROTL(bits,word)                         \
00049   (((word) << (bits)) | ((word) >> (32-(bits))))
00050 #define SHA256_ROTR(bits,word)                         \
00051   (((word) >> (bits)) | ((word) << (32-(bits))))
00052 
00053 /* Define the SHA SIGMA and sigma macros */
00054 #define SHA256_SIGMA0(word)   \
00055   (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word))
00056 #define SHA256_SIGMA1(word)   \
00057   (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word))
00058 #define SHA256_sigma0(word)   \
00059   (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word))
00060 #define SHA256_sigma1(word)   \
00061   (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word))
00062 
00063 /*
00064  * Add "length" to the length.
00065  * Set Corrupted when overflow has occurred.
00066  */
00067 static uint32_t addTemp;
00068 #define SHA224_256AddLength(context, length)               \
00069   (addTemp = (context)->Length_Low, (context)->Corrupted = \
00070     (((context)->Length_Low += (length)) < addTemp) &&     \
00071     (++(context)->Length_High == 0) ? shaInputTooLong :    \
00072                                       (context)->Corrupted )
00073 
00074 /* Local Function Prototypes */
00075 static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);
00076 static void SHA224_256ProcessMessageBlock(SHA256Context *context);
00077 static void SHA224_256Finalize(SHA256Context *context,
00078   uint8_t Pad_Byte);
00079 static void SHA224_256PadMessage(SHA256Context *context,
00080   uint8_t Pad_Byte);
00081 static int SHA224_256ResultN(SHA256Context *context,
00082   uint8_t Message_Digest[ ], int HashSize);
00083 
00084 /* Initial Hash Values: FIPS 180-3 section 5.3.2 */
00085 static uint32_t SHA224_H0[SHA256HashSize/4] = {
00086     0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
00087     0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
00088 };
00089 
00090 /* Initial Hash Values: FIPS 180-3 section 5.3.3 */
00091 static uint32_t SHA256_H0[SHA256HashSize/4] = {
00092   0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
00093   0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
00094 };
00095 
00096 /*
00097  * SHA224Reset
00098  *
00099  * Description:
00100  *   This function will initialize the SHA224Context in preparation
00101  *   for computing a new SHA224 message digest.
00102  *
00103  * Parameters:
00104  *   context: [in/out]
00105  *     The context to reset.
00106  *
00107  * Returns:
00108  *   sha Error Code.
00109  */
00110 int SHA224Reset(SHA224Context *context)
00111 {
00112   return SHA224_256Reset(context, SHA224_H0);
00113 }
00114 
00115 /*
00116  * SHA224Input
00117  *
00118  * Description:
00119  *   This function accepts an array of octets as the next portion
00120  *   of the message.
00121  *
00122  * Parameters:
00123  *   context: [in/out]
00124  *     The SHA context to update.
00125  *   message_array[ ]: [in]
00126  *     An array of octets representing the next portion of
00127  *     the message.
00128  *   length: [in]
00129  *     The length of the message in message_array.
00130  *
00131  * Returns:
00132  *   sha Error Code.
00133  *
00134  */
00135 int SHA224Input(SHA224Context *context, const uint8_t *message_array,
00136     unsigned int length)
00137 {
00138   return SHA256Input(context, message_array, length);
00139 }
00140 
00141 /*
00142  * SHA224FinalBits
00143  *
00144  * Description:
00145  *   This function will add in any final bits of the message.
00146  *
00147  * Parameters:
00148  *   context: [in/out]
00149  *     The SHA context to update.
00150  *   message_bits: [in]
00151  *     The final bits of the message, in the upper portion of the
00152  *     byte.  (Use 0b###00000 instead of 0b00000### to input the
00153  *     three bits ###.)
00154  *   length: [in]
00155  *     The number of bits in message_bits, between 1 and 7.
00156  *
00157  * Returns:
00158  *   sha Error Code.
00159  */
00160 int SHA224FinalBits(SHA224Context *context,
00161                     uint8_t message_bits, unsigned int length)
00162 {
00163   return SHA256FinalBits(context, message_bits, length);
00164 }
00165 
00166 /*
00167  * SHA224Result
00168  *
00169  * Description:
00170  *   This function will return the 224-bit message digest
00171  *   into the Message_Digest array provided by the caller.
00172  *   NOTE:
00173  *    The first octet of hash is stored in the element with index 0,
00174  *    the last octet of hash in the element with index 27.
00175  *
00176  * Parameters:
00177  *   context: [in/out]
00178  *     The context to use to calculate the SHA hash.
00179  *   Message_Digest[ ]: [out]
00180  *     Where the digest is returned.
00181  *
00182  * Returns:
00183  *   sha Error Code.
00184  */
00185 int SHA224Result(SHA224Context *context,
00186     uint8_t Message_Digest[SHA224HashSize])
00187 {
00188   return SHA224_256ResultN(context, Message_Digest, SHA224HashSize);
00189 }
00190 
00191 /*
00192  * SHA256Reset
00193  *
00194  * Description:
00195  *   This function will initialize the SHA256Context in preparation
00196  *   for computing a new SHA256 message digest.
00197  *
00198  * Parameters:
00199  *   context: [in/out]
00200  *     The context to reset.
00201  *
00202  * Returns:
00203  *   sha Error Code.
00204  */
00205 int SHA256Reset(SHA256Context *context)
00206 {
00207   return SHA224_256Reset(context, SHA256_H0);
00208 }
00209 
00210 /*
00211  * SHA256Input
00212  *
00213  * Description:
00214  *   This function accepts an array of octets as the next portion
00215  *   of the message.
00216  *
00217  * Parameters:
00218  *   context: [in/out]
00219  *     The SHA context to update.
00220  *   message_array[ ]: [in]
00221  *     An array of octets representing the next portion of
00222  *     the message.
00223  *   length: [in]
00224  *     The length of the message in message_array.
00225  *
00226  * Returns:
00227  *   sha Error Code.
00228  */
00229 int SHA256Input(SHA256Context *context, const uint8_t *message_array,
00230     unsigned int length)
00231 {
00232   if (!context) return shaNull;
00233   if (!length) return shaSuccess;
00234   if (!message_array) return shaNull;
00235   if (context->Computed) return context->Corrupted = shaStateError;
00236   if (context->Corrupted) return context->Corrupted;
00237 
00238   while (length--) {
00239     context->Message_Block[context->Message_Block_Index++] =
00240             *message_array;
00241 
00242     if ((SHA224_256AddLength(context, 8) == shaSuccess) &&
00243       (context->Message_Block_Index == SHA256_Message_Block_Size))
00244       SHA224_256ProcessMessageBlock(context);
00245 
00246     message_array++;
00247   }
00248 
00249   return context->Corrupted;
00250 
00251 }
00252 
00253 /*
00254  * SHA256FinalBits
00255  *
00256  * Description:
00257  *   This function will add in any final bits of the message.
00258  *
00259  * Parameters:
00260  *   context: [in/out]
00261  *     The SHA context to update.
00262  *   message_bits: [in]
00263  *     The final bits of the message, in the upper portion of the
00264  *     byte.  (Use 0b###00000 instead of 0b00000### to input the
00265  *     three bits ###.)
00266  *   length: [in]
00267  *     The number of bits in message_bits, between 1 and 7.
00268  *
00269  * Returns:
00270  *   sha Error Code.
00271  */
00272 int SHA256FinalBits(SHA256Context *context,
00273                     uint8_t message_bits, unsigned int length)
00274 {
00275   static uint8_t masks[8] = {
00276       /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
00277       /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
00278       /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
00279       /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
00280   };
00281   static uint8_t markbit[8] = {
00282       /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
00283       /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
00284       /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
00285       /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
00286   };
00287 
00288   if (!context) return shaNull;
00289   if (!length) return shaSuccess;
00290   if (context->Corrupted) return context->Corrupted;
00291   if (context->Computed) return context->Corrupted = shaStateError;
00292   if (length >= 8) return context->Corrupted = shaBadParam;
00293 
00294   SHA224_256AddLength(context, length);
00295   SHA224_256Finalize(context, (uint8_t)
00296     ((message_bits & masks[length]) | markbit[length]));
00297 
00298   return context->Corrupted;
00299 }
00300 
00301 /*
00302  * SHA256Result
00303  *
00304  * Description:
00305  *   This function will return the 256-bit message digest
00306  *   into the Message_Digest array provided by the caller.
00307  *   NOTE:
00308  *    The first octet of hash is stored in the element with index 0,
00309  *    the last octet of hash in the element with index 31.
00310  *
00311  * Parameters:
00312  *   context: [in/out]
00313  *     The context to use to calculate the SHA hash.
00314  *   Message_Digest[ ]: [out]
00315  *     Where the digest is returned.
00316  *
00317  * Returns:
00318  *   sha Error Code.
00319  */
00320 int SHA256Result(SHA256Context *context,
00321                  uint8_t Message_Digest[SHA256HashSize])
00322 {
00323   return SHA224_256ResultN(context, Message_Digest, SHA256HashSize);
00324 }
00325 
00326 /*
00327  * SHA224_256Reset
00328  *
00329  * Description:
00330  *   This helper function will initialize the SHA256Context in
00331  *   preparation for computing a new SHA-224 or SHA-256 message digest.
00332  *
00333  * Parameters:
00334  *   context: [in/out]
00335  *     The context to reset.
00336  *   H0[ ]: [in]
00337  *     The initial hash value array to use.
00338  *
00339  * Returns:
00340  *   sha Error Code.
00341  */
00342 static int SHA224_256Reset(SHA256Context *context, uint32_t *H0)
00343 {
00344   if (!context) return shaNull;
00345 
00346   context->Length_High = context->Length_Low = 0;
00347   context->Message_Block_Index  = 0;
00348 
00349   context->Intermediate_Hash[0] = H0[0];
00350   context->Intermediate_Hash[1] = H0[1];
00351   context->Intermediate_Hash[2] = H0[2];
00352   context->Intermediate_Hash[3] = H0[3];
00353   context->Intermediate_Hash[4] = H0[4];
00354   context->Intermediate_Hash[5] = H0[5];
00355   context->Intermediate_Hash[6] = H0[6];
00356   context->Intermediate_Hash[7] = H0[7];
00357 
00358   context->Computed  = 0;
00359   context->Corrupted = shaSuccess;
00360 
00361   return shaSuccess;
00362 }
00363 
00364 /*
00365  * SHA224_256ProcessMessageBlock
00366  *
00367  * Description:
00368  *   This helper function will process the next 512 bits of the
00369  *   message stored in the Message_Block array.
00370  *
00371  * Parameters:
00372  *   context: [in/out]
00373  *     The SHA context to update.
00374  *
00375  * Returns:
00376  *   Nothing.
00377  *
00378  * Comments:
00379  *   Many of the variable names in this code, especially the
00380  *   single character names, were used because those were the
00381  *   names used in the Secure Hash Standard.
00382  */
00383 static void SHA224_256ProcessMessageBlock(SHA256Context *context)
00384 {
00385   /* Constants defined in FIPS 180-3, section 4.2.2 */
00386   static const uint32_t K[64] = {
00387       0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
00388       0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
00389       0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
00390       0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00391       0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
00392       0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
00393       0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
00394       0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00395       0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
00396       0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
00397       0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
00398       0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00399       0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00400   };
00401   int        t, t4;                   /* Loop counter */
00402   uint32_t   temp1, temp2;            /* Temporary word value */
00403   uint32_t   W[64];                   /* Word sequence */
00404   uint32_t   A, B, C, D, E, F, G, H;  /* Word buffers */
00405 
00406   /*
00407    * Initialize the first 16 words in the array W
00408    */
00409   for (t = t4 = 0; t < 16; t++, t4 += 4)
00410     W[t] = (((uint32_t)context->Message_Block[t4]) << 24) |
00411            (((uint32_t)context->Message_Block[t4 + 1]) << 16) |
00412            (((uint32_t)context->Message_Block[t4 + 2]) << 8) |
00413            (((uint32_t)context->Message_Block[t4 + 3]));
00414 
00415   for (t = 16; t < 64; t++)
00416     W[t] = SHA256_sigma1(W[t-2]) + W[t-7] +
00417         SHA256_sigma0(W[t-15]) + W[t-16];
00418 
00419   A = context->Intermediate_Hash[0];
00420   B = context->Intermediate_Hash[1];
00421   C = context->Intermediate_Hash[2];
00422   D = context->Intermediate_Hash[3];
00423   E = context->Intermediate_Hash[4];
00424   F = context->Intermediate_Hash[5];
00425   G = context->Intermediate_Hash[6];
00426   H = context->Intermediate_Hash[7];
00427 
00428   for (t = 0; t < 64; t++) {
00429     temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
00430     temp2 = SHA256_SIGMA0(A) + SHA_Maj(A,B,C);
00431     H = G;
00432     G = F;
00433     F = E;
00434     E = D + temp1;
00435     D = C;
00436     C = B;
00437     B = A;
00438     A = temp1 + temp2;
00439   }
00440 
00441   context->Intermediate_Hash[0] += A;
00442   context->Intermediate_Hash[1] += B;
00443   context->Intermediate_Hash[2] += C;
00444   context->Intermediate_Hash[3] += D;
00445   context->Intermediate_Hash[4] += E;
00446   context->Intermediate_Hash[5] += F;
00447   context->Intermediate_Hash[6] += G;
00448   context->Intermediate_Hash[7] += H;
00449 
00450   context->Message_Block_Index = 0;
00451 }
00452 
00453 /*
00454  * SHA224_256Finalize
00455  *
00456  * Description:
00457  *   This helper function finishes off the digest calculations.
00458  *
00459  * Parameters:
00460  *   context: [in/out]
00461  *     The SHA context to update.
00462  *   Pad_Byte: [in]
00463  *     The last byte to add to the message block before the 0-padding
00464  *     and length.  This will contain the last bits of the message
00465  *     followed by another single bit.  If the message was an
00466  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
00467  *
00468  * Returns:
00469  *   sha Error Code.
00470  */
00471 static void SHA224_256Finalize(SHA256Context *context,
00472     uint8_t Pad_Byte)
00473 {
00474   int i;
00475   SHA224_256PadMessage(context, Pad_Byte);
00476   /* message may be sensitive, so clear it out */
00477   for (i = 0; i < SHA256_Message_Block_Size; ++i)
00478     context->Message_Block[i] = 0;
00479   context->Length_High = 0;     /* and clear length */
00480   context->Length_Low = 0;
00481   context->Computed = 1;
00482 }
00483 
00484 /*
00485  * SHA224_256PadMessage
00486  *
00487  * Description:
00488  *   According to the standard, the message must be padded to the next
00489  *   even multiple of 512 bits.  The first padding bit must be a '1'.
00490  *   The last 64 bits represent the length of the original message.
00491  *   All bits in between should be 0.  This helper function will pad
00492  *   the message according to those rules by filling the
00493  *   Message_Block array accordingly.  When it returns, it can be
00494  *   assumed that the message digest has been computed.
00495  *
00496  * Parameters:
00497  *   context: [in/out]
00498  *     The context to pad.
00499  *   Pad_Byte: [in]
00500  *     The last byte to add to the message block before the 0-padding
00501  *     and length.  This will contain the last bits of the message
00502  *     followed by another single bit.  If the message was an
00503  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
00504  *
00505  * Returns:
00506  *   Nothing.
00507  */
00508 static void SHA224_256PadMessage(SHA256Context *context,
00509     uint8_t Pad_Byte)
00510 {
00511   /*
00512    * Check to see if the current message block is too small to hold
00513    * the initial padding bits and length.  If so, we will pad the
00514    * block, process it, and then continue padding into a second
00515    * block.
00516    */
00517   if (context->Message_Block_Index >= (SHA256_Message_Block_Size-8)) {
00518     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
00519     while (context->Message_Block_Index < SHA256_Message_Block_Size)
00520       context->Message_Block[context->Message_Block_Index++] = 0;
00521     SHA224_256ProcessMessageBlock(context);
00522   } else
00523     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
00524 
00525   while (context->Message_Block_Index < (SHA256_Message_Block_Size-8))
00526     context->Message_Block[context->Message_Block_Index++] = 0;
00527 
00528   /*
00529    * Store the message length as the last 8 octets
00530    */
00531   context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
00532   context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
00533   context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
00534   context->Message_Block[59] = (uint8_t)(context->Length_High);
00535   context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
00536   context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
00537   context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
00538   context->Message_Block[63] = (uint8_t)(context->Length_Low);
00539 
00540   SHA224_256ProcessMessageBlock(context);
00541 }
00542 
00543 /*
00544  * SHA224_256ResultN
00545  *
00546  * Description:
00547  *   This helper function will return the 224-bit or 256-bit message
00548  *   digest into the Message_Digest array provided by the caller.
00549  *   NOTE:
00550  *    The first octet of hash is stored in the element with index 0,
00551  *    the last octet of hash in the element with index 27/31.
00552  *
00553  * Parameters:
00554  *   context: [in/out]
00555  *     The context to use to calculate the SHA hash.
00556  *   Message_Digest[ ]: [out]
00557  *     Where the digest is returned.
00558  *   HashSize: [in]
00559  *     The size of the hash, either 28 or 32.
00560  *
00561  * Returns:
00562  *   sha Error Code.
00563  */
00564 static int SHA224_256ResultN(SHA256Context *context,
00565     uint8_t Message_Digest[ ], int HashSize)
00566 {
00567   int i;
00568 
00569   if (!context) return shaNull;
00570   if (!Message_Digest) return shaNull;
00571   if (context->Corrupted) return context->Corrupted;
00572 
00573   if (!context->Computed)
00574     SHA224_256Finalize(context, 0x80);
00575 
00576   for (i = 0; i < HashSize; ++i)
00577     Message_Digest[i] = (uint8_t)
00578       (context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ));
00579 
00580   return shaSuccess;
00581 }