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 |