]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/md4.cpp
UINT4 -> uint32
[freerainbowtables] / Client Applications / rcracki_mt / md4.cpp
1 /*\r
2  * rcracki_mt is a multithreaded implementation and fork of the original \r
3  * RainbowCrack\r
4  *\r
5  * Copyright Bitweasil\r
6  * Copyright 2009, 2010 DaniĆ«l Niggebrugge <niggebrugge@fox-it.com>\r
7  * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
8  *\r
9  * This file is part of rcracki_mt.\r
10  *\r
11  * rcracki_mt is free software: you can redistribute it and/or modify\r
12  * it under the terms of the GNU General Public License as published by\r
13  * the Free Software Foundation, either version 2 of the License, or\r
14  * (at your option) any later version.\r
15  *\r
16  * rcracki_mt is distributed in the hope that it will be useful,\r
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
19  * GNU General Public License for more details.\r
20  *\r
21  * You should have received a copy of the GNU General Public License\r
22  * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
23  *\r
24  * This code implements the MD4 message-digest algorithm.\r
25  * "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\r
26  * \r
27  * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke\r
28  */\r
29 \r
30 \r
31 //#include <cstdlib>\r
32 //#include <cstring>\r
33 #include "md4.h"\r
34 \r
35 /* MD4 Defines as per RFC reference implementation */\r
36 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))\r
37 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))\r
38 #define H(x, y, z) ((x) ^ (y) ^ (z))\r
39 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))\r
40 #define FF(a, b, c, d, x, s) { \\r
41                 (a) += F ((b), (c), (d)) + (x); \\r
42                 (a) = ROTATE_LEFT ((a), (s)); \\r
43         }\r
44 #define GG(a, b, c, d, x, s) { \\r
45                 (a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \\r
46                 (a) = ROTATE_LEFT ((a), (s)); \\r
47         }\r
48 #define HH(a, b, c, d, x, s) { \\r
49                 (a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \\r
50                 (a) = ROTATE_LEFT ((a), (s)); \\r
51         }\r
52 #define S11 3\r
53 #define S12 7\r
54 #define S13 11\r
55 #define S14 19\r
56 #define S21 3\r
57 #define S22 5\r
58 #define S23 9\r
59 #define S24 13\r
60 #define S31 3\r
61 #define S32 9\r
62 #define S33 11\r
63 #define S34 15\r
64 /* End MD4 Defines */\r
65 \r
66 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)\r
67 {\r
68         // access data as 4-byte word\r
69         #define uData                           ((uint32 *)pData)\r
70         #define uDigest                         ((uint32 *)pDigest)\r
71 \r
72         // pad word and append bit at appropriate location\r
73         #define MD4_pad_w0()            (0x00000080)\r
74         #define MD4_pad_w1(data)        (((data) & 0x000000FF) | 0x00008000)\r
75         #define MD4_pad_w2(data)        (((data) & 0x0000FFFF) | 0x00800000)\r
76         #define MD4_pad_w3(data)        (((data) & 0x00FFFFFF) | 0x80000000)\r
77 \r
78         // For the hash working space\r
79         //__attribute__((aligned(16))) uint32 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
80         //__declspec(align(16)) uint32 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
81         uint32 data[MD4_DIGEST_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
82 \r
83         // For the output result\r
84         uint32 a,b,c,d;\r
85 \r
86         switch (length)\r
87         {\r
88                 case 0:\r
89                 {\r
90                         data[ 0] = MD4_pad_w0();\r
91 \r
92                         data[14] = 0;\r
93                 }\r
94                 break;\r
95                 case 1:\r
96                 {\r
97                         data[ 0] = MD4_pad_w1(uData[0]);\r
98 \r
99                         data[14] = 1 << 3;\r
100                 }\r
101                 break;\r
102                 case 2:\r
103                 {\r
104                         data[ 0] = MD4_pad_w2(uData[0]);\r
105 \r
106                         data[14] = 2 << 3;\r
107                 }\r
108                 break;\r
109                 case 3:\r
110                 {\r
111                         data[ 0] = MD4_pad_w3(uData[0]);\r
112 \r
113                         data[14] = 3 << 3;\r
114                 }\r
115                 break;\r
116                 case 4:\r
117                 {\r
118                         data[ 0] = uData[0];\r
119                         data[ 1] = MD4_pad_w0();\r
120 \r
121                         data[14] = 4 << 3;\r
122                 }\r
123                 break;\r
124                 case 5:\r
125                 {\r
126                         data[ 0] = uData[0];\r
127                         data[ 1] = MD4_pad_w1(uData[1]);\r
128 \r
129                         data[14] = 5 << 3;\r
130                 }\r
131                 break;\r
132                 case 6:\r
133                 {\r
134                         data[ 0] = uData[0];\r
135                         data[ 1] = MD4_pad_w2(uData[1]);\r
136 \r
137                         data[14] = 6 << 3;\r
138                 }\r
139                 break;\r
140                 case 7:\r
141                 {\r
142                         data[ 0] = uData[0];\r
143                         data[ 1] = MD4_pad_w3(uData[1]);\r
144 \r
145                         data[14] = 7 << 3;\r
146                 }\r
147                 break;\r
148                 case 8:\r
149                 {\r
150                         data[ 0] = uData[0];\r
151                         data[ 1] = uData[1];\r
152                         data[ 2] = MD4_pad_w0();\r
153 \r
154                         data[14] = 8 << 3;\r
155                 }\r
156                 break;\r
157                 case 9:\r
158                 {\r
159                         data[ 0] = uData[0];\r
160                         data[ 1] = uData[1];\r
161                         data[ 2] = MD4_pad_w1(uData[2]);\r
162 \r
163                         data[14] = 9 << 3;\r
164                 }\r
165                 break;\r
166                 case 10:\r
167                 {\r
168                         data[ 0] = uData[0];\r
169                         data[ 1] = uData[1];\r
170                         data[ 2] = MD4_pad_w2(uData[2]);\r
171 \r
172                         data[14] = 10 << 3;\r
173                 }\r
174                 break;\r
175                 case 11:\r
176                 {\r
177                         data[ 0] = uData[0];\r
178                         data[ 1] = uData[1];\r
179                         data[ 2] = MD4_pad_w3(uData[2]);\r
180 \r
181                         data[14] = 11 << 3;\r
182                 }\r
183                 break;\r
184                 case 12:\r
185                 {\r
186                         data[ 0] = uData[0];\r
187                         data[ 1] = uData[1];\r
188                         data[ 2] = uData[2];\r
189                         data[ 3] = MD4_pad_w0();\r
190 \r
191                         data[14] = 12 << 3;\r
192                 }\r
193                 break;\r
194                 case 13:\r
195                 {\r
196                         data[ 0] = uData[0];\r
197                         data[ 1] = uData[1];\r
198                         data[ 2] = uData[2];\r
199                         data[ 3] = MD4_pad_w1(uData[3]);\r
200 \r
201                         data[14] = 13 << 3;\r
202                 }\r
203                 break;\r
204                 case 14:\r
205                 {\r
206                         data[ 0] = uData[0];\r
207                         data[ 1] = uData[1];\r
208                         data[ 2] = uData[2];\r
209                         data[ 3] = MD4_pad_w2(uData[3]);\r
210 \r
211                         data[14] = 14 << 3;\r
212                 }\r
213                 break;\r
214                 case 15:\r
215                 {\r
216                         data[ 0] = uData[0];\r
217                         data[ 1] = uData[1];\r
218                         data[ 2] = uData[2];\r
219                         data[ 3] = MD4_pad_w3(uData[3]);\r
220 \r
221                         data[14] = 15 << 3;\r
222                 }\r
223                 break;\r
224 \r
225                 default:\r
226                 {\r
227                         length = length % 32; // lenght >= 32 not suported\r
228 \r
229                         int word = length >> 2;\r
230 \r
231                         int i = 0;\r
232                         while (i < word) {\r
233                                 data[i] = uData[i];\r
234                                 i++;\r
235                         }\r
236 \r
237                         switch (length & 0x3) {\r
238                                 case 0:\r
239                                 {\r
240                                         data[word] = MD4_pad_w0();\r
241                                 }\r
242                                 break;\r
243                                 case 1:\r
244                                 {\r
245                                         data[word] = MD4_pad_w1(uData[word]);\r
246                                 }\r
247                                 break;\r
248                                 case 2:\r
249                                 {\r
250                                         data[word] = MD4_pad_w2(uData[word]);\r
251                                 }\r
252                                 break;\r
253                                 case 3:\r
254                                 {\r
255                                         data[word] = MD4_pad_w3(uData[word]);\r
256                                 }\r
257                                 break;\r
258                         }\r
259 \r
260                         data[14] = length << 3;\r
261                 }\r
262                 break;\r
263         }\r
264 \r
265         a = 0x67452301;\r
266         b = 0xefcdab89;\r
267         c = 0x98badcfe;\r
268         d = 0x10325476;\r
269 \r
270         /* Round 1 */\r
271         FF (a, b, c, d, data[ 0], S11); /* 1 */\r
272         FF (d, a, b, c, data[ 1], S12); /* 2 */\r
273         FF (c, d, a, b, data[ 2], S13); /* 3 */\r
274         FF (b, c, d, a, data[ 3], S14); /* 4 */\r
275         FF (a, b, c, d, data[ 4], S11); /* 5 */\r
276         FF (d, a, b, c, data[ 5], S12); /* 6 */\r
277         FF (c, d, a, b, data[ 6], S13); /* 7 */\r
278         FF (b, c, d, a, data[ 7], S14); /* 8 */\r
279         FF (a, b, c, d,        0, S11); /* 9 */\r
280         FF (d, a, b, c,        0, S12); /* 10 */\r
281         FF (c, d, a, b,        0, S13); /* 11 */\r
282         FF (b, c, d, a,        0, S14); /* 12 */\r
283         FF (a, b, c, d,        0, S11); /* 13 */\r
284         FF (d, a, b, c,        0, S12); /* 14 */\r
285         FF (c, d, a, b, data[14], S13); /* 15 */\r
286         FF (b, c, d, a,        0, S14); /* 16 */\r
287 \r
288         /* Round 2 */\r
289         GG (a, b, c, d, data[ 0], S21); /* 17 */\r
290         GG (d, a, b, c, data[ 4], S22); /* 18 */\r
291         GG (c, d, a, b,        0, S23); /* 19 */\r
292         GG (b, c, d, a,        0, S24); /* 20 */\r
293         GG (a, b, c, d, data[ 1], S21); /* 21 */\r
294         GG (d, a, b, c, data[ 5], S22); /* 22 */\r
295         GG (c, d, a, b,        0, S23); /* 23 */\r
296         GG (b, c, d, a,        0, S24); /* 24 */\r
297         GG (a, b, c, d, data[ 2], S21); /* 25 */\r
298         GG (d, a, b, c, data[ 6], S22); /* 26 */\r
299         GG (c, d, a, b,        0, S23); /* 27 */\r
300         GG (b, c, d, a, data[14], S24); /* 28 */\r
301         GG (a, b, c, d, data[ 3], S21); /* 29 */\r
302         GG (d, a, b, c, data[ 7], S22); /* 30 */\r
303         GG (c, d, a, b,        0, S23); /* 31 */\r
304         GG (b, c, d, a,        0, S24); /* 32 */\r
305 \r
306         /* Round 3 */\r
307         HH (a, b, c, d, data[ 0], S31); /* 33 */\r
308         HH (d, a, b, c,        0, S32); /* 34 */\r
309         HH (c, d, a, b, data[ 4], S33); /* 35 */\r
310         HH (b, c, d, a,        0, S34); /* 36 */\r
311         HH (a, b, c, d, data[ 2], S31); /* 37 */\r
312         HH (d, a, b, c,        0, S32); /* 38 */\r
313         HH (c, d, a, b, data[ 6], S33); /* 39 */\r
314         HH (b, c, d, a, data[14], S34); /* 40 */\r
315         HH (a, b, c, d, data[ 1], S31); /* 41 */\r
316         HH (d, a, b, c,        0, S32); /* 42 */\r
317         HH (c, d, a, b, data[ 5], S33); /* 43 */\r
318         HH (b, c, d, a,        0, S34); /* 44 */\r
319         HH (a, b, c, d, data[ 3], S31); /* 45 */\r
320         HH (d, a, b, c,        0, S32); /* 46 */\r
321         HH (c, d, a, b, data[ 7], S33); /* 47 */\r
322         HH (b, c, d, a,        0, S34); /* 48 */\r
323 \r
324         // Finally, add initial values, as this is the only pass we make.\r
325         a += 0x67452301;\r
326         b += 0xefcdab89;\r
327         c += 0x98badcfe;\r
328         d += 0x10325476;\r
329 \r
330         uDigest[0] = a;\r
331         uDigest[1] = b;\r
332         uDigest[2] = c;\r
333         uDigest[3] = d;\r
334 }\r