| LEFT | RIGHT |
| (no file at all) | |
| 1 /* | |
| 2 100% free public domain implementation of the SHA-1 algorithm | |
| 3 by Dominik Reichl <dominik.reichl@t-online.de> | |
| 4 Web: http://www.dominik-reichl.de/ | |
| 5 | |
| 6 See header file for version history. | |
| 7 */ | |
| 8 | |
| 9 // If compiling with MFC, you might want to add #include "StdAfx.h" | |
| 10 | |
| 11 #include "PluginStdAfx.h" | |
| 12 | |
| 13 #define _CRT_SECURE_NO_WARNINGS | |
| 14 #include "PluginSha1.h" | |
| 15 | |
| 16 #ifdef SHA1_UTILITY_FUNCTIONS | |
| 17 #define SHA1_MAX_FILE_BUFFER 8000 | |
| 18 #endif | |
| 19 | |
| 20 // Rotate x bits to the left | |
| 21 #ifndef ROL32 | |
| 22 #ifdef _MSC_VER | |
| 23 #define ROL32(_val32,_nBits) _rotl(_val32,_nBits) | |
| 24 #else | |
| 25 #define ROL32(_val32,_nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) | |
| 26 #endif | |
| 27 #endif | |
| 28 | |
| 29 #ifdef SHA1_LITTLE_ENDIAN | |
| 30 #define SHABLK0(i) (m_block->l[i] = \ | |
| 31 (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)
) | |
| 32 #else | |
| 33 #define SHABLK0(i) (m_block->l[i]) | |
| 34 #endif | |
| 35 | |
| 36 #define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(
i+8)&15] \ | |
| 37 ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) | |
| 38 | |
| 39 // SHA-1 rounds | |
| 40 #define _R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=RO
L32(w,30);} | |
| 41 #define _R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL
32(w,30);} | |
| 42 #define _R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,3
0);} | |
| 43 #define _R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w
=ROL32(w,30);} | |
| 44 #define _R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,3
0);} | |
| 45 | |
| 46 CSHA1::CSHA1() | |
| 47 { | |
| 48 m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace; | |
| 49 | |
| 50 Reset(); | |
| 51 } | |
| 52 | |
| 53 CSHA1::~CSHA1() | |
| 54 { | |
| 55 Reset(); | |
| 56 } | |
| 57 | |
| 58 void CSHA1::Reset() | |
| 59 { | |
| 60 // SHA1 initialization constants | |
| 61 m_state[0] = 0x67452301; | |
| 62 m_state[1] = 0xEFCDAB89; | |
| 63 m_state[2] = 0x98BADCFE; | |
| 64 m_state[3] = 0x10325476; | |
| 65 m_state[4] = 0xC3D2E1F0; | |
| 66 | |
| 67 m_count[0] = 0; | |
| 68 m_count[1] = 0; | |
| 69 } | |
| 70 | |
| 71 void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer) | |
| 72 { | |
| 73 UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState
[4]; | |
| 74 | |
| 75 memcpy(m_block, pBuffer, 64); | |
| 76 | |
| 77 // 4 rounds of 20 operations each. Loop unrolled. | |
| 78 _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); | |
| 79 _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); | |
| 80 _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); | |
| 81 _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); | |
| 82 _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); | |
| 83 _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); | |
| 84 _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); | |
| 85 _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); | |
| 86 _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); | |
| 87 _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); | |
| 88 _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); | |
| 89 _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); | |
| 90 _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); | |
| 91 _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); | |
| 92 _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); | |
| 93 _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); | |
| 94 _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); | |
| 95 _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); | |
| 96 _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); | |
| 97 _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); | |
| 98 | |
| 99 // Add the working vars back into state | |
| 100 pState[0] += a; | |
| 101 pState[1] += b; | |
| 102 pState[2] += c; | |
| 103 pState[3] += d; | |
| 104 pState[4] += e; | |
| 105 | |
| 106 // Wipe variables | |
| 107 #ifdef SHA1_WIPE_VARIABLES | |
| 108 a = b = c = d = e = 0; | |
| 109 #endif | |
| 110 } | |
| 111 | |
| 112 // Use this function to hash in binary data and strings | |
| 113 void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen) | |
| 114 { | |
| 115 UINT_32 j = ((m_count[0] >> 3) & 0x3F); | |
| 116 | |
| 117 if((m_count[0] += (uLen << 3)) < (uLen << 3)) | |
| 118 ++m_count[1]; // Overflow | |
| 119 | |
| 120 m_count[1] += (uLen >> 29); | |
| 121 | |
| 122 UINT_32 i; | |
| 123 if((j + uLen) > 63) | |
| 124 { | |
| 125 i = 64 - j; | |
| 126 memcpy(&m_buffer[j], pbData, i); | |
| 127 Transform(m_state, m_buffer); | |
| 128 | |
| 129 for( ; (i + 63) < uLen; i += 64) | |
| 130 Transform(m_state, &pbData[i]); | |
| 131 | |
| 132 j = 0; | |
| 133 } | |
| 134 else i = 0; | |
| 135 | |
| 136 if((uLen - i) != 0) | |
| 137 memcpy(&m_buffer[j], &pbData[i], uLen - i); | |
| 138 } | |
| 139 | |
| 140 #ifdef SHA1_UTILITY_FUNCTIONS | |
| 141 // Hash in file contents | |
| 142 bool CSHA1::HashFile(const TCHAR* tszFileName) | |
| 143 { | |
| 144 if(tszFileName == NULL) return false; | |
| 145 | |
| 146 FILE* fpIn = _tfopen(tszFileName, _T("rb")); | |
| 147 if(fpIn == NULL) return false; | |
| 148 | |
| 149 _fseeki64(fpIn, 0, SEEK_END); | |
| 150 const INT_64 lFileSize = _ftelli64(fpIn); | |
| 151 _fseeki64(fpIn, 0, SEEK_SET); | |
| 152 | |
| 153 const INT_64 lMaxBuf = SHA1_MAX_FILE_BUFFER; | |
| 154 UINT_8 vData[SHA1_MAX_FILE_BUFFER]; | |
| 155 INT_64 lRemaining = lFileSize; | |
| 156 | |
| 157 while(lRemaining > 0) | |
| 158 { | |
| 159 const size_t uMaxRead = static_cast<size_t>((lRemaining > lMaxBuf) ? | |
| 160 lMaxBuf : lRemaining); | |
| 161 | |
| 162 const size_t uRead = fread(vData, 1, uMaxRead, fpIn); | |
| 163 if(uRead == 0) | |
| 164 { | |
| 165 fclose(fpIn); | |
| 166 return false; | |
| 167 } | |
| 168 | |
| 169 Update(vData, static_cast<UINT_32>(uRead)); | |
| 170 | |
| 171 lRemaining -= static_cast<INT_64>(uRead); | |
| 172 } | |
| 173 | |
| 174 fclose(fpIn); | |
| 175 return (lRemaining == 0); | |
| 176 } | |
| 177 #endif | |
| 178 | |
| 179 void CSHA1::Final() | |
| 180 { | |
| 181 UINT_32 i; | |
| 182 | |
| 183 UINT_8 finalcount[8]; | |
| 184 for(i = 0; i < 8; ++i) | |
| 185 finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)] | |
| 186 >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent | |
| 187 | |
| 188 Update((UINT_8*)"\200", 1); | |
| 189 | |
| 190 while ((m_count[0] & 504) != 448) | |
| 191 Update((UINT_8*)"\0", 1); | |
| 192 | |
| 193 Update(finalcount, 8); // Cause a SHA1Transform() | |
| 194 | |
| 195 for(i = 0; i < 20; ++i) | |
| 196 m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); | |
| 197 | |
| 198 // Wipe variables for security reasons | |
| 199 #ifdef SHA1_WIPE_VARIABLES | |
| 200 memset(m_buffer, 0, 64); | |
| 201 memset(m_state, 0, 20); | |
| 202 memset(m_count, 0, 8); | |
| 203 memset(finalcount, 0, 8); | |
| 204 Transform(m_state, m_buffer); | |
| 205 #endif | |
| 206 } | |
| 207 | |
| 208 #ifdef SHA1_UTILITY_FUNCTIONS | |
| 209 // Get the final hash as a pre-formatted string | |
| 210 bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const | |
| 211 { | |
| 212 if(tszReport == NULL) return false; | |
| 213 | |
| 214 TCHAR tszTemp[16]; | |
| 215 | |
| 216 if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT)) | |
| 217 { | |
| 218 _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]); | |
| 219 _tcscpy(tszReport, tszTemp); | |
| 220 | |
| 221 const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X"
)); | |
| 222 for(size_t i = 1; i < 20; ++i) | |
| 223 { | |
| 224 _sntprintf(tszTemp, 15, lpFmt, m_digest[i]); | |
| 225 _tcscat(tszReport, tszTemp); | |
| 226 } | |
| 227 } | |
| 228 else if(rtReportType == REPORT_DIGIT) | |
| 229 { | |
| 230 _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]); | |
| 231 _tcscpy(tszReport, tszTemp); | |
| 232 | |
| 233 for(size_t i = 1; i < 20; ++i) | |
| 234 { | |
| 235 _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]); | |
| 236 _tcscat(tszReport, tszTemp); | |
| 237 } | |
| 238 } | |
| 239 else return false; | |
| 240 | |
| 241 return true; | |
| 242 } | |
| 243 #endif | |
| 244 | |
| 245 #ifdef SHA1_STL_FUNCTIONS | |
| 246 bool CSHA1::ReportHashStl(std::basic_string<TCHAR>& strOut, REPORT_TYPE rtReport
Type) const | |
| 247 { | |
| 248 TCHAR tszOut[84]; | |
| 249 const bool bResult = ReportHash(tszOut, rtReportType); | |
| 250 if(bResult) strOut = tszOut; | |
| 251 return bResult; | |
| 252 } | |
| 253 #endif | |
| 254 | |
| 255 // Get the raw message digest | |
| 256 bool CSHA1::GetHash(UINT_8* pbDest) const | |
| 257 { | |
| 258 if(pbDest == NULL) return false; | |
| 259 memcpy(pbDest, m_digest, 20); | |
| 260 return true; | |
| 261 } | |
| LEFT | RIGHT |