Code

Rearrange to enable code that does not directly rely on lcms.
[inkscape.git] / src / dom / util / digest.h
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         }
252         
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         }
261         
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         }
271         
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
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
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
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
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
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
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__ */