1 #ifndef __DIGEST_H__
2 #define __DIGEST_H__
3 /**
4 * Secure Hashing Tool
5 *
6 *
7 * Author:
8 * Bob Jamison
9 *
10 * Copyright (C) 2006-2008 Bob Jamison
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
27 /**
28 *
29 * This base class and its subclasses provide an easy API for providing
30 * several different types of secure hashing functions for whatever use
31 * a developer might need. This is not intended as a high-performance
32 * replacement for the fine implementations already available. Rather, it
33 * is a small and simple (and maybe a bit slow?) tool for moderate common
34 * hashing requirements, like for communications and authentication.
35 *
36 * These hashes are intended to be simple to use. For example:
37 * Sha256 digest;
38 * digest.append("The quick brown dog");
39 * std::string result = digest.finishHex();
40 *
41 * Or, use one of the static convenience methods:
42 *
43 * example: std::string digest =
44 * Digest::hashHex(Digest::HASH_XXX, str);
45 *
46 * ...where HASH_XXX represents one of the hash
47 * algorithms listed in HashType.
48 *
49 * There are several forms of append() for convenience.
50 * finish() and finishHex() call reset() for both security and
51 * to prepare for the next use.
52 *
53 *
54 * Much effort has been applied to make this code portable, and it
55 * has been tested on various 32- and 64-bit machines. If you
56 * add another algorithm, please test it likewise.
57 *
58 *
59 * The SHA algorithms are derived directly from FIPS-180-3. The
60 * SHA tests at the bottom of digest.cpp are also directly from
61 * that document.
62 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
63 *
64 * The MD5 algorithm is from RFC 1321
65 *
66 * To run the tests, compile standalone with -DDIGEST_TEST. Example:
67 *
68 * g++ -DDIGEST_TEST digest.cpp -o testdigest
69 * or
70 * g++ -DDIGEST_TEST -m64 digest.cpp -o testdigest
71 *
72 */
74 #include <vector>
75 #include <string>
77 #include <stdint.h>
81 /**
82 * Base class. Do not use instantiate class directly. Rather, use of of the
83 * subclasses below, or call one of this class's static convenience methods.
84 *
85 * For all subclasses, overload reset(), update(unsigned char),
86 * transform(), and finish()
87 */
88 class Digest
89 {
90 public:
92 /**
93 * Different types of hash algorithms.
94 */
95 typedef enum
96 {
97 HASH_NONE,
98 HASH_SHA1,
99 HASH_SHA224,
100 HASH_SHA256,
101 HASH_SHA384,
102 HASH_SHA512,
103 HASH_MD5
104 } HashType;
106 /**
107 * Constructor, with no type
108 */
109 Digest() : hashType(HASH_NONE)
110 { reset(); }
112 /**
113 * Destructor
114 */
115 virtual ~Digest()
116 { reset(); }
118 /**
119 * Return one of the enumerated hash types above
120 */
121 virtual int getType()
122 { return hashType; }
124 /**
125 * Append a single byte to the hash
126 */
127 void append(unsigned char ch)
128 { update(ch); }
130 /**
131 * Append a string to the hash
132 */
133 virtual void append(const std::string &str)
134 {
135 for (unsigned int i=0 ; i<str.size() ; i++)
136 update((unsigned char)str[i]);
137 }
139 /**
140 * Append a byte buffer to the hash
141 */
142 virtual void append(unsigned char *buf, int len)
143 {
144 for (int i=0 ; i<len ; i++)
145 update(buf[i]);
146 }
148 /**
149 * Append a byte vector to the hash
150 */
151 virtual void append(const std::vector<unsigned char> buf)
152 {
153 for (unsigned int i=0 ; i<buf.size() ; i++)
154 update(buf[i]);
155 }
157 /**
158 * Finish the hash and return a hexidecimal version of the computed
159 * value
160 */
161 virtual std::string finishHex();
163 /**
164 * Initialize the fields of this hash engine to its starting values.
165 * Overload this in every subclass
166 */
167 virtual void reset()
168 { clearByteCount(); }
170 /**
171 * Finish the hash and return its computed value
172 * Overload this in every subclass
173 */
174 virtual std::vector<unsigned char> finish()
175 {
176 std::vector<unsigned char> ret;
177 return ret;
178 }
181 //########################
182 //# Convenience methods
183 //########################
185 /**
186 * Convenience method. This is a simple way of getting a hash.
187 * Returns a byte buffer with the digest output.
188 * call with: std::vector<unsigned char> digest =
189 * Digest::hash(Digest::HASH_XXX, buf, len);
190 */
191 static std::vector<unsigned char> hash(HashType typ,
192 unsigned char *buf,
193 int len);
194 /**
195 * Convenience method. This is a simple way of getting a hash.
196 * Returns a byte buffer with the digest output.
197 * call with: std::vector<unsigned char> digest =
198 * Digest::hash(Digest::HASH_XXX, str);
199 */
200 static std::vector<unsigned char> hash(HashType typ,
201 const std::string &str);
203 /**
204 * Convenience method. This is a simple way of getting a hash.
205 * Returns a string with the hexidecimal form of the digest output.
206 * call with: std::string digest =
207 * Digest::hash(Digest::HASH_XXX, buf, len);
208 */
209 static std::string hashHex(HashType typ,
210 unsigned char *buf,
211 int len);
212 /**
213 * Convenience method. This is a simple way of getting a hash.
214 * Returns a string with the hexidecimal form of the digest output.
215 * call with: std::string digest =
216 * Digest::hash(Digest::HASH_XXX, str);
217 */
218 static std::string hashHex(HashType typ,
219 const std::string &str);
221 protected:
223 /**
224 * Update the hash with a given byte
225 * Overload this in every subclass
226 */
227 virtual void update(unsigned char /*ch*/)
228 {}
230 /**
231 * Perform the particular block hashing algorithm for a
232 * particular type of hash.
233 * Overload this in every subclass
234 */
235 virtual void transform()
236 {}
239 /**
240 * The enumerated type of the hash
241 */
242 int hashType;
244 /**
245 * Increment the count of bytes processed so far. Should be called
246 * in update()
247 */
248 void incByteCount()
249 {
250 nrBytes++;
251 }
253 /**
254 * Clear the byte / bit count information. Both for processing
255 * another message, also for security. Should be called in reset()
256 */
257 void clearByteCount()
258 {
259 nrBytes = nrBits = 0;
260 }
262 /**
263 * Calculates the bit count from the current byte count. Should be called
264 * in finish(), before any padding is added. This basically does a
265 * snapshot of the bitcount value before the padding.
266 */
267 void getBitCount()
268 {
269 nrBits = (nrBytes << 3) & 0xFFFFFFFFFFFFFFFFLL;
270 }
272 /**
273 * Common code for appending the 64-bit bitcount to the end of the
274 * message, after the padding. Should be called after padding, just
275 * before outputting the result.
276 */
277 void appendBitCount()
278 {
279 update((unsigned char)((nrBits>>56) & 0xff));
280 update((unsigned char)((nrBits>>48) & 0xff));
281 update((unsigned char)((nrBits>>40) & 0xff));
282 update((unsigned char)((nrBits>>32) & 0xff));
283 update((unsigned char)((nrBits>>24) & 0xff));
284 update((unsigned char)((nrBits>>16) & 0xff));
285 update((unsigned char)((nrBits>> 8) & 0xff));
286 update((unsigned char)((nrBits ) & 0xff));
287 }
289 /**
290 * Bit and byte counts
291 */
292 uint64_t nrBytes;
293 uint64_t nrBits;
294 };
300 /**
301 * SHA-1,
302 * Section 6.1, SECURE HASH STANDARD
303 * Federal Information Processing Standards Publication 180-2
304 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
305 */
306 class Sha1 : public Digest
307 {
308 public:
310 /**
311 * Constructor
312 */
313 Sha1()
314 { hashType = HASH_SHA1; reset(); }
316 /**
317 * Destructor
318 */
319 virtual ~Sha1()
320 { reset(); }
322 /**
323 * Overloaded from Digest
324 */
325 virtual void reset();
327 /**
328 * Overloaded from Digest
329 */
330 virtual std::vector<unsigned char> finish();
332 protected:
334 /**
335 * Overloaded from Digest
336 */
337 virtual void update(unsigned char val);
339 /**
340 * Overloaded from Digest
341 */
342 virtual void transform();
344 private:
346 uint32_t hashBuf[5];
347 uint32_t inBuf[80];
349 int longNr;
350 int byteNr;
351 uint32_t inb[4];
353 };
360 /**
361 * SHA-224,
362 * Section 6.1, SECURE HASH STANDARD
363 * Federal Information Processing Standards Publication 180-2
364 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
365 */
366 class Sha224 : public Digest
367 {
368 public:
370 /**
371 * Constructor
372 */
373 Sha224()
374 { hashType = HASH_SHA224; reset(); }
376 /**
377 * Destructor
378 */
379 virtual ~Sha224()
380 { reset(); }
382 /**
383 * Overloaded from Digest
384 */
385 virtual void reset();
387 /**
388 * Overloaded from Digest
389 */
390 virtual std::vector<unsigned char> finish();
392 protected:
394 /**
395 * Overloaded from Digest
396 */
397 virtual void update(unsigned char val);
399 /**
400 * Overloaded from Digest
401 */
402 virtual void transform();
404 private:
406 uint32_t hashBuf[8];
407 uint32_t inBuf[64];
408 int longNr;
409 int byteNr;
410 uint32_t inb[4];
412 };
416 /**
417 * SHA-256,
418 * Section 6.1, SECURE HASH STANDARD
419 * Federal Information Processing Standards Publication 180-2
420 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
421 */
422 class Sha256 : public Digest
423 {
424 public:
426 /**
427 * Constructor
428 */
429 Sha256()
430 { hashType = HASH_SHA256; reset(); }
432 /**
433 * Destructor
434 */
435 virtual ~Sha256()
436 { reset(); }
438 /**
439 * Overloaded from Digest
440 */
441 virtual void reset();
443 /**
444 * Overloaded from Digest
445 */
446 virtual std::vector<unsigned char> finish();
448 protected:
450 /**
451 * Overloaded from Digest
452 */
453 virtual void update(unsigned char val);
455 /**
456 * Overloaded from Digest
457 */
458 virtual void transform();
460 private:
462 uint32_t hashBuf[8];
463 uint32_t inBuf[64];
464 int longNr;
465 int byteNr;
466 uint32_t inb[4];
468 };
472 /**
473 * SHA-384,
474 * Section 6.1, SECURE HASH STANDARD
475 * Federal Information Processing Standards Publication 180-2
476 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
477 */
478 class Sha384 : public Digest
479 {
480 public:
482 /**
483 * Constructor
484 */
485 Sha384()
486 { hashType = HASH_SHA384; reset(); }
488 /**
489 * Destructor
490 */
491 virtual ~Sha384()
492 { reset(); }
494 /**
495 * Overloaded from Digest
496 */
497 virtual void reset();
499 /**
500 * Overloaded from Digest
501 */
502 virtual std::vector<unsigned char> finish();
504 protected:
506 /**
507 * Overloaded from Digest
508 */
509 virtual void update(unsigned char val);
511 /**
512 * Overloaded from Digest
513 */
514 virtual void transform();
518 private:
520 uint64_t hashBuf[8];
521 uint64_t inBuf[80];
522 int longNr;
523 int byteNr;
524 uint64_t inb[8];
526 };
531 /**
532 * SHA-512,
533 * Section 6.1, SECURE HASH STANDARD
534 * Federal Information Processing Standards Publication 180-2
535 * http://csrc.nist.gov/publications/drafts/fips_180-3/draft_fips-180-3_June-08-2007.pdf
536 */
537 class Sha512 : public Digest
538 {
539 public:
541 /**
542 * Constructor
543 */
544 Sha512()
545 { hashType = HASH_SHA512; reset(); }
547 /**
548 * Destructor
549 */
550 virtual ~Sha512()
551 { reset(); }
553 /**
554 * Overloaded from Digest
555 */
556 virtual void reset();
558 /**
559 * Overloaded from Digest
560 */
561 virtual std::vector<unsigned char> finish();
563 protected:
565 /**
566 * Overloaded from Digest
567 */
568 virtual void update(unsigned char val);
570 /**
571 * Overloaded from Digest
572 */
573 virtual void transform();
575 private:
577 uint64_t hashBuf[8];
578 uint64_t inBuf[80];
579 int longNr;
580 int byteNr;
581 uint64_t inb[8];
583 };
593 /**
594 * IETF RFC 1321, MD5 Specification
595 * http://www.ietf.org/rfc/rfc1321.txt
596 */
597 class Md5 : public Digest
598 {
599 public:
601 /**
602 * Constructor
603 */
604 Md5()
605 { hashType = HASH_MD5; reset(); }
607 /**
608 * Destructor
609 */
610 virtual ~Md5()
611 { reset(); }
613 /**
614 * Overloaded from Digest
615 */
616 virtual void reset();
618 /**
619 * Overloaded from Digest
620 */
621 virtual std::vector<unsigned char> finish();
623 protected:
625 /**
626 * Overloaded from Digest
627 */
628 virtual void update(unsigned char val);
630 /**
631 * Overloaded from Digest
632 */
633 virtual void transform();
635 private:
637 uint32_t hashBuf[4];
638 uint32_t inBuf[16];
640 uint32_t inb[4]; // Buffer for input bytes as longs
641 int byteNr; // which byte in long
642 int longNr; // which long in 16-long buffer
644 };
654 #endif /* __DIGEST_H__ */