]> git.sesse.net Git - freerainbowtables/blob - Common/rt api/md4.cpp
2011 (C)
[freerainbowtables] / Common / rt api / md4.cpp
1 /*
2  * freerainbowtables is a project for generating, distributing, and using
3  * perfect rainbow tables
4  *
5  * Copyright Bitweasil
6  * Copyright 2009, 2010 DaniĆ«l Niggebrugge <niggebrugge@fox-it.com>
7  * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>
8  *
9  * This file is part of freerainbowtables.
10  *
11  * freerainbowtables is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * freerainbowtables is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
23  */
24
25 /*
26  * This code implements the MD4 message-digest algorithm.
27  * "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
28  * 
29  * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke
30  */
31
32 //#include <cstdlib>
33 #include <cstring>
34 #include "md4.h"
35
36 /* MD4 Defines as per RFC reference implementation */
37 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
38 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
39 #define H(x, y, z) ((x) ^ (y) ^ (z))
40 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
41 #define FF(a, b, c, d, x, s) { \
42     (a) += F ((b), (c), (d)) + (x); \
43     (a) = ROTATE_LEFT ((a), (s)); \
44   }
45 #define GG(a, b, c, d, x, s) { \
46     (a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \
47     (a) = ROTATE_LEFT ((a), (s)); \
48   }
49 #define HH(a, b, c, d, x, s) { \
50     (a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \
51     (a) = ROTATE_LEFT ((a), (s)); \
52   }
53 #define S11 3
54 #define S12 7
55 #define S13 11
56 #define S14 19
57 #define S21 3
58 #define S22 5
59 #define S23 9
60 #define S24 13
61 #define S31 3
62 #define S32 9
63 #define S33 11
64 #define S34 15
65 /* End MD4 Defines */
66
67
68 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
69 {
70         // For the hash working space
71         uint32 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
72
73         // For the output result
74         uint32 a,b,c,d;
75
76         b0 = 0x00000000;
77         b1 = 0x00000000;
78         b2 = 0x00000000;
79         b3 = 0x00000000;
80         b4 = 0x00000000;
81         b5 = 0x00000000;
82         b6 = 0x00000000;
83         b7 = 0x00000000;
84         b8 = 0x00000000;
85         b9 = 0x00000000;
86         b10 = 0x00000000;
87         b11 = 0x00000000;
88         b12 = 0x00000000;
89         b13 = 0x00000000;
90         b14 = 0x00000000;
91         b15 = 0x00000000; 
92
93         // LOAD DATA INTO b0 ... whatever here.   
94         switch (length)
95         {
96                 case 2:
97                 {
98                         unsigned char in[4];
99                         memcpy(in, pData, length);
100                         in[2] = 0x80;
101                         in[3] = 0x00;
102                         uint32 * pUiIn = (uint32 *) in;
103                         b0 = pUiIn[0];
104                 }
105                 break;
106                 case 4:
107                 {
108                         unsigned char in[4];
109                         memcpy(in, pData, length);
110                         uint32 * pUiIn = (uint32 *) in;
111                         b0 = pUiIn[0];
112                         b1 = 0x00000080;
113                 }
114                 break;
115                 case 6:
116                 {
117                         unsigned char in[8];
118                         memcpy(in, pData, length);
119                         in[6] = 0x80;
120                         in[7] = 0x00;
121                         uint32 * pUiIn = (uint32 *) in;
122                         b0 = pUiIn[0];
123                         b1 = pUiIn[1];
124                 }
125                 break;
126                 case 8:
127                 {
128                         unsigned char in[8];
129                         memcpy(in, pData, length);
130                         uint32 * pUiIn = (uint32 *) in;
131                         b0 = pUiIn[0];
132                         b1 = pUiIn[1];
133                         b2 = 0x00000080;
134                 }
135                 break;
136                 case 10:
137                 {
138                         unsigned char in[12];
139                         memcpy(in, pData, length);
140                         in[10] = 0x80;
141                         in[11] = 0x00;
142                         uint32 * pUiIn = (uint32 *) in;
143                         b0 = pUiIn[0];
144                         b1 = pUiIn[1];
145                         b2 = pUiIn[2];
146                 }
147                 break;
148                 default:
149                 {
150                         unsigned char in[32];
151                         memcpy(in, pData, length);
152                         in[length] = 0x80;
153                         memset(in + length + 1, 0, 32 - length - 1);
154                         uint32 * pUiIn = (uint32 *) in;
155                         b0 = pUiIn[0];
156                         b1 = pUiIn[1];
157                         b2 = pUiIn[2];
158                         b3 = pUiIn[3];
159                         b4 = pUiIn[4];
160                         b5 = pUiIn[5];
161                         b6 = pUiIn[6];
162                         b7 = pUiIn[7]; // max 14 2byte chars (ntlm)
163                         b8 = pUiIn[8];
164                 }
165                 break;
166         }
167
168         b14 = length << 3;
169
170         a = 0x67452301;
171         b = 0xefcdab89;
172         c = 0x98badcfe;
173         d = 0x10325476;
174
175         /* Round 1 */
176         FF (a, b, c, d, b0, S11); /* 1 */
177         FF (d, a, b, c, b1, S12); /* 2 */
178         FF (c, d, a, b, b2, S13); /* 3 */
179         FF (b, c, d, a, b3, S14); /* 4 */
180         FF (a, b, c, d, b4, S11); /* 5 */
181         FF (d, a, b, c, b5, S12); /* 6 */
182         FF (c, d, a, b, b6, S13); /* 7 */
183         FF (b, c, d, a, b7, S14); /* 8 */
184         FF (a, b, c, d, 0, S11); /* 9 */
185         FF (d, a, b, c, 0, S12); /* 10 */
186         FF (c, d, a, b, 0, S13); /* 11 */
187         FF (b, c, d, a, 0, S14); /* 12 */
188         FF (a, b, c, d, 0, S11); /* 13 */
189         FF (d, a, b, c, 0, S12); /* 14 */
190         FF (c, d, a, b, b14, S13); /* 15 */
191         FF (b, c, d, a, 0, S14); /* 16 */
192
193         /* Round 2 */
194         GG (a, b, c, d, b0, S21); /* 17 */
195         GG (d, a, b, c, b4, S22); /* 18 */
196         GG (c, d, a, b, 0, S23); /* 19 */
197         GG (b, c, d, a, 0, S24); /* 20 */
198         GG (a, b, c, d, b1, S21); /* 21 */
199         GG (d, a, b, c, b5, S22); /* 22 */
200         GG (c, d, a, b, 0, S23); /* 23 */
201         GG (b, c, d, a, 0, S24); /* 24 */
202         GG (a, b, c, d, b2, S21); /* 25 */
203         GG (d, a, b, c, b6, S22); /* 26 */
204         GG (c, d, a, b, 0, S23); /* 27 */
205         GG (b, c, d, a, b14, S24); /* 28 */
206         GG (a, b, c, d, b3, S21); /* 29 */
207         GG (d, a, b, c, b7, S22); /* 30 */
208         GG (c, d, a, b, 0, S23); /* 31 */
209         GG (b, c, d, a, 0, S24); /* 32 */
210
211         /* Round 3 */
212         HH (a, b, c, d, b0, S31); /* 33 */
213         HH (d, a, b, c, 0, S32); /* 34 */
214         HH (c, d, a, b, b4, S33); /* 35 */
215         HH (b, c, d, a, 0, S34); /* 36 */
216         HH (a, b, c, d, b2, S31); /* 37 */
217         HH (d, a, b, c, 0, S32); /* 38 */
218         HH (c, d, a, b, b6, S33); /* 39 */
219         HH (b, c, d, a, b14, S34); /* 40 */
220         HH (a, b, c, d, b1, S31); /* 41 */
221         HH (d, a, b, c, 0, S32); /* 42 */
222         HH (c, d, a, b, b5, S33); /* 43 */
223         HH (b, c, d, a, 0, S34); /* 44 */
224         HH (a, b, c, d, b3, S31); /* 45 */
225         HH (d, a, b, c, 0, S32); /* 46 */
226         HH (c, d, a, b, b7, S33); /* 47 */
227         HH (b, c, d, a, 0, S34); /* 48 */
228
229         // Finally, add initial values, as this is the only pass we make.
230         a += 0x67452301;
231         b += 0xefcdab89;
232         c += 0x98badcfe;
233         d += 0x10325476;
234
235         uint32 buf[4] = { a, b, c, d};
236         memcpy(pDigest, buf, 16);
237
238         return;
239 }