The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
md5.cpp
Go to the documentation of this file.
1 // MD5.CC - source code for the C++/object oriented translation and
2 // modification of MD5.
3 
4 // Translation and modification (c) 1995 by Mordechai T. Abzug
5 
6 // This translation/ modification is provided "as is," without express or
7 // implied warranty of any kind.
8 
9 // The translator/ modifier does not claim (1) that MD5 will do what you think
10 // it does; (2) that this translation/ modification is accurate; or (3) that
11 // this software is "merchantible." (Language for this disclaimer partially
12 // copied from the disclaimer below).
13 
14 /* based on:
15 
16  MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
17  MDDRIVER.C - test driver for MD2, MD4 and MD5
18 
19 
20  Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
21 rights reserved.
22 
23 License to copy and use this software is granted provided that it
24 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
25 Algorithm" in all material mentioning or referencing this software
26 or this function.
27 
28 License is also granted to make and use derivative works provided
29 that such works are identified as "derived from the RSA Data
30 Security, Inc. MD5 Message-Digest Algorithm" in all material
31 mentioning or referencing the derived work.
32 
33 RSA Data Security, Inc. makes no representations concerning either
34 the merchantability of this software or the suitability of this
35 software for any particular purpose. It is provided "as is"
36 without express or implied warranty of any kind.
37 
38 These notices must be retained in any copies of any part of this
39 documentation and/or software.
40 
41  */
42 
43 
44 
45 
46 
47 
48 #include "md5.hpp"
49 
50 #include <assert.h>
51 #include <iostream>
52 #include <string.h> // Edit: needed for strlen() (strings.h should
53  // include it but apparently does not for me)
54 
55 #include "global.hpp"
56 
57 
58 
59 // MD5 simple initialization method
60 
62  : state()
63  , count()
64  , buffer()
65  , digest()
66  , finalized(0)
67 {
68  init();
69 }
70 
71 // MD5 block update operation. Continues an MD5 message-digest
72 // operation, processing another message block, and updating the
73 // context.
74 
75 void MD5::update (const uint1* input, uint4 input_length) {
76 
77  uint4 input_index, buffer_index;
78  uint4 buffer_space; // how much space is left in buffer
79 
80  if (finalized){ // so we can't update!
81  std::cerr << "MD5::update: Can't update a finalized digest!" << std::endl;
82  return;
83  }
84 
85  // Compute number of bytes mod 64
86  buffer_index = ((count[0] >> 3) & 0x3F);
87 
88  // Update number of bits
89  if ( (count[0] += (input_length << 3))<(input_length << 3) )
90  count[1]++;
91 
92  count[1] += (input_length >> 29);
93 
94 
95  buffer_space = 64 - buffer_index; // how much space is left in buffer
96 
97  // Transform as many times as possible.
98  if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
99  // fill the rest of the buffer and transform
100  memcpy (buffer + buffer_index, input, buffer_space);
101  transform (buffer);
102 
103  // now, transform each 64-byte piece of the input, bypassing the buffer
104  for (input_index = buffer_space; input_index + 63 < input_length;
105  input_index += 64)
106  transform (input+input_index);
107 
108  buffer_index = 0; // so we can buffer remaining
109  }
110  else
111  input_index=0; // so we can buffer the whole input
112 
113 
114  // and here we do the buffering:
115  memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
116 }
117 
118 // MD5 finalization. Ends an MD5 message-digest operation, writing the
119 // the message digest and zeroizing the context.
120 
121 
123 
124  uint1 bits[8];
125  uint4 index, padLen;
126  static uint1 PADDING[64]={
127  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
129  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
130  };
131 
132  if (finalized){
133  std::cerr << "MD5::finalize: Already finalized this digest!" << std::endl;
134  return;
135  }
136 
137  // Save number of bits
138  encode (bits, count, 8);
139 
140  // Pad out to 56 mod 64.
141  index = (count[0] >> 3) & 0x3f;
142  padLen = (index < 56) ? (56 - index) : (120 - index);
143  update (PADDING, padLen);
144 
145  // Append length (before padding)
146  update (bits, 8);
147 
148  // Store state in digest
149  encode (digest, state, 16);
150 
151  // Zeroize sensitive information
152  memset (buffer, 0, sizeof(*buffer));
153 
154  finalized=1;
155 
156 }
157 
158 
159 std::array<uint8_t, 16> MD5::raw_digest()
160 {
161  std::array<uint8_t, 16> s;
162 
163  if (!finalized){
164  std::cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
165  "finalized the digest!" <<std::endl;
166  throw std::logic_error("MD5::raw_digest: attempted to obtain digest before finalizing it");
167  }
168 
169  memcpy(s.data(), digest, 16);
170  return s;
171 }
172 
173 // PRIVATE METHODS:
174 
175 void MD5::init(){
176  finalized=0; // we just started!
177 
178  // Nothing counted, so count=0
179  count[0] = 0;
180  count[1] = 0;
181 
182  // Load magic initialization constants.
183  state[0] = 0x67452301;
184  state[1] = 0xefcdab89;
185  state[2] = 0x98badcfe;
186  state[3] = 0x10325476;
187 }
188 
189 
190 
191 // Constants for MD5Transform routine.
192 // Although we could use C++ style constants, defines are actually better,
193 // since they let us easily evade scope clashes.
194 
195 #define S11 7
196 #define S12 12
197 #define S13 17
198 #define S14 22
199 #define S21 5
200 #define S22 9
201 #define S23 14
202 #define S24 20
203 #define S31 4
204 #define S32 11
205 #define S33 16
206 #define S34 23
207 #define S41 6
208 #define S42 10
209 #define S43 15
210 #define S44 21
211 
212 
213 
214 
215 // MD5 basic transformation. Transforms state based on block.
216 void MD5::transform (const uint1 block[64]){
217 
218  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
219 
220  decode (x, block, 64);
221 
222  assert(!finalized); // not just a user error, since the method is private
223 
224  /* Round 1 */
225  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
226  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
227  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
228  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
229  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
230  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
231  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
232  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
233  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
234  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
235  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
236  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
237  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
238  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
239  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
240  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
241 
242  /* Round 2 */
243  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
244  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
245  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
246  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
247  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
248  GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
249  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
250  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
251  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
252  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
253  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
254  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
255  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
256  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
257  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
258  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
259 
260  /* Round 3 */
261  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
262  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
263  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
264  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
265  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
266  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
267  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
268  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
269  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
270  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
271  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
272  HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
273  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
274  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
275  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
276  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
277 
278  /* Round 4 */
279  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
280  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
281  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
282  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
283  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
284  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
285  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
286  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
287  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
288  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
289  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
290  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
291  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
292  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
293  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
294  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
295 
296  state[0] += a;
297  state[1] += b;
298  state[2] += c;
299  state[3] += d;
300 
301  // Zeroize sensitive information.
302  memset ( reinterpret_cast<uint1*>(x), 0, sizeof(x));
303 
304 }
305 
306 
307 
308 // Encodes input (UINT4) into output (uint1). Assumes len is
309 // a multiple of 4.
311 
312  uint4 i, j;
313 
314  for (i = 0, j = 0; j < len; i++, j += 4) {
315  output[j] = static_cast<uint1> (input[i] & 0xff);
316  output[j+1] = static_cast<uint1>((input[i] >> 8) & 0xff);
317  output[j+2] = static_cast<uint1>((input[i] >> 16) & 0xff);
318  output[j+3] = static_cast<uint1>((input[i] >> 24) & 0xff);
319  }
320 }
321 
322 
323 
324 
325 // Decodes input (uint1) into output (UINT4). Assumes len is
326 // a multiple of 4.
328 
329  uint4 i, j;
330 
331  for (i = 0, j = 0; j < len; i++, j += 4)
332  output[i] = (static_cast<uint4>(input[j]))
333  | ((static_cast<uint4>(input[j+1])) << 8)
334  | ((static_cast<uint4>(input[j+2])) << 16)
335  | ((static_cast<uint4>(input[j+3])) << 24);
336 }
337 
338 
339 
340 
341 // ROTATE_LEFT rotates x left n bits.
342 
344  return (x << n) | (x >> (32-n)) ;
345 }
346 
347 
348 
349 
350 // F, G, H and I are basic MD5 functions.
351 
353  return (x & y) | (~x & z);
354 }
355 
357  return (x & z) | (y & ~z);
358 }
359 
361  return x ^ y ^ z;
362 }
363 
365  return y ^ (x | ~z);
366 }
367 
368 
369 
370 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
371 // Rotation is separate from addition to prevent recomputation.
372 
373 
374 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
375  uint4 s, uint4 ac){
376  a += F(b, c, d) + x + ac;
377  a = rotate_left (a, s) +b;
378 }
379 
380 inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
381  uint4 s, uint4 ac){
382  a += G(b, c, d) + x + ac;
383  a = rotate_left (a, s) +b;
384 }
385 
386 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
387  uint4 s, uint4 ac){
388  a += H(b, c, d) + x + ac;
389  a = rotate_left (a, s) +b;
390 }
391 
392 inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
393  uint4 s, uint4 ac){
394  a += I(b, c, d) + x + ac;
395  a = rotate_left (a, s) +b;
396 }
GLdouble GLdouble z
Definition: glew.h:1527
uint4 state[4]
Definition: md5.hpp:68
#define S43
Definition: md5.cpp:209
#define S34
Definition: md5.cpp:206
static void decode(uint4 *dest, const uint1 *src, uint4 length)
Definition: md5.cpp:327
uint1 finalized
Definition: md5.hpp:72
void update(const uint8_t *input, const uint32_t input_length)
Definition: md5.cpp:75
const GLfloat * c
Definition: glew.h:12741
#define S22
Definition: md5.cpp:200
#define S11
Definition: md5.cpp:195
GLenum GLenum GLenum input
Definition: glew.h:10668
static uint4 F(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:352
static uint4 I(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:364
static void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:392
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
#define d
#define S44
Definition: md5.cpp:210
void transform(const uint1 buffer[64])
Definition: md5.cpp:216
uint1 buffer[64]
Definition: md5.hpp:70
uint32_t uint4
Definition: md5.hpp:63
static uint4 rotate_left(uint4 x, uint4 n)
Definition: md5.cpp:343
uint8_t uint1
Definition: md5.hpp:65
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
#define S42
Definition: md5.cpp:208
GLuint GLenum GLenum transform
Definition: glew.h:11418
static uint4 G(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:356
#define S14
Definition: md5.cpp:198
static void encode(uint1 *dest, uint4 *src, uint4 length)
Definition: md5.cpp:310
#define S31
Definition: md5.cpp:203
static void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:386
GLenum GLsizei len
Definition: glew.h:5662
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
#define S13
Definition: md5.cpp:197
GLuint GLuint GLsizei count
Definition: glew.h:1221
void init()
Definition: md5.cpp:175
static void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:374
GLuint buffer
Definition: glew.h:1648
#define S21
Definition: md5.cpp:199
static const char * output
Definition: luac.cpp:31
#define S23
Definition: md5.cpp:201
static void block(LexState *ls)
Definition: lparser.cpp:1081
std::array< uint8_t, 16 > raw_digest()
Definition: md5.cpp:159
uint1 digest[16]
Definition: md5.hpp:71
GLuint index
Definition: glew.h:1782
#define S12
Definition: md5.cpp:196
size_t i
Definition: function.cpp:1057
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
static void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:380
void finalize()
Definition: md5.cpp:122
MD5()
Definition: md5.cpp:61
GLclampd n
Definition: glew.h:5903
#define S32
Definition: md5.cpp:204
#define S41
Definition: md5.cpp:207
#define c
Definition: glew.h:12743
static uint4 H(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:360
#define S24
Definition: md5.cpp:202
GLdouble s
Definition: glew.h:1358
#define S33
Definition: md5.cpp:205