src/network/sha1.cc

00001 /*
00002  *      sha1.cpp
00003  *
00004  *      Copyright (C) 1998
00005  *      Paul E. Jones <paulej@arid.us>
00006  *      All Rights Reserved.
00007  *
00008  *****************************************************************************
00009  *      $Id: sha1.cpp,v 1.9 2004/03/27 18:02:20 paulej Exp $
00010  *****************************************************************************
00011  *
00012  *      Description:
00013  *              This class implements the Secure Hashing Standard as defined
00014  *              in FIPS PUB 180-1 published April 17, 1995.
00015  *
00016  *              The Secure Hashing Standard, which uses the Secure Hashing
00017  *              Algorithm (SHA), produces a 160-bit message digest for a
00018  *              given data stream.  In theory, it is highly improbable that
00019  *              two messages will produce the same message digest.  Therefore,
00020  *              this algorithm can serve as a means of providing a "fingerprint"
00021  *              for a message.
00022  *
00023  *      Portability Issues:
00024  *              SHA-1 is defined in terms of 32-bit "words".  This code was
00025  *              written with the expectation that the processor has at least
00026  *              a 32-bit machine word size.  If the machine word size is larger,
00027  *              the code should still function properly.  One caveat to that
00028  *              is that the input functions taking characters and character arrays
00029  *              assume that only 8 bits of information are stored in each character.
00030  *
00031  *      Caveats:
00032  *              SHA-1 is designed to work with messages less than 2^64 bits long.
00033  *              Although SHA-1 allows a message digest to be generated for
00034  *              messages of any number of bits less than 2^64, this implementation
00035  *              only works with messages with a length that is a multiple of 8
00036  *              bits.
00037  *
00038  */
00039 
00040 #include "sha1.h"
00041 
00042 /*      
00043  *      SHA1
00044  *
00045  *      Description:
00046  *              This is the constructor for the sha1 class.
00047  *
00048  *      Parameters:
00049  *              None.
00050  *
00051  *      Returns:
00052  *              Nothing.
00053  *
00054  *      Comments:
00055  *
00056  */
00057 SHA1::SHA1()
00058 {
00059         Reset();
00060 }
00061 
00062 /*      
00063  *      ~SHA1
00064  *
00065  *      Description:
00066  *              This is the destructor for the sha1 class
00067  *
00068  *      Parameters:
00069  *              None.
00070  *
00071  *      Returns:
00072  *              Nothing.
00073  *
00074  *      Comments:
00075  *
00076  */
00077 SHA1::~SHA1()
00078 {
00079         // The destructor does nothing
00080 }
00081 
00082 /*      
00083  *      Reset
00084  *
00085  *      Description:
00086  *              This function will initialize the sha1 class member variables
00087  *              in preparation for computing a new message digest.
00088  *
00089  *      Parameters:
00090  *              None.
00091  *
00092  *      Returns:
00093  *              Nothing.
00094  *
00095  *      Comments:
00096  *
00097  */
00098 void SHA1::Reset()
00099 {
00100         Length_Low                      = 0;
00101         Length_High                     = 0;
00102         Message_Block_Index     = 0;
00103 
00104         H[0]            = 0x67452301;
00105         H[1]            = 0xEFCDAB89;
00106         H[2]            = 0x98BADCFE;
00107         H[3]            = 0x10325476;
00108         H[4]            = 0xC3D2E1F0;
00109 
00110         Computed        = false;
00111         Corrupted       = false;
00112 }
00113 
00114 /*      
00115  *      Result
00116  *
00117  *      Description:
00118  *              This function will return the 160-bit message digest into the
00119  *              array provided.
00120  *
00121  *      Parameters:
00122  *              message_digest_array: [out]
00123  *                      This is an array of five unsigned integers which will be filled
00124  *                      with the message digest that has been computed.
00125  *
00126  *      Returns:
00127  *              True if successful, false if it failed.
00128  *
00129  *      Comments:
00130  *
00131  */
00132 bool SHA1::Result(unsigned *message_digest_array)
00133 {
00134         int i;                                                                  // Counter
00135 
00136         if (Corrupted)
00137         {
00138                 return false;
00139         }
00140 
00141         if (!Computed)
00142         {
00143                 PadMessage();
00144                 Computed = true;
00145         }
00146 
00147         for(i = 0; i < 5; i++)
00148         {
00149                 message_digest_array[i] = H[i];
00150         }
00151 
00152         return true;
00153 }
00154 
00155 /*      
00156  *      Input
00157  *
00158  *      Description:
00159  *              This function accepts an array of octets as the next portion of
00160  *              the message.
00161  *
00162  *      Parameters:
00163  *              message_array: [in]
00164  *                      An array of characters representing the next portion of the
00165  *                      message.
00166  *
00167  *      Returns:
00168  *              Nothing.
00169  *
00170  *      Comments:
00171  *
00172  */
00173 void SHA1::Input(       const unsigned char     *message_array,
00174                                         unsigned                        length)
00175 {
00176         if (!length)
00177         {
00178                 return;
00179         }
00180 
00181         if (Computed || Corrupted)
00182         {
00183                 Corrupted = true;
00184                 return;
00185         }
00186 
00187         while(length-- && !Corrupted)
00188         {
00189                 Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
00190 
00191                 Length_Low += 8;
00192                 Length_Low &= 0xFFFFFFFF;                               // Force it to 32 bits
00193                 if (Length_Low == 0)
00194                 {
00195                         Length_High++;
00196                         Length_High &= 0xFFFFFFFF;                      // Force it to 32 bits
00197                         if (Length_High == 0)
00198                         {
00199                                 Corrupted = true;                               // Message is too long
00200                         }
00201                 }
00202 
00203                 if (Message_Block_Index == 64)
00204                 {
00205                         ProcessMessageBlock();
00206                 }
00207 
00208                 message_array++;
00209         }
00210 }
00211 
00212 /*      
00213  *      Input
00214  *
00215  *      Description:
00216  *              This function accepts an array of octets as the next portion of
00217  *              the message.
00218  *
00219  *      Parameters:
00220  *              message_array: [in]
00221  *                      An array of characters representing the next portion of the
00222  *                      message.
00223  *              length: [in]
00224  *                      The length of the message_array
00225  *
00226  *      Returns:
00227  *              Nothing.
00228  *
00229  *      Comments:
00230  *
00231  */
00232 void SHA1::Input(       const char      *message_array,
00233                                         unsigned        length)
00234 {
00235         Input((unsigned char *) message_array, length);
00236 }
00237 
00238 /*      
00239  *      Input
00240  *
00241  *      Description:
00242  *              This function accepts a single octets as the next message element.
00243  *
00244  *      Parameters:
00245  *              message_element: [in]
00246  *                      The next octet in the message.
00247  *
00248  *      Returns:
00249  *              Nothing.
00250  *
00251  *      Comments:
00252  *
00253  */
00254 void SHA1::Input(unsigned char message_element)
00255 {
00256         Input(&message_element, 1);
00257 }
00258 
00259 /*      
00260  *      Input
00261  *
00262  *      Description:
00263  *              This function accepts a single octet as the next message element.
00264  *
00265  *      Parameters:
00266  *              message_element: [in]
00267  *                      The next octet in the message.
00268  *
00269  *      Returns:
00270  *              Nothing.
00271  *
00272  *      Comments:
00273  *
00274  */
00275 void SHA1::Input(char message_element)
00276 {
00277         Input((unsigned char *) &message_element, 1);
00278 }
00279 
00280 /*      
00281  *      operator<<
00282  *
00283  *      Description:
00284  *              This operator makes it convenient to provide character strings to
00285  *              the SHA1 object for processing.
00286  *
00287  *      Parameters:
00288  *              message_array: [in]
00289  *                      The character array to take as input.
00290  *
00291  *      Returns:
00292  *              A reference to the SHA1 object.
00293  *
00294  *      Comments:
00295  *              Each character is assumed to hold 8 bits of information.
00296  *
00297  */
00298 SHA1& SHA1::operator<<(const char *message_array)
00299 {
00300         const char *p = message_array;
00301 
00302         while(*p)
00303         {
00304                 Input(*p);
00305                 p++;
00306         }
00307 
00308         return *this;
00309 }
00310 
00311 /*      
00312  *      operator<<
00313  *
00314  *      Description:
00315  *              This operator makes it convenient to provide character strings to
00316  *              the SHA1 object for processing.
00317  *
00318  *      Parameters:
00319  *              message_array: [in]
00320  *                      The character array to take as input.
00321  *
00322  *      Returns:
00323  *              A reference to the SHA1 object.
00324  *
00325  *      Comments:
00326  *              Each character is assumed to hold 8 bits of information.
00327  *
00328  */
00329 SHA1& SHA1::operator<<(const unsigned char *message_array)
00330 {
00331         const unsigned char *p = message_array;
00332 
00333         while(*p)
00334         {
00335                 Input(*p);
00336                 p++;
00337         }
00338 
00339         return *this;
00340 }
00341 
00342 /*      
00343  *      operator<<
00344  *
00345  *      Description:
00346  *              This function provides the next octet in the message.
00347  *
00348  *      Parameters:
00349  *              message_element: [in]
00350  *                      The next octet in the message
00351  *
00352  *      Returns:
00353  *              A reference to the SHA1 object.
00354  *
00355  *      Comments:
00356  *              The character is assumed to hold 8 bits of information.
00357  *
00358  */
00359 SHA1& SHA1::operator<<(const char message_element)
00360 {
00361         Input((unsigned char *) &message_element, 1);
00362 
00363         return *this;
00364 }
00365 
00366 /*      
00367  *      operator<<
00368  *
00369  *      Description:
00370  *              This function provides the next octet in the message.
00371  *
00372  *      Parameters:
00373  *              message_element: [in]
00374  *                      The next octet in the message
00375  *
00376  *      Returns:
00377  *              A reference to the SHA1 object.
00378  *
00379  *      Comments:
00380  *              The character is assumed to hold 8 bits of information.
00381  *
00382  */
00383 SHA1& SHA1::operator<<(const unsigned char message_element)
00384 {
00385         Input(&message_element, 1);
00386 
00387         return *this;
00388 }
00389 
00390 /*      
00391  *      ProcessMessageBlock
00392  *
00393  *      Description:
00394  *              This function will process the next 512 bits of the message
00395  *              stored in the Message_Block array.
00396  *
00397  *      Parameters:
00398  *              None.
00399  *
00400  *      Returns:
00401  *              Nothing.
00402  *
00403  *      Comments:
00404  *              Many of the variable names in this function, especially the single
00405  *              character names, were used because those were the names used
00406  *              in the publication.
00407  *
00408  */
00409 void SHA1::ProcessMessageBlock()
00410 {
00411         const unsigned K[] =    {                               // Constants defined for SHA-1
00412                                                                 0x5A827999,
00413                                                                 0x6ED9EBA1,
00414                                                                 0x8F1BBCDC,
00415                                                                 0xCA62C1D6
00416                                                         };
00417         int             t;                                                      // Loop counter
00418         unsigned        temp;                                           // Temporary word value
00419         unsigned        W[80];                                          // Word sequence
00420         unsigned        A, B, C, D, E;                          // Word buffers
00421 
00422         /*
00423          *      Initialize the first 16 words in the array W
00424          */
00425         for(t = 0; t < 16; t++)
00426         {
00427                 W[t] = ((unsigned) Message_Block[t * 4]) << 24;
00428                 W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16;
00429                 W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8;
00430                 W[t] |= ((unsigned) Message_Block[t * 4 + 3]);
00431         }
00432 
00433         for(t = 16; t < 80; t++)
00434         {
00435            W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
00436         }
00437 
00438         A = H[0];
00439         B = H[1];
00440         C = H[2];
00441         D = H[3];
00442         E = H[4];
00443 
00444         for(t = 0; t < 20; t++)
00445         {
00446                 temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
00447                 temp &= 0xFFFFFFFF;
00448                 E = D;
00449                 D = C;
00450                 C = CircularShift(30,B);
00451                 B = A;
00452                 A = temp;
00453         }
00454 
00455         for(t = 20; t < 40; t++)
00456         {
00457                 temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
00458                 temp &= 0xFFFFFFFF;
00459                 E = D;
00460                 D = C;
00461                 C = CircularShift(30,B);
00462                 B = A;
00463                 A = temp;
00464         }
00465 
00466         for(t = 40; t < 60; t++)
00467         {
00468                 temp = CircularShift(5,A) +
00469                            ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
00470                 temp &= 0xFFFFFFFF;
00471                 E = D;
00472                 D = C;
00473                 C = CircularShift(30,B);
00474                 B = A;
00475                 A = temp;
00476         }
00477 
00478         for(t = 60; t < 80; t++)
00479         {
00480                 temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
00481                 temp &= 0xFFFFFFFF;
00482                 E = D;
00483                 D = C;
00484                 C = CircularShift(30,B);
00485                 B = A;
00486                 A = temp;
00487         }
00488 
00489         H[0] = (H[0] + A) & 0xFFFFFFFF;
00490         H[1] = (H[1] + B) & 0xFFFFFFFF;
00491         H[2] = (H[2] + C) & 0xFFFFFFFF;
00492         H[3] = (H[3] + D) & 0xFFFFFFFF;
00493         H[4] = (H[4] + E) & 0xFFFFFFFF;
00494 
00495         Message_Block_Index = 0;
00496 }
00497 
00498 /*      
00499  *      PadMessage
00500  *
00501  *      Description:
00502  *              According to the standard, the message must be padded to an even
00503  *              512 bits.  The first padding bit must be a '1'.  The last 64 bits
00504  *              represent the length of the original message.  All bits in between
00505  *              should be 0.  This function will pad the message according to those
00506  *              rules by filling the message_block array accordingly.  It will also
00507  *              call ProcessMessageBlock() appropriately.  When it returns, it
00508  *              can be assumed that the message digest has been computed.
00509  *
00510  *      Parameters:
00511  *              None.
00512  *
00513  *      Returns:
00514  *              Nothing.
00515  *
00516  *      Comments:
00517  *
00518  */
00519 void SHA1::PadMessage()
00520 {
00521         /*
00522          *      Check to see if the current message block is too small to hold
00523          *      the initial padding bits and length.  If so, we will pad the
00524          *      block, process it, and then continue padding into a second block.
00525          */
00526         if (Message_Block_Index > 55)
00527         {
00528                 Message_Block[Message_Block_Index++] = 0x80;
00529                 while(Message_Block_Index < 64)
00530                 {
00531                         Message_Block[Message_Block_Index++] = 0;
00532                 }
00533 
00534                 ProcessMessageBlock();
00535 
00536                 while(Message_Block_Index < 56)
00537                 {
00538                         Message_Block[Message_Block_Index++] = 0;
00539                 }
00540         }
00541         else
00542         {
00543                 Message_Block[Message_Block_Index++] = 0x80;
00544                 while(Message_Block_Index < 56)
00545                 {
00546                         Message_Block[Message_Block_Index++] = 0;
00547                 }
00548 
00549         }
00550 
00551         /*
00552          *      Store the message length as the last 8 octets
00553          */
00554         Message_Block[56] = (Length_High >> 24) & 0xFF;
00555         Message_Block[57] = (Length_High >> 16) & 0xFF;
00556         Message_Block[58] = (Length_High >> 8) & 0xFF;
00557         Message_Block[59] = (Length_High) & 0xFF;
00558         Message_Block[60] = (Length_Low >> 24) & 0xFF;
00559         Message_Block[61] = (Length_Low >> 16) & 0xFF;
00560         Message_Block[62] = (Length_Low >> 8) & 0xFF;
00561         Message_Block[63] = (Length_Low) & 0xFF;
00562 
00563         ProcessMessageBlock();
00564 }
00565 
00566 
00567 /*      
00568  *      CircularShift
00569  *
00570  *      Description:
00571  *              This member function will perform a circular shifting operation.
00572  *
00573  *      Parameters:
00574  *              bits: [in]
00575  *                      The number of bits to shift (1-31)
00576  *              word: [in]
00577  *                      The value to shift (assumes a 32-bit integer)
00578  *
00579  *      Returns:
00580  *              The shifted value.
00581  *
00582  *      Comments:
00583  *
00584  */
00585 unsigned SHA1::CircularShift(int bits, unsigned word)
00586 {
00587         return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
00588 }

Generated on Mon Dec 3 04:30:13 2007 for lo-testserver by  doxygen 1.3.9.1