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
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
00055 block = ( SHA1_WORKSPACE_BLOCK * ) workspace;
00056 memcpy( block, buffer, 64 );
00057
00058
00059 a = state[ 0 ];
00060 b = state[ 1 ];
00061 c = state[ 2 ];
00062 d = state[ 3 ];
00063 e = state[ 4 ];
00064
00065
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
00148 state[ 0 ] += a;
00149 state[ 1 ] += b;
00150 state[ 2 ] += c;
00151 state[ 3 ] += d;
00152 state[ 4 ] += e;
00153
00154
00155 a = 0;
00156 b = 0;
00157 c = 0;
00158 d = 0;
00159 e = 0;
00160 }
00161
00162
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
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
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
00220
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 );
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 );
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
00265 i = 0;
00266
00267
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
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
00316 void CSHA1::GetHash( unsigned char *uDest )
00317 {
00318 memcpy( uDest, m_digest, 20 );
00319 }
00320
00321
00322
00323 unsigned char * CSHA1::GetHash( void ) const
00324 {
00325 return ( unsigned char * ) m_digest;
00326 }