1 #ifndef __DIGEST_H__
2 #define __DIGEST_H__
3 /**
4 * Secure Hashing Tool
5 * *
6 * Authors:
7 * Bob Jamison
8 *
9 * Copyright (C) 2006 Bob Jamison
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
26 /**
27 *
28 * This base class and its subclasses provide an easy API for providing
29 * several different types of secure hashing functions for whatever use
30 * a developer might need. This is not intended as a high-performance
31 * replacement for the fine implementations already available. Rather, it
32 * is a small and simple (and maybe a bit slow?) tool for moderate common
33 * hashing requirements, like for communications and authentication.
34 *
35 * These hashes are intended to be simple to use. For example:
36 * Sha256Digest digest;
37 * digest.append("The quick brown dog");
38 * std::string result = digest.finishHex();
39 *
40 * There are several forms of append() for convenience.
41 * finish() and finishHex() call reset() for both security and
42 * to prepare for the next use.
43 *
44 */
46 #include <vector>
47 #include <string>
50 /**
51 * Base class. Do not use this class directly. Rather, use of of the
52 * subclasses below.
53 * For all subclasses, overload reset(), update(unsigned char), and finish()
54 */
55 class Digest
56 {
57 public:
59 /**
60 * Different types of hash algorithms.
61 */
62 typedef enum
63 {
64 HASH_NONE,
65 HASH_SHA1,
66 HASH_SHA224,
67 HASH_SHA256,
68 HASH_SHA384,
69 HASH_SHA512,
70 HASH_MD5
71 } HashType;
73 /**
74 * Constructor, with no type
75 */
76 Digest() : hashType(HASH_NONE)
77 { reset(); }
79 /**
80 * Destructor
81 */
82 virtual ~Digest()
83 { reset(); }
85 /**
86 * Return one of the enumerated hash types above
87 */
88 virtual int getType()
89 { return hashType; }
91 /**
92 * Append a single byte to the hash
93 */
94 void append(unsigned char ch)
95 { update(ch); }
97 /**
98 * Append a string to the hash
99 */
100 virtual void append(const std::string &str)
101 {
102 for (unsigned int i=0 ; i<str.size() ; i++)
103 update((unsigned char)str[i]);
104 }
106 /**
107 * Append a byte buffer to the hash
108 */
109 virtual void append(unsigned char *buf, int len)
110 {
111 for (int i=0 ; i<len ; i++)
112 update(buf[i]);
113 }
115 /**
116 * Append a byte vector to the hash
117 */
118 virtual void append(const std::vector<unsigned char> buf)
119 {
120 for (unsigned int i=0 ; i<buf.size() ; i++)
121 update(buf[i]);
122 }
124 /**
125 * Finish the hash and return a hexidecimal version of the computed
126 * value
127 */
128 virtual std::string finishHex();
130 /**
131 * Initialize the fields of this hash engine to its starting values.
132 * Overload this in every subclass
133 */
134 virtual void reset()
135 {}
137 /**
138 * Finish the hash and return its computed value
139 * Overload this in every subclass
140 */
141 virtual std::vector<unsigned char> finish()
142 {
143 std::vector<unsigned char> ret;
144 return ret;
145 }
147 protected:
149 /**
150 * Update the hash with a given byte
151 * Overload this in every subclass
152 */
153 virtual void update(unsigned char ch)
154 {}
156 /**
157 * The enumerated type of the hash
158 */
159 int hashType;
160 };
166 /**
167 * SHA-1,
168 * Section 6.1, SECURE HASH STANDARD
169 * Federal Information Processing Standards Publication 180-2
170 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
171 */
172 class Sha1Digest : public Digest
173 {
174 public:
176 /**
177 * Constructor
178 */
179 Sha1Digest()
180 { hashType = HASH_SHA1; reset(); }
182 /**
183 * Destructor
184 */
185 virtual ~Sha1Digest()
186 { reset(); }
188 /**
189 * Overloaded from Digest
190 */
191 virtual void reset();
193 /**
194 * Overloaded from Digest
195 */
196 virtual std::vector<unsigned char> finish();
198 protected:
200 /**
201 * Overloaded from Digest
202 */
203 virtual void update(unsigned char val);
205 private:
207 void hashblock();
209 unsigned long H[5];
210 unsigned long W[80];
211 unsigned long long size;
212 int lenW;
214 };
221 /**
222 * SHA-224,
223 * Section 6.1, SECURE HASH STANDARD
224 * Federal Information Processing Standards Publication 180-2
225 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
226 */
227 class Sha224Digest : public Digest
228 {
229 public:
231 /**
232 * Constructor
233 */
234 Sha224Digest()
235 { hashType = HASH_SHA224; reset(); }
237 /**
238 * Destructor
239 */
240 virtual ~Sha224Digest()
241 { reset(); }
243 /**
244 * Overloaded from Digest
245 */
246 virtual void reset();
248 /**
249 * Overloaded from Digest
250 */
251 virtual std::vector<unsigned char> finish();
253 protected:
255 /**
256 * Overloaded from Digest
257 */
258 virtual void update(unsigned char val);
260 private:
262 void hashblock();
264 unsigned long H[8];
265 unsigned long W[64];
266 unsigned long long size;
267 int lenW;
269 };
273 /**
274 * SHA-256,
275 * Section 6.1, SECURE HASH STANDARD
276 * Federal Information Processing Standards Publication 180-2
277 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
278 */
279 class Sha256Digest : public Digest
280 {
281 public:
283 /**
284 * Constructor
285 */
286 Sha256Digest()
287 { hashType = HASH_SHA256; reset(); }
289 /**
290 * Destructor
291 */
292 virtual ~Sha256Digest()
293 { reset(); }
295 /**
296 * Overloaded from Digest
297 */
298 virtual void reset();
300 /**
301 * Overloaded from Digest
302 */
303 virtual std::vector<unsigned char> finish();
305 protected:
307 /**
308 * Overloaded from Digest
309 */
310 virtual void update(unsigned char val);
312 private:
314 void hashblock();
316 unsigned long H[8];
317 unsigned long W[64];
318 unsigned long long size;
319 int lenW;
321 };
324 /**
325 * SHA-384,
326 * Section 6.1, SECURE HASH STANDARD
327 * Federal Information Processing Standards Publication 180-2
328 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
329 */
330 class Sha384Digest : public Digest
331 {
332 public:
334 /**
335 * Constructor
336 */
337 Sha384Digest()
338 { hashType = HASH_SHA384; reset(); }
340 /**
341 * Destructor
342 */
343 virtual ~Sha384Digest()
344 { reset(); }
346 /**
347 * Overloaded from Digest
348 */
349 virtual void reset();
351 /**
352 * Overloaded from Digest
353 */
354 virtual std::vector<unsigned char> finish();
356 protected:
358 /**
359 * Overloaded from Digest
360 */
361 virtual void update(unsigned char val);
363 private:
365 void hashblock();
367 unsigned long long H[8];
368 unsigned long long W[80];
369 unsigned long long size;
370 int lenW;
372 };
377 /**
378 * SHA-512,
379 * Section 6.1, SECURE HASH STANDARD
380 * Federal Information Processing Standards Publication 180-2
381 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
382 */
383 class Sha512Digest : public Digest
384 {
385 public:
387 /**
388 * Constructor
389 */
390 Sha512Digest()
391 { hashType = HASH_SHA512; reset(); }
393 /**
394 * Destructor
395 */
396 virtual ~Sha512Digest()
397 { reset(); }
399 /**
400 * Overloaded from Digest
401 */
402 virtual void reset();
404 /**
405 * Overloaded from Digest
406 */
407 virtual std::vector<unsigned char> finish();
409 protected:
411 /**
412 * Overloaded from Digest
413 */
414 virtual void update(unsigned char val);
416 private:
418 void hashblock();
420 unsigned long long H[8];
421 unsigned long long W[80];
422 unsigned long long size;
423 int lenW;
425 };
435 /**
436 * IETF RFC 1321, MD5 Specification
437 * http://www.ietf.org/rfc/rfc1321.txt
438 */
439 class Md5Digest : public Digest
440 {
441 public:
443 /**
444 * Constructor
445 */
446 Md5Digest()
447 { hashType = HASH_MD5; reset(); }
449 /**
450 * Destructor
451 */
452 virtual ~Md5Digest()
453 { reset(); }
455 /**
456 * Overloaded from Digest
457 */
458 virtual void reset();
460 /**
461 * Overloaded from Digest
462 */
463 virtual std::vector<unsigned char> finish();
465 protected:
467 /**
468 * Overloaded from Digest
469 */
470 virtual void update(unsigned char val);
472 private:
474 void hashblock();
476 unsigned long hash[8];
477 unsigned long W[64];
478 unsigned long long size;
479 int lenW;
481 };
491 #endif /* __DIGEST_H__ */