]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/md4.cpp
rcracki_mt updated to rti2
[freerainbowtables] / Client Applications / rcracki_mt / md4.cpp
1 /*
2  * This code implements the MD4 message-digest algorithm.
3  * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil
4  * 
5  * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke
6  */
7
8
9 //#include <cstdlib>
10 #include <cstring>
11 #include "md4.h"
12
13 /* MD4 Defines as per RFC reference implementation */
14 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
15 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
16 #define H(x, y, z) ((x) ^ (y) ^ (z))
17 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
18 #define FF(a, b, c, d, x, s) { \
19     (a) += F ((b), (c), (d)) + (x); \
20     (a) = ROTATE_LEFT ((a), (s)); \
21   }
22 #define GG(a, b, c, d, x, s) { \
23     (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
24     (a) = ROTATE_LEFT ((a), (s)); \
25   }
26 #define HH(a, b, c, d, x, s) { \
27     (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
28     (a) = ROTATE_LEFT ((a), (s)); \
29   }
30 #define S11 3
31 #define S12 7
32 #define S13 11
33 #define S14 19
34 #define S21 3
35 #define S22 5
36 #define S23 9
37 #define S24 13
38 #define S31 3
39 #define S32 9
40 #define S33 11
41 #define S34 15
42 /* End MD4 Defines */
43
44 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
45 {
46         // access data as 4-byte word
47         #define uData                           ((UINT4 *)pData)
48         #define uDigest                         ((UINT4 *)pDigest)
49
50         // pad word and append bit at appropriate location
51         #define MD4_pad_w0()            (0x00000080)
52         #define MD4_pad_w1(data)        (((data) & 0x000000FF) | 0x00008000)
53         #define MD4_pad_w2(data)        (((data) & 0x0000FFFF) | 0x00800000)
54         #define MD4_pad_w3(data)        (((data) & 0x00FFFFFF) | 0x80000000)
55
56         // For the hash working space
57         //__attribute__((aligned(16))) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
58         //__declspec(align(16)) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
59         UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
60
61         // For the output result
62         UINT4 a,b,c,d;
63
64         switch (length)
65         {
66                 case 0:
67                 {
68                         data[ 0] = MD4_pad_w0();
69
70                         data[14] = 0;
71                 }
72                 break;
73                 case 1:
74                 {
75                         data[ 0] = MD4_pad_w1(uData[0]);
76
77                         data[14] = 1 << 3;
78                 }
79                 break;
80                 case 2:
81                 {
82                         data[ 0] = MD4_pad_w2(uData[0]);
83
84                         data[14] = 2 << 3;
85                 }
86                 break;
87                 case 3:
88                 {
89                         data[ 0] = MD4_pad_w3(uData[0]);
90
91                         data[14] = 3 << 3;
92                 }
93                 break;
94                 case 4:
95                 {
96                         data[ 0] = uData[0];
97                         data[ 1] = MD4_pad_w0();
98
99                         data[14] = 4 << 3;
100                 }
101                 break;
102                 case 5:
103                 {
104                         data[ 0] = uData[0];
105                         data[ 1] = MD4_pad_w1(uData[1]);
106
107                         data[14] = 5 << 3;
108                 }
109                 break;
110                 case 6:
111                 {
112                         data[ 0] = uData[0];
113                         data[ 1] = MD4_pad_w2(uData[1]);
114
115                         data[14] = 6 << 3;
116                 }
117                 break;
118                 case 7:
119                 {
120                         data[ 0] = uData[0];
121                         data[ 1] = MD4_pad_w3(uData[1]);
122
123                         data[14] = 7 << 3;
124                 }
125                 break;
126                 case 8:
127                 {
128                         data[ 0] = uData[0];
129                         data[ 1] = uData[1];
130                         data[ 2] = MD4_pad_w0();
131
132                         data[14] = 8 << 3;
133                 }
134                 break;
135                 case 9:
136                 {
137                         data[ 0] = uData[0];
138                         data[ 1] = uData[1];
139                         data[ 2] = MD4_pad_w1(uData[2]);
140
141                         data[14] = 9 << 3;
142                 }
143                 break;
144                 case 10:
145                 {
146                         data[ 0] = uData[0];
147                         data[ 1] = uData[1];
148                         data[ 2] = MD4_pad_w2(uData[2]);
149
150                         data[14] = 10 << 3;
151                 }
152                 break;
153                 case 11:
154                 {
155                         data[ 0] = uData[0];
156                         data[ 1] = uData[1];
157                         data[ 2] = MD4_pad_w3(uData[2]);
158
159                         data[14] = 11 << 3;
160                 }
161                 break;
162                 case 12:
163                 {
164                         data[ 0] = uData[0];
165                         data[ 1] = uData[1];
166                         data[ 2] = uData[2];
167                         data[ 3] = MD4_pad_w0();
168
169                         data[14] = 12 << 3;
170                 }
171                 break;
172                 case 13:
173                 {
174                         data[ 0] = uData[0];
175                         data[ 1] = uData[1];
176                         data[ 2] = uData[2];
177                         data[ 3] = MD4_pad_w1(uData[3]);
178
179                         data[14] = 13 << 3;
180                 }
181                 break;
182                 case 14:
183                 {
184                         data[ 0] = uData[0];
185                         data[ 1] = uData[1];
186                         data[ 2] = uData[2];
187                         data[ 3] = MD4_pad_w2(uData[3]);
188
189                         data[14] = 14 << 3;
190                 }
191                 break;
192                 case 15:
193                 {
194                         data[ 0] = uData[0];
195                         data[ 1] = uData[1];
196                         data[ 2] = uData[2];
197                         data[ 3] = MD4_pad_w3(uData[3]);
198
199                         data[14] = 15 << 3;
200                 }
201                 break;
202
203                 default:
204                 {
205                         length = length % 32; // lenght >= 32 not suported
206
207                         int word = length >> 2;
208
209                         int i = 0;
210                         while (i < word) {
211                                 data[i] = uData[i];
212                                 i++;
213                         }
214
215                         switch (length & 0x3) {
216                                 case 0:
217                                 {
218                                         data[word] = MD4_pad_w0();
219                                 }
220                                 break;
221                                 case 1:
222                                 {
223                                         data[word] = MD4_pad_w1(uData[word]);
224                                 }
225                                 break;
226                                 case 2:
227                                 {
228                                         data[word] = MD4_pad_w2(uData[word]);
229                                 }
230                                 break;
231                                 case 3:
232                                 {
233                                         data[word] = MD4_pad_w3(uData[word]);
234                                 }
235                                 break;
236                         }
237
238                         data[14] = length << 3;
239                 }
240                 break;
241         }
242
243         a = 0x67452301;
244         b = 0xefcdab89;
245         c = 0x98badcfe;
246         d = 0x10325476;
247
248         /* Round 1 */
249         FF (a, b, c, d, data[ 0], S11); /* 1 */
250         FF (d, a, b, c, data[ 1], S12); /* 2 */
251         FF (c, d, a, b, data[ 2], S13); /* 3 */
252         FF (b, c, d, a, data[ 3], S14); /* 4 */
253         FF (a, b, c, d, data[ 4], S11); /* 5 */
254         FF (d, a, b, c, data[ 5], S12); /* 6 */
255         FF (c, d, a, b, data[ 6], S13); /* 7 */
256         FF (b, c, d, a, data[ 7], S14); /* 8 */
257         FF (a, b, c, d,        0, S11); /* 9 */
258         FF (d, a, b, c,        0, S12); /* 10 */
259         FF (c, d, a, b,        0, S13); /* 11 */
260         FF (b, c, d, a,        0, S14); /* 12 */
261         FF (a, b, c, d,        0, S11); /* 13 */
262         FF (d, a, b, c,        0, S12); /* 14 */
263         FF (c, d, a, b, data[14], S13); /* 15 */
264         FF (b, c, d, a,        0, S14); /* 16 */
265
266         /* Round 2 */
267         GG (a, b, c, d, data[ 0], S21); /* 17 */
268         GG (d, a, b, c, data[ 4], S22); /* 18 */
269         GG (c, d, a, b,        0, S23); /* 19 */
270         GG (b, c, d, a,        0, S24); /* 20 */
271         GG (a, b, c, d, data[ 1], S21); /* 21 */
272         GG (d, a, b, c, data[ 5], S22); /* 22 */
273         GG (c, d, a, b,        0, S23); /* 23 */
274         GG (b, c, d, a,        0, S24); /* 24 */
275         GG (a, b, c, d, data[ 2], S21); /* 25 */
276         GG (d, a, b, c, data[ 6], S22); /* 26 */
277         GG (c, d, a, b,        0, S23); /* 27 */
278         GG (b, c, d, a, data[14], S24); /* 28 */
279         GG (a, b, c, d, data[ 3], S21); /* 29 */
280         GG (d, a, b, c, data[ 7], S22); /* 30 */
281         GG (c, d, a, b,        0, S23); /* 31 */
282         GG (b, c, d, a,        0, S24); /* 32 */
283
284         /* Round 3 */
285         HH (a, b, c, d, data[ 0], S31); /* 33 */
286         HH (d, a, b, c,        0, S32); /* 34 */
287         HH (c, d, a, b, data[ 4], S33); /* 35 */
288         HH (b, c, d, a,        0, S34); /* 36 */
289         HH (a, b, c, d, data[ 2], S31); /* 37 */
290         HH (d, a, b, c,        0, S32); /* 38 */
291         HH (c, d, a, b, data[ 6], S33); /* 39 */
292         HH (b, c, d, a, data[14], S34); /* 40 */
293         HH (a, b, c, d, data[ 1], S31); /* 41 */
294         HH (d, a, b, c,        0, S32); /* 42 */
295         HH (c, d, a, b, data[ 5], S33); /* 43 */
296         HH (b, c, d, a,        0, S34); /* 44 */
297         HH (a, b, c, d, data[ 3], S31); /* 45 */
298         HH (d, a, b, c,        0, S32); /* 46 */
299         HH (c, d, a, b, data[ 7], S33); /* 47 */
300         HH (b, c, d, a,        0, S34); /* 48 */
301
302         // Finally, add initial values, as this is the only pass we make.
303         a += 0x67452301;
304         b += 0xefcdab89;
305         c += 0x98badcfe;
306         d += 0x10325476;
307
308         uDigest[0] = a;
309         uDigest[1] = b;
310         uDigest[2] = c;
311         uDigest[3] = d;
312 }
313
314 //void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
315 //{
316 //      // For the hash working space
317 //      UINT4 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
318 //
319 //      // For the output result
320 //      UINT4 a,b,c,d;
321 //
322 //      b0 = 0x00000000;
323 //      b1 = 0x00000000;
324 //      b2 = 0x00000000;
325 //      b3 = 0x00000000;
326 //      b4 = 0x00000000;
327 //      b5 = 0x00000000;
328 //      b6 = 0x00000000;
329 //      b7 = 0x00000000;
330 //      b8 = 0x00000000;
331 //      b9 = 0x00000000;
332 //      b10 = 0x00000000;
333 //      b11 = 0x00000000;
334 //      b12 = 0x00000000;
335 //      b13 = 0x00000000;
336 //      b14 = 0x00000000;
337 //      b15 = 0x00000000; 
338 //
339 //      // LOAD DATA INTO b0 ... whatever here.   
340 //      switch (length)
341 //      {
342 //              case 2:
343 //              {
344 //                      unsigned char in[4];
345 //                      memcpy(in, pData, length);
346 //                      in[2] = 0x80;
347 //                      in[3] = 0x00;
348 //                      UINT4 * pUiIn = (UINT4 *) in;
349 //                      b0 = pUiIn[0];
350 //              }
351 //              break;
352 //              case 4:
353 //              {
354 //                      unsigned char in[4];
355 //                      memcpy(in, pData, length);
356 //                      UINT4 * pUiIn = (UINT4 *) in;
357 //                      b0 = pUiIn[0];
358 //                      b1 = 0x00000080;
359 //              }
360 //              break;
361 //              case 6:
362 //              {
363 //                      unsigned char in[8];
364 //                      memcpy(in, pData, length);
365 //                      in[6] = 0x80;
366 //                      in[7] = 0x00;
367 //                      UINT4 * pUiIn = (UINT4 *) in;
368 //                      b0 = pUiIn[0];
369 //                      b1 = pUiIn[1];
370 //              }
371 //              break;
372 //              case 8:
373 //              {
374 //                      unsigned char in[8];
375 //                      memcpy(in, pData, length);
376 //                      UINT4 * pUiIn = (UINT4 *) in;
377 //                      b0 = pUiIn[0];
378 //                      b1 = pUiIn[1];
379 //                      b2 = 0x00000080;
380 //              }
381 //              break;
382 //              case 10:
383 //              {
384 //                      unsigned char in[12];
385 //                      memcpy(in, pData, length);
386 //                      in[10] = 0x80;
387 //                      in[11] = 0x00;
388 //                      UINT4 * pUiIn = (UINT4 *) in;
389 //                      b0 = pUiIn[0];
390 //                      b1 = pUiIn[1];
391 //                      b2 = pUiIn[2];
392 //              }
393 //              break;
394 //              default:
395 //              {
396 //                      unsigned char in[32];
397 //                      memcpy(in, pData, length);
398 //                      in[length] = 0x80;
399 //                      memset(in + length + 1, 0, 32 - length - 1);
400 //                      UINT4 * pUiIn = (UINT4 *) in;
401 //                      b0 = pUiIn[0];
402 //                      b1 = pUiIn[1];
403 //                      b2 = pUiIn[2];
404 //                      b3 = pUiIn[3];
405 //                      b4 = pUiIn[4];
406 //                      b5 = pUiIn[5];
407 //                      b6 = pUiIn[6];
408 //                      b7 = pUiIn[7]; // max 14 2byte chars (ntlm)
409 //                      b8 = pUiIn[8];
410 //              }
411 //              break;
412 //      }
413 //
414 //      b14 = length << 3;
415 //
416 //      a = 0x67452301;
417 //      b = 0xefcdab89;
418 //      c = 0x98badcfe;
419 //      d = 0x10325476;
420 //
421 //      /* Round 1 */
422 //      FF (a, b, c, d, b0, S11); /* 1 */
423 //      FF (d, a, b, c, b1, S12); /* 2 */
424 //      FF (c, d, a, b, b2, S13); /* 3 */
425 //      FF (b, c, d, a, b3, S14); /* 4 */
426 //      FF (a, b, c, d, b4, S11); /* 5 */
427 //      FF (d, a, b, c, b5, S12); /* 6 */
428 //      FF (c, d, a, b, b6, S13); /* 7 */
429 //      FF (b, c, d, a, b7, S14); /* 8 */
430 //      FF (a, b, c, d, 0, S11); /* 9 */
431 //      FF (d, a, b, c, 0, S12); /* 10 */
432 //      FF (c, d, a, b, 0, S13); /* 11 */
433 //      FF (b, c, d, a, 0, S14); /* 12 */
434 //      FF (a, b, c, d, 0, S11); /* 13 */
435 //      FF (d, a, b, c, 0, S12); /* 14 */
436 //      FF (c, d, a, b, b14, S13); /* 15 */
437 //      FF (b, c, d, a, 0, S14); /* 16 */
438 //
439 //      /* Round 2 */
440 //      GG (a, b, c, d, b0, S21); /* 17 */
441 //      GG (d, a, b, c, b4, S22); /* 18 */
442 //      GG (c, d, a, b, 0, S23); /* 19 */
443 //      GG (b, c, d, a, 0, S24); /* 20 */
444 //      GG (a, b, c, d, b1, S21); /* 21 */
445 //      GG (d, a, b, c, b5, S22); /* 22 */
446 //      GG (c, d, a, b, 0, S23); /* 23 */
447 //      GG (b, c, d, a, 0, S24); /* 24 */
448 //      GG (a, b, c, d, b2, S21); /* 25 */
449 //      GG (d, a, b, c, b6, S22); /* 26 */
450 //      GG (c, d, a, b, 0, S23); /* 27 */
451 //      GG (b, c, d, a, b14, S24); /* 28 */
452 //      GG (a, b, c, d, b3, S21); /* 29 */
453 //      GG (d, a, b, c, b7, S22); /* 30 */
454 //      GG (c, d, a, b, 0, S23); /* 31 */
455 //      GG (b, c, d, a, 0, S24); /* 32 */
456 //
457 //      /* Round 3 */
458 //      HH (a, b, c, d, b0, S31); /* 33 */
459 //      HH (d, a, b, c, 0, S32); /* 34 */
460 //      HH (c, d, a, b, b4, S33); /* 35 */
461 //      HH (b, c, d, a, 0, S34); /* 36 */
462 //      HH (a, b, c, d, b2, S31); /* 37 */
463 //      HH (d, a, b, c, 0, S32); /* 38 */
464 //      HH (c, d, a, b, b6, S33); /* 39 */
465 //      HH (b, c, d, a, b14, S34); /* 40 */
466 //      HH (a, b, c, d, b1, S31); /* 41 */
467 //      HH (d, a, b, c, 0, S32); /* 42 */
468 //      HH (c, d, a, b, b5, S33); /* 43 */
469 //      HH (b, c, d, a, 0, S34); /* 44 */
470 //      HH (a, b, c, d, b3, S31); /* 45 */
471 //      HH (d, a, b, c, 0, S32); /* 46 */
472 //      HH (c, d, a, b, b7, S33); /* 47 */
473 //      HH (b, c, d, a, 0, S34); /* 48 */
474 //
475 //      // Finally, add initial values, as this is the only pass we make.
476 //      a += 0x67452301;
477 //      b += 0xefcdab89;
478 //      c += 0x98badcfe;
479 //      d += 0x10325476;
480 //
481 //      UINT4 buf[4] = { a, b, c, d};
482 //      memcpy(pDigest, buf, 16);
483 //
484 //      return;
485 //}