1 //  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
2 //  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
3 //
4 //  Copyright (c) 2003 Peter Brian Clements
5 //  Copyright (c) 2019 Michael D. Nahas
6 //
7 //  par2cmdline is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2 of the License, or
10 //  (at your option) any later version.
11 //
12 //  par2cmdline is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 
21 #ifndef __MD5_H__
22 #define __MD5_H__
23 
24 #ifdef _WIN32
25 #pragma pack(push, 1)
26 #define PACKED
27 #else
28 #define PACKED __attribute__ ((packed))
29 #endif
30 
31 // This file defines the MD5Hash and MD5Context objects which are used
32 // to compute and manipulate the MD5 Hash values for a block of data.
33 
34 //  Usage:
35 //
36 //  MD5Context context;
37 //  context.Update(buffer, length);
38 //
39 //  MD5Hash hash;
40 //  context.Final(hash);
41 
42 
43 
44 // MD5 Hash value
45 
46 struct MD5Hash;
47 ostream& operator<<(ostream &s, const MD5Hash &hash);
48 
49 struct MD5Hash
50 {
51   // Comparison operators
52   bool operator==(const MD5Hash &other) const;
53   bool operator!=(const MD5Hash &other) const;
54 
55   bool operator<(const MD5Hash &other) const;
56   bool operator>=(const MD5Hash &other) const;
57   bool operator>(const MD5Hash &other) const;
58   bool operator<=(const MD5Hash &other) const;
59 
60   // Convert value to hex
61   friend ostream& operator<<(ostream &s, const MD5Hash &hash);
62   string print(void) const;
63 
64   u8 hash[16]; // 16 byte MD5 Hash value
65 } PACKED;
66 
67 // Intermediate computation state
68 
69 class MD5State
70 {
71 public:
72   MD5State(void);
73   void Reset(void);
74 
75 public:
76   void UpdateState(const u32 (&block)[16]);
77 
78 protected:
79   u32 state[4]; // 16 byte MD5 computation state
80 };
81 
82 // MD5 computation context with 64 byte buffer
83 
84 class MD5Context : public MD5State
85 {
86 public:
87   MD5Context(void);
~MD5Context(void)88   ~MD5Context(void) {};
89   void Reset(void);
90 
91   // Process data from a buffer
92   void Update(const void *buffer, size_t length);
93 
94   // Process 0 bytes
95   void Update(size_t length);
96 
97   // Compute the final hash value
98   void Final(MD5Hash &output);
99 
100   // Get the Hash value and the total number of bytes processed.
101   MD5Hash Hash(void) const;
Bytes(void)102   u64 Bytes(void) const {return bytes;}
103 
104   friend ostream& operator<<(ostream &s, const MD5Context &context);
105   string print(void) const;
106 
107 protected:
108   enum {buffersize = 64};
109   unsigned char block[buffersize];
110   size_t used;
111 
112   u64 bytes;
113 };
114 
115 // Compare hash values
116 
117 inline bool MD5Hash::operator==(const MD5Hash &other) const
118 {
119   return (0==memcmp(&hash, &other.hash, sizeof(hash)));
120 }
121 inline bool MD5Hash::operator!=(const MD5Hash &other) const
122 {
123   return !operator==(other);
124 }
125 
126 inline bool MD5Hash::operator<(const MD5Hash &other) const
127 {
128   size_t index = 15;
129   while (index > 0 && hash[index] == other.hash[index])
130   {
131     index--;
132   }
133 
134   return hash[index] < other.hash[index];
135 }
136 inline bool MD5Hash::operator>=(const MD5Hash &other) const
137 {
138   return !operator<(other);
139 }
140 inline bool MD5Hash::operator>(const MD5Hash &other) const
141 {
142   return other.operator<(*this);
143 }
144 inline bool MD5Hash::operator<=(const MD5Hash &other) const
145 {
146   return !other.operator<(*this);
147 }
148 
149 #ifdef _WIN32
150 #pragma pack(pop)
151 #endif
152 #undef PACKED
153 
154 #endif // __MD5_H__
155