• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

SHA1.cpp

Go to the documentation of this file.
00001 
00021 #include "SHA1.h"
00022 #include <stdlib.h>
00023 
00024 
00025 CSHA1::CSHA1()
00026 {
00027         Reset();
00028 }
00029 
00030 CSHA1::~CSHA1()
00031 {
00032         Reset();
00033 }
00034 
00035 
00036 void CSHA1::Reset()
00037 {
00038         // SHA1 initialization constants
00039         m_state[ 0 ] = 0x67452301;
00040         m_state[ 1 ] = 0xEFCDAB89;
00041         m_state[ 2 ] = 0x98BADCFE;
00042         m_state[ 3 ] = 0x10325476;
00043         m_state[ 4 ] = 0xC3D2E1F0;
00044 
00045         m_count[ 0 ] = 0;
00046         m_count[ 1 ] = 0;
00047 }
00048 
00049 void CSHA1::Transform( unsigned int state[ 5 ], unsigned char buffer[ 64 ] )
00050 {
00051         unsigned int a = 0, b = 0, c = 0, d = 0, e = 0;
00052 
00053         SHA1_WORKSPACE_BLOCK* block;
00054         // static unsigned char workspace[64];
00055         block = ( SHA1_WORKSPACE_BLOCK * ) workspace;
00056         memcpy( block, buffer, 64 );
00057 
00058         // Copy state[] to working vars
00059         a = state[ 0 ];
00060         b = state[ 1 ];
00061         c = state[ 2 ];
00062         d = state[ 3 ];
00063         e = state[ 4 ];
00064 
00065         // 4 rounds of 20 operations each. Loop unrolled.
00066         R0( a, b, c, d, e, 0 );
00067         R0( e, a, b, c, d, 1 );
00068         R0( d, e, a, b, c, 2 );
00069         R0( c, d, e, a, b, 3 );
00070         R0( b, c, d, e, a, 4 );
00071         R0( a, b, c, d, e, 5 );
00072         R0( e, a, b, c, d, 6 );
00073         R0( d, e, a, b, c, 7 );
00074         R0( c, d, e, a, b, 8 );
00075         R0( b, c, d, e, a, 9 );
00076         R0( a, b, c, d, e, 10 );
00077         R0( e, a, b, c, d, 11 );
00078         R0( d, e, a, b, c, 12 );
00079         R0( c, d, e, a, b, 13 );
00080         R0( b, c, d, e, a, 14 );
00081         R0( a, b, c, d, e, 15 );
00082         R1( e, a, b, c, d, 16 );
00083         R1( d, e, a, b, c, 17 );
00084         R1( c, d, e, a, b, 18 );
00085         R1( b, c, d, e, a, 19 );
00086         R2( a, b, c, d, e, 20 );
00087         R2( e, a, b, c, d, 21 );
00088         R2( d, e, a, b, c, 22 );
00089         R2( c, d, e, a, b, 23 );
00090         R2( b, c, d, e, a, 24 );
00091         R2( a, b, c, d, e, 25 );
00092         R2( e, a, b, c, d, 26 );
00093         R2( d, e, a, b, c, 27 );
00094         R2( c, d, e, a, b, 28 );
00095         R2( b, c, d, e, a, 29 );
00096         R2( a, b, c, d, e, 30 );
00097         R2( e, a, b, c, d, 31 );
00098         R2( d, e, a, b, c, 32 );
00099         R2( c, d, e, a, b, 33 );
00100         R2( b, c, d, e, a, 34 );
00101         R2( a, b, c, d, e, 35 );
00102         R2( e, a, b, c, d, 36 );
00103         R2( d, e, a, b, c, 37 );
00104         R2( c, d, e, a, b, 38 );
00105         R2( b, c, d, e, a, 39 );
00106         R3( a, b, c, d, e, 40 );
00107         R3( e, a, b, c, d, 41 );
00108         R3( d, e, a, b, c, 42 );
00109         R3( c, d, e, a, b, 43 );
00110         R3( b, c, d, e, a, 44 );
00111         R3( a, b, c, d, e, 45 );
00112         R3( e, a, b, c, d, 46 );
00113         R3( d, e, a, b, c, 47 );
00114         R3( c, d, e, a, b, 48 );
00115         R3( b, c, d, e, a, 49 );
00116         R3( a, b, c, d, e, 50 );
00117         R3( e, a, b, c, d, 51 );
00118         R3( d, e, a, b, c, 52 );
00119         R3( c, d, e, a, b, 53 );
00120         R3( b, c, d, e, a, 54 );
00121         R3( a, b, c, d, e, 55 );
00122         R3( e, a, b, c, d, 56 );
00123         R3( d, e, a, b, c, 57 );
00124         R3( c, d, e, a, b, 58 );
00125         R3( b, c, d, e, a, 59 );
00126         R4( a, b, c, d, e, 60 );
00127         R4( e, a, b, c, d, 61 );
00128         R4( d, e, a, b, c, 62 );
00129         R4( c, d, e, a, b, 63 );
00130         R4( b, c, d, e, a, 64 );
00131         R4( a, b, c, d, e, 65 );
00132         R4( e, a, b, c, d, 66 );
00133         R4( d, e, a, b, c, 67 );
00134         R4( c, d, e, a, b, 68 );
00135         R4( b, c, d, e, a, 69 );
00136         R4( a, b, c, d, e, 70 );
00137         R4( e, a, b, c, d, 71 );
00138         R4( d, e, a, b, c, 72 );
00139         R4( c, d, e, a, b, 73 );
00140         R4( b, c, d, e, a, 74 );
00141         R4( a, b, c, d, e, 75 );
00142         R4( e, a, b, c, d, 76 );
00143         R4( d, e, a, b, c, 77 );
00144         R4( c, d, e, a, b, 78 );
00145         R4( b, c, d, e, a, 79 );
00146 
00147         // Add the working vars back into state[]
00148         state[ 0 ] += a;
00149         state[ 1 ] += b;
00150         state[ 2 ] += c;
00151         state[ 3 ] += d;
00152         state[ 4 ] += e;
00153 
00154         // Wipe variables
00155         a = 0;
00156         b = 0;
00157         c = 0;
00158         d = 0;
00159         e = 0;
00160 }
00161 
00162 // Use this function to hash in binary data and strings
00163 void CSHA1::Update( unsigned char* data, unsigned int len )
00164 {
00165         unsigned int i = 0, j = 0;
00166 
00167         j = ( m_count[ 0 ] >> 3 ) & 63;
00168 
00169         if ( ( m_count[ 0 ] += len << 3 ) < ( len << 3 ) )
00170                 m_count[ 1 ] ++;
00171 
00172         m_count[ 1 ] += ( len >> 29 );
00173 
00174         if ( ( j + len ) > 63 )
00175         {
00176                 memcpy( &m_buffer[ j ], data, ( i = 64 - j ) );
00177                 Transform( m_state, m_buffer );
00178 
00179                 for ( ; i + 63 < len; i += 64 )
00180                 {
00181                         Transform( m_state, &data[ i ] );
00182                 }
00183 
00184                 j = 0;
00185         }
00186 
00187         else
00188                 i = 0;
00189 
00190         memcpy( &m_buffer[ j ], &data[ i ], len - i );
00191 }
00192 
00193 // Hash in file contents
00194 bool CSHA1::HashFile( char *szFileName )
00195 {
00196         unsigned long ulFileSize = 0, ulRest = 0, ulBlocks = 0;
00197         unsigned long i = 0;
00198         unsigned char uData[ MAX_FILE_READ_BUFFER ];
00199         FILE *fIn = NULL;
00200 
00201         if ( ( fIn = fopen( szFileName, "rb" ) ) == NULL )
00202                 return ( false );
00203 
00204         fseek( fIn, 0, SEEK_END );
00205 
00206         ulFileSize = ftell( fIn );
00207 
00208         fseek( fIn, 0, SEEK_SET );
00209 
00210         // This is faster
00211         div_t temp;
00212 
00213         temp = div( ulFileSize, MAX_FILE_READ_BUFFER );
00214 
00215         ulRest = temp.rem;
00216 
00217         ulBlocks = temp.quot;
00218 
00219         // ulRest = ulFileSize % MAX_FILE_READ_BUFFER;
00220         // ulBlocks = ulFileSize / MAX_FILE_READ_BUFFER;
00221 
00222         for ( i = 0; i < ulBlocks; i++ )
00223         {
00224                 fread( uData, 1, MAX_FILE_READ_BUFFER, fIn );
00225                 Update( uData, MAX_FILE_READ_BUFFER );
00226         }
00227 
00228         if ( ulRest != 0 )
00229         {
00230                 fread( uData, 1, ulRest, fIn );
00231                 Update( uData, ulRest );
00232         }
00233 
00234         fclose( fIn );
00235         fIn = NULL;
00236 
00237         return ( true );
00238 }
00239 
00240 void CSHA1::Final()
00241 {
00242         unsigned int i = 0;
00243         unsigned char finalcount[ 8 ] =
00244         {
00245                 0, 0, 0, 0, 0, 0, 0, 0
00246         };
00247 
00248         for ( i = 0; i < 8; i++ )
00249                 finalcount[ i ] = (unsigned char) ( ( m_count[ ( i >= 4 ? 0 : 1 ) ]
00250                 >> ( ( 3 - ( i & 3 ) ) * 8 ) ) & 255 ); // Endian independent
00251 
00252                 Update( ( unsigned char * ) "\200", 1 );
00253 
00254                 while ( ( m_count[ 0 ] & 504 ) != 448 )
00255                         Update( ( unsigned char * ) "\0", 1 );
00256 
00257                 Update( finalcount, 8 ); // Cause a SHA1Transform()
00258 
00259                 for ( i = 0; i < 20; i++ )
00260                 {
00261                         m_digest[ i ] = (unsigned char) ( ( m_state[ i >> 2 ] >> ( ( 3 - ( i & 3 ) ) * 8 ) ) & 255 );
00262                 }
00263 
00264                 // Wipe variables for security reasons
00265                 i = 0;
00266 
00267 //              j = 0;
00268 
00269                 memset( m_buffer, 0, 64 );
00270 
00271                 memset( m_state, 0, 20 );
00272 
00273                 memset( m_count, 0, 8 );
00274 
00275                 memset( finalcount, 0, 8 );
00276 
00277                 Transform( m_state, m_buffer );
00278 }
00279 
00280 // Get the final hash as a pre-formatted string
00281 void CSHA1::ReportHash( char *szReport, unsigned char uReportType )
00282 {
00283         unsigned char i = 0;
00284         char szTemp[ 4 ];
00285 
00286         if ( uReportType == REPORT_HEX )
00287         {
00288                 sprintf( szTemp, "%02X", m_digest[ 0 ] );
00289                 strcat( szReport, szTemp );
00290 
00291                 for ( i = 1; i < 20; i++ )
00292                 {
00293                         sprintf( szTemp, " %02X", m_digest[ i ] );
00294                         strcat( szReport, szTemp );
00295                 }
00296         }
00297 
00298         else
00299                 if ( uReportType == REPORT_DIGIT )
00300                 {
00301                         sprintf( szTemp, "%u", m_digest[ 0 ] );
00302                         strcat( szReport, szTemp );
00303 
00304                         for ( i = 1; i < 20; i++ )
00305                         {
00306                                 sprintf( szTemp, " %u", m_digest[ i ] );
00307                                 strcat( szReport, szTemp );
00308                         }
00309                 }
00310 
00311                 else
00312                         strcpy( szReport, "Error: Unknown report type!" );
00313 }
00314 
00315 // Get the raw message digest
00316 void CSHA1::GetHash( unsigned char *uDest )
00317 {
00318         memcpy( uDest, m_digest, 20 );
00319 }
00320 
00321 // Get the raw message digest
00322 // Added by Kevin to be quicker
00323 unsigned char * CSHA1::GetHash( void ) const
00324 {
00325         return ( unsigned char * ) m_digest;
00326 }

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1