2 * rcracki_mt is a multithreaded implementation and fork of the original
\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
9 * This file is part of rcracki_mt.
\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
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
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
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
27 * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke
\r
31 //#include <cstdlib>
\r
32 //#include <cstring>
\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
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
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
64 /* End MD4 Defines */
\r
66 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
\r
68 // access data as 4-byte word
\r
69 #define uData ((uint32 *)pData)
\r
70 #define uDigest ((uint32 *)pDigest)
\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
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
83 // For the output result
\r
90 data[ 0] = MD4_pad_w0();
\r
97 data[ 0] = MD4_pad_w1(uData[0]);
\r
104 data[ 0] = MD4_pad_w2(uData[0]);
\r
111 data[ 0] = MD4_pad_w3(uData[0]);
\r
118 data[ 0] = uData[0];
\r
119 data[ 1] = MD4_pad_w0();
\r
126 data[ 0] = uData[0];
\r
127 data[ 1] = MD4_pad_w1(uData[1]);
\r
134 data[ 0] = uData[0];
\r
135 data[ 1] = MD4_pad_w2(uData[1]);
\r
142 data[ 0] = uData[0];
\r
143 data[ 1] = MD4_pad_w3(uData[1]);
\r
150 data[ 0] = uData[0];
\r
151 data[ 1] = uData[1];
\r
152 data[ 2] = MD4_pad_w0();
\r
159 data[ 0] = uData[0];
\r
160 data[ 1] = uData[1];
\r
161 data[ 2] = MD4_pad_w1(uData[2]);
\r
168 data[ 0] = uData[0];
\r
169 data[ 1] = uData[1];
\r
170 data[ 2] = MD4_pad_w2(uData[2]);
\r
172 data[14] = 10 << 3;
\r
177 data[ 0] = uData[0];
\r
178 data[ 1] = uData[1];
\r
179 data[ 2] = MD4_pad_w3(uData[2]);
\r
181 data[14] = 11 << 3;
\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
191 data[14] = 12 << 3;
\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
201 data[14] = 13 << 3;
\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
211 data[14] = 14 << 3;
\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
221 data[14] = 15 << 3;
\r
227 length = length % 32; // lenght >= 32 not suported
\r
229 int word = length >> 2;
\r
233 data[i] = uData[i];
\r
237 switch (length & 0x3) {
\r
240 data[word] = MD4_pad_w0();
\r
245 data[word] = MD4_pad_w1(uData[word]);
\r
250 data[word] = MD4_pad_w2(uData[word]);
\r
255 data[word] = MD4_pad_w3(uData[word]);
\r
260 data[14] = length << 3;
\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
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
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
324 // Finally, add initial values, as this is the only pass we make.
\r