Avionics
Dropship Simulator
MD5.h
Go to the documentation of this file.
1 /* MD5
2 converted to C++ class by Frank Thilo (thilo@unix-ag.org)
3 for bzflag (http://www.bzflag.org)
4 
5 based on:
6 
7 md5.h and md5.c
8 reference implementation of RFC 1321
9 
10 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
11 rights reserved.
12 
13 License to copy and use this software is granted provided that it
14 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15 Algorithm" in all material mentioning or referencing this software
16 or this function.
17 
18 License is also granted to make and use derivative works provided
19 that such works are identified as "derived from the RSA Data
20 Security, Inc. MD5 Message-Digest Algorithm" in all material
21 mentioning or referencing the derived work.
22 
23 RSA Data Security, Inc. makes no representations concerning either
24 the merchantability of this software or the suitability of this
25 software for any particular purpose. It is provided "as is"
26 without express or implied warranty of any kind.
27 
28 These notices must be retained in any copies of any part of this
29 documentation and/or software.
30 
31 */
32 
33 #ifndef BZF_MD5_H
34 #define BZF_MD5_H
35 
36 //#include <cstring>
37 //#include <iostream>
38 
39 
40 // a small class for calculating MD5 hashes of strings or byte arrays
41 // it is not meant to be fast or secure
42 //
43 // usage: 1) feed it blocks of uchars with update()
44 // 2) finalize()
45 // 3) get hexdigest() string
46 // or
47 // MD5(std::string).hexdigest()
48 //
49 // assumes that char is 8 bit and int is 32 bit
50 class MD5
51 {
52 public:
53  typedef unsigned int size_type; // must be 32bit
54 
55  MD5();
56  MD5(const std::string& text);
57  void update(const unsigned char* buf, size_type length);
58  void update(const char* buf, size_type length);
59  MD5& finalize();
60  std::string hexdigest() const;
61  friend std::ostream& operator<<(std::ostream&, MD5 md5);
62 
63 private:
64  void init();
65  typedef unsigned char uint1; // 8bit
66  typedef unsigned int uint4; // 32bit
67  enum
68  {
69  blocksize = 64
70  }; // VC6 won't eat a const static int here
71 
72  void transform(const uint1 block[blocksize]);
73  static void decode(uint4 output[], const uint1 input[], size_type len);
74  static void encode(uint1 output[], const uint4 input[], size_type len);
75 
76  bool finalized;
77  uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
78  uint4 count[2]; // 64bit counter for number of bits (lo, hi)
79  uint4 state[4]; // digest so far
80  uint1 digest[16]; // the result
81 
82  // low level logic operations
83  static inline uint4 F(uint4 x, uint4 y, uint4 z);
84  static inline uint4 G(uint4 x, uint4 y, uint4 z);
85  static inline uint4 H(uint4 x, uint4 y, uint4 z);
86  static inline uint4 I(uint4 x, uint4 y, uint4 z);
87  static inline uint4 rotate_left(uint4 x, int n);
88  static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
89  static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
90  static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
91  static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
92 };
93 
94 std::string md5(const std::string str);
95 
96 #endif
97 
98 
99 /* system implementation headers */
100 #include <cstdio>
101 
102 
103 // Constants for MD5Transform routine.
104 #define S11 7
105 #define S12 12
106 #define S13 17
107 #define S14 22
108 #define S21 5
109 #define S22 9
110 #define S23 14
111 #define S24 20
112 #define S31 4
113 #define S32 11
114 #define S33 16
115 #define S34 23
116 #define S41 6
117 #define S42 10
118 #define S43 15
119 #define S44 21
120 
122 
123 // F, G, H and I are basic MD5 functions.
125 {
126  return x & y | ~x & z;
127 }
128 
130 {
131  return x & z | y & ~z;
132 }
133 
135 {
136  return x ^ y ^ z;
137 }
138 
140 {
141  return y ^ (x | ~z);
142 }
143 
144 // rotate_left rotates x left n bits.
146 {
147  return (x << n) | (x >> (32 - n));
148 }
149 
150 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
151 // Rotation is separate from addition to prevent recomputation.
152 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
153 {
154  a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
155 }
156 
157 inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
158 {
159  a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
160 }
161 
162 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
163 {
164  a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
165 }
166 
167 inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
168 {
169  a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
170 }
171 
173 
174 // default ctor, just initailize
175 inline MD5::MD5()
176 {
177  init();
178 }
179 
181 
182 // nifty shortcut ctor, compute MD5 for string and finalize it right away
183 inline MD5::MD5(const std::string& text)
184 {
185  init();
186  update(text.c_str(), text.length());
187  finalize();
188 }
189 
191 
192 inline void MD5::init()
193 {
194  finalized = false;
195 
196  count[0] = 0;
197  count[1] = 0;
198 
199  // load magic initialization constants.
200  state[0] = 0x67452301;
201  state[1] = 0xefcdab89;
202  state[2] = 0x98badcfe;
203  state[3] = 0x10325476;
204 }
205 
207 
208 // decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
209 inline void MD5::decode(uint4 output[], const uint1 input[], size_type len)
210 {
211  for (unsigned int i = 0, j = 0; j < len; i++ , j += 4)
212  output[i] = static_cast<uint4>(input[j]) | (static_cast<uint4>(input[j + 1]) << 8) |
213  (static_cast<uint4>(input[j + 2]) << 16) | (static_cast<uint4>(input[j + 3]) << 24);
214 }
215 
217 
218 // encodes input (uint4) into output (unsigned char). Assumes len is
219 // a multiple of 4.
220 inline void MD5::encode(uint1 output[], const uint4 input[], size_type len)
221 {
222  for (size_type i = 0, j = 0; j < len; i++ , j += 4)
223  {
224  output[j] = input[i] & 0xff;
225  output[j + 1] = (input[i] >> 8) & 0xff;
226  output[j + 2] = (input[i] >> 16) & 0xff;
227  output[j + 3] = (input[i] >> 24) & 0xff;
228  }
229 }
230 
232 
233 // apply MD5 algo on a block
234 inline void MD5::transform(const uint1 block[blocksize])
235 {
236  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
237  decode(x, block, blocksize);
238 
239  /* Round 1 */
240  FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
241  FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
242  FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
243  FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
244  FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
245  FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
246  FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
247  FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
248  FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
249  FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
250  FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
251  FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
252  FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
253  FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
254  FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
255  FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
256 
257  /* Round 2 */
258  GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
259  GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
260  GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
261  GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
262  GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
263  GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
264  GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
265  GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
266  GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
267  GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
268  GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
269  GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
270  GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
271  GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
272  GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
273  GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
274 
275  /* Round 3 */
276  HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
277  HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
278  HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
279  HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
280  HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
281  HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
282  HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
283  HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
284  HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
285  HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
286  HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
287  HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
288  HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
289  HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
290  HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
291  HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
292 
293  /* Round 4 */
294  II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
295  II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
296  II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
297  II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
298  II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
299  II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
300  II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
301  II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
302  II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
303  II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
304  II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
305  II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
306  II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
307  II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
308  II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
309  II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
310 
311  state[0] += a;
312  state[1] += b;
313  state[2] += c;
314  state[3] += d;
315 
316  // Zeroize sensitive information.
317  memset(x, 0, sizeof x);
318 }
319 
321 
322 // MD5 block update operation. Continues an MD5 message-digest
323 // operation, processing another message block
324 inline void MD5::update(const unsigned char input[], size_type length)
325 {
326  // compute number of bytes mod 64
327  size_type index = count[0] / 8 % blocksize;
328 
329  // Update number of bits
330  if ((count[0] += (length << 3)) < (length << 3))
331  count[1]++;
332  count[1] += (length >> 29);
333 
334  // number of bytes we need to fill in buffer
335  size_type firstpart = 64 - index;
336 
337  size_type i;
338 
339  // transform as many times as possible.
340  if (length >= firstpart)
341  {
342  // fill buffer first, transform
343  memcpy(&buffer[index], input, firstpart);
344  transform(buffer);
345 
346  // transform chunks of blocksize (64 bytes)
347  for (i = firstpart; i + blocksize <= length; i += blocksize)
348  transform(&input[i]);
349 
350  index = 0;
351  }
352  else
353  i = 0;
354 
355  // buffer remaining input
356  memcpy(&buffer[index], &input[i], length - i);
357 }
358 
360 
361 // for convenience provide a verson with signed char
362 inline void MD5::update(const char input[], size_type length)
363 {
364  update(reinterpret_cast<const unsigned char*>(input), length);
365 }
366 
368 
369 // MD5 finalization. Ends an MD5 message-digest operation, writing the
370 // the message digest and zeroizing the context.
372 {
373  static unsigned char padding[64] = {
374  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
375  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
376  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
377  };
378 
379  if (!finalized)
380  {
381  // Save number of bits
382  unsigned char bits[8];
383  encode(bits, count, 8);
384 
385  // pad out to 56 mod 64.
386  size_type index = count[0] / 8 % 64;
387  size_type padLen = (index < 56) ? (56 - index) : (120 - index);
388  update(padding, padLen);
389 
390  // Append length (before padding)
391  update(bits, 8);
392 
393  // Store state in digest
394  encode(digest, state, 16);
395 
396  // Zeroize sensitive information.
397  memset(buffer, 0, sizeof buffer);
398  memset(count, 0, sizeof count);
399 
400  finalized = true;
401  }
402 
403  return *this;
404 }
405 
407 
408 // return hex representation of digest as string
409 inline std::string MD5::hexdigest() const
410 {
411  if (!finalized)
412  return "";
413 
414  char buf[33];
415  for (int i = 0; i < 16; i++)
416  sprintf_s(buf + i * 2, 33 - i * 2, "%02x", digest[i]);
417  buf[32] = 0;
418 
419  return std::string(buf);
420 }
421 
423 
424 inline std::ostream& operator<<(std::ostream& out, MD5 md5)
425 {
426  return out << md5.hexdigest();
427 }
428 
430 
431 inline std::string md5(const std::string str)
432 {
433  MD5 md5 = MD5(str);
434 
435  return md5.hexdigest();
436 }
std::ostream & operator<<(std::ostream &out, MD5 md5)
Definition: MD5.h:424
#define S24
Definition: MD5.h:111
#define S33
Definition: MD5.h:114
#define S31
Definition: MD5.h:112
#define S41
Definition: MD5.h:116
void update(const unsigned char *buf, size_type length)
Definition: MD5.h:50
uint1 buffer[blocksize]
Definition: MD5.h:77
static void encode(uint1 output[], const uint4 input[], size_type len)
Definition: MD5.h:220
#define S43
Definition: MD5.h:118
#define S34
Definition: MD5.h:115
void transform(const uint1 block[blocksize])
Definition: MD5.h:234
uint1 digest[16]
Definition: MD5.h:80
void init()
Definition: MD5.h:192
#define S21
Definition: MD5.h:108
unsigned int uint4
Definition: MD5.h:66
static uint4 G(uint4 x, uint4 y, uint4 z)
Definition: MD5.h:129
#define S22
Definition: MD5.h:109
static void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.h:152
friend std::ostream & operator<<(std::ostream &, MD5 md5)
Definition: MD5.h:424
static void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.h:167
static void decode(uint4 output[], const uint1 input[], size_type len)
Definition: MD5.h:209
static uint4 H(uint4 x, uint4 y, uint4 z)
Definition: MD5.h:134
#define S12
Definition: MD5.h:105
std::string hexdigest() const
Definition: MD5.h:409
#define S23
Definition: MD5.h:110
static uint4 rotate_left(uint4 x, int n)
Definition: MD5.h:145
MD5 & finalize()
Definition: MD5.h:371
bool finalized
Definition: MD5.h:76
MD5()
Definition: MD5.h:175
static uint4 I(uint4 x, uint4 y, uint4 z)
Definition: MD5.h:139
static void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.h:162
#define S14
Definition: MD5.h:107
#define S32
Definition: MD5.h:113
#define S11
Definition: MD5.h:104
#define S13
Definition: MD5.h:106
uint4 count[2]
Definition: MD5.h:78
#define S44
Definition: MD5.h:119
std::string md5(const std::string str)
Definition: MD5.h:431
unsigned int size_type
Definition: MD5.h:53
unsigned char uint1
Definition: MD5.h:65
uint4 state[4]
Definition: MD5.h:79
static uint4 F(uint4 x, uint4 y, uint4 z)
Definition: MD5.h:124
static void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.h:157
#define S42
Definition: MD5.h:117