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   Version 1.9 - 2011-11-10
7   - Added Unicode test vectors.
8   - Improved support for hashing files using the HashFile method that
9     are larger than 4 GB.
10   - Improved file hashing performance (by using a larger buffer).
11   - Disabled unnecessary compiler warnings.
12   - Internal variables are now private.
13 
14   Version 1.8 - 2009-03-16
15   - Converted project files to Visual Studio 2008 format.
16   - Added Unicode support for HashFile utility method.
17   - Added support for hashing files using the HashFile method that are
18     larger than 2 GB.
19   - HashFile now returns an error code instead of copying an error
20     message into the output buffer.
21   - GetHash now returns an error code and validates the input parameter.
22   - Added ReportHashStl STL utility method.
23   - Added REPORT_HEX_SHORT reporting mode.
24   - Improved Linux compatibility of test program.
25 
26   Version 1.7 - 2006-12-21
27   - Fixed buffer underrun warning that appeared when compiling with
28     Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the
29     patch).
30   - Breaking change: ReportHash writes the final hash to the start
31     of the buffer, i.e. it's not appending it to the string anymore.
32   - Made some function parameters const.
33   - Added Visual Studio 2005 project files to demo project.
34 
35   Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
36   - You can set the endianness in your files, no need to modify the
37     header file of the CSHA1 class anymore.
38   - Aligned data support.
39   - Made support/compilation of the utility functions (ReportHash and
40     HashFile) optional (useful when bytes count, for example in embedded
41     environments).
42 
43   Version 1.5 - 2005-01-01
44   - 64-bit compiler compatibility added.
45   - Made variable wiping optional (define SHA1_WIPE_VARIABLES).
46   - Removed unnecessary variable initializations.
47   - ROL32 improvement for the Microsoft compiler (using _rotl).
48 
CSHA1()49   Version 1.4 - 2004-07-22
50   - CSHA1 now compiles fine with GCC 3.3 under MacOS X  (thanks to Larry
51     Hastings).
52 
53   Version 1.3 - 2003-08-17
54   - Fixed a small memory bug and made a buffer array a class member to
55     ensure correct working when using multiple CSHA1 class instances at
56     one time.
57 
58   Version 1.2 - 2002-11-16
59   - Borlands C++ compiler seems to have problems with string addition
60     using sprintf. Fixed the bug which caused the digest report function
61     not to work properly. CSHA1 is now Borland compatible.
62 
63   Version 1.1 - 2002-10-11
64   - Removed two unnecessary header file includes and changed BOOL to
65     bool. Fixed some minor bugs in the web page contents.
66 
67   Version 1.0 - 2002-06-20
68   - First official release.
69 
70   ================ Test Vectors ================
71 
72   SHA1("abc" in ANSI) =
73     A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
74   SHA1("abc" in Unicode LE) =
75     9F04F41A 84851416 2050E3D6 8C1A7ABB 441DC2B5
76 
77   SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
78     in ANSI) =
79     84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
80   SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
81     in Unicode LE) =
82     51D7D876 9AC72C40 9C5B0E3F 69C60ADC 9A039014
83 
84   SHA1(A million repetitions of "a" in ANSI) =
85     34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
86   SHA1(A million repetitions of "a" in Unicode LE) =
87     C4609560 A108A0C6 26AA7F2B 38A65566 739353C5
88 */
89 
90 #ifndef ___SHA1_HDR___
91 #define ___SHA1_HDR___
92 
93 #if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
94 #define SHA1_UTILITY_FUNCTIONS
95 #endif
96 
97 #if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS)
98 #define SHA1_STL_FUNCTIONS
99 #if !defined(SHA1_UTILITY_FUNCTIONS)
100 #error STL functions require SHA1_UTILITY_FUNCTIONS.
101 #endif
102 #endif
103 
104 #include <memory.h>
105 
106 #ifdef SHA1_UTILITY_FUNCTIONS
107 #include <stdio.h>
108 #include <string.h>
109 #endif
110 
111 #ifdef SHA1_STL_FUNCTIONS
112 #include <string>
113 #endif
114 
115 #ifdef _MSC_VER
116 #include <stdlib.h>
117 #endif
118 
119 // You can define the endian mode in your files without modifying the SHA-1
120 // source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
121 // in your files, before including the SHA1.h header file. If you don't
122 // define anything, the class defaults to little endian.
123 #if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
124 #define SHA1_LITTLE_ENDIAN
125 #endif
126 
127 // If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not,
128 // #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
129 // defaults to wiping.
130 #if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
131 #define SHA1_WIPE_VARIABLES
132 #endif
133 
134 #if defined(SHA1_HAS_TCHAR)
135 #include <tchar.h>
136 #else
137 #ifdef _MSC_VER
138 #include <tchar.h>
139 #else
140 #ifndef TCHAR
141 #define TCHAR char
142 #endif
143 #ifndef _T
144 #define _T(__x) (__x)
145 #define _tmain main
146 #define _tprintf printf
147 #define _getts gets
148 #define _tcslen strlen
149 #define _tfopen fopen
150 #define _tcscpy strcpy
151 #define _tcscat strcat
152 #define _sntprintf snprintf
153 #endif
154 #endif
155 #endif
156 
157 ///////////////////////////////////////////////////////////////////////////
158 // Define variable types
159 
160 #ifndef UINT_8
161 #ifdef _MSC_VER // Compiling with Microsoft compiler
162 #define UINT_8  unsigned __int8
163 #else // !_MSC_VER
164 #define UINT_8 unsigned char
165 #endif // _MSC_VER
166 #endif
167 
168 #ifndef UINT_32
169 #ifdef _MSC_VER // Compiling with Microsoft compiler
170 #define UINT_32 unsigned __int32
171 #else // !_MSC_VER
172 #if (ULONG_MAX == 0xFFFFFFFF)
173 #define UINT_32 unsigned long
174 #else
175 #define UINT_32 unsigned int
176 #endif
177 #endif // _MSC_VER
178 #endif // UINT_32
179 
180 #ifndef INT_64
181 #ifdef _MSC_VER // Compiling with Microsoft compiler
182 #define INT_64 __int64
183 #else // !_MSC_VER
184 #define INT_64 long long
185 #endif // _MSC_VER
186 #endif // INT_64
187 
188 #ifndef UINT_64
189 #ifdef _MSC_VER // Compiling with Microsoft compiler
190 #define UINT_64 unsigned __int64
191 #else // !_MSC_VER
192 #define UINT_64 unsigned long long
193 #endif // _MSC_VER
194 #endif // UINT_64
195 
196 ///////////////////////////////////////////////////////////////////////////
197 // Declare SHA-1 workspace
198 
199 typedef union
200 {
201 	UINT_8 c[64];
202 	UINT_32 l[16];
203 } SHA1_WORKSPACE_BLOCK;
ReportHash(TCHAR * tszReport,REPORT_TYPE rtReportType) const204 
205 class CSHA1
206 {
207 public:
208 #ifdef SHA1_UTILITY_FUNCTIONS
209 	// Different formats for ReportHash
210 	enum REPORT_TYPE
211 	{
212 		REPORT_HEX = 0,
213 		REPORT_DIGIT = 1,
214 		REPORT_HEX_SHORT = 2
215 	};
216 #endif
217 
218 	// Constructor and destructor
219 	CSHA1();
220 	~CSHA1();
221 
222 	void Reset();
223 
224 	// Hash in binary data and strings
225 	void Update(const UINT_8* pbData, UINT_32 uLen);
226 
227 #ifdef SHA1_UTILITY_FUNCTIONS
228 	// Hash in file contents
229 	bool HashFile(const TCHAR* tszFileName);
230 #endif
231 
232 	// Finalize hash, call before using ReportHash(Stl)
233 	void Final();
234 
235 #ifdef SHA1_UTILITY_FUNCTIONS
236 	bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const;
237 #endif
238 
239 #ifdef SHA1_STL_FUNCTIONS
240 	bool ReportHashStl(std::basic_string<TCHAR>& strOut, REPORT_TYPE rtReportType =
241 		REPORT_HEX) const;
242 #endif
243 
244 	// Get the raw message digest (20 bytes)
245 	bool GetHash(UINT_8* pbDest20) const;
246 
247 private:
248 	// Private SHA-1 transformation
249 	void Transform(UINT_32* pState, const UINT_8* pBuffer);
250 
251 	// Member variables
252 	UINT_32 m_state[5];
253 	UINT_32 m_count[2];
254 	UINT_32 m_reserved0[1]; // Memory alignment padding
255 	UINT_8 m_buffer[64];
256 	UINT_8 m_digest[20];
257 	UINT_32 m_reserved1[3]; // Memory alignment padding
258 
259 	UINT_8 m_workspace[64];
260 	SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above
261 };
262 
263 #endif // ___SHA1_HDR___
264