]> git.sesse.net Git - freerainbowtables/blob - Common/rt api/md4.cpp
UINT4 -> uint32
[freerainbowtables] / Common / rt api / 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) + (uint32)0x5a827999; \
24     (a) = ROTATE_LEFT ((a), (s)); \
25   }
26 #define HH(a, b, c, d, x, s) { \
27     (a) += H ((b), (c), (d)) + (x) + (uint32)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
45 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
46 {
47         // For the hash working space
48         uint32 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
49
50         // For the output result
51         uint32 a,b,c,d;
52
53         b0 = 0x00000000;
54         b1 = 0x00000000;
55         b2 = 0x00000000;
56         b3 = 0x00000000;
57         b4 = 0x00000000;
58         b5 = 0x00000000;
59         b6 = 0x00000000;
60         b7 = 0x00000000;
61         b8 = 0x00000000;
62         b9 = 0x00000000;
63         b10 = 0x00000000;
64         b11 = 0x00000000;
65         b12 = 0x00000000;
66         b13 = 0x00000000;
67         b14 = 0x00000000;
68         b15 = 0x00000000; 
69
70         // LOAD DATA INTO b0 ... whatever here.   
71         switch (length)
72         {
73                 case 2:
74                 {
75                         unsigned char in[4];
76                         memcpy(in, pData, length);
77                         in[2] = 0x80;
78                         in[3] = 0x00;
79                         uint32 * pUiIn = (uint32 *) in;
80                         b0 = pUiIn[0];
81                 }
82                 break;
83                 case 4:
84                 {
85                         unsigned char in[4];
86                         memcpy(in, pData, length);
87                         uint32 * pUiIn = (uint32 *) in;
88                         b0 = pUiIn[0];
89                         b1 = 0x00000080;
90                 }
91                 break;
92                 case 6:
93                 {
94                         unsigned char in[8];
95                         memcpy(in, pData, length);
96                         in[6] = 0x80;
97                         in[7] = 0x00;
98                         uint32 * pUiIn = (uint32 *) in;
99                         b0 = pUiIn[0];
100                         b1 = pUiIn[1];
101                 }
102                 break;
103                 case 8:
104                 {
105                         unsigned char in[8];
106                         memcpy(in, pData, length);
107                         uint32 * pUiIn = (uint32 *) in;
108                         b0 = pUiIn[0];
109                         b1 = pUiIn[1];
110                         b2 = 0x00000080;
111                 }
112                 break;
113                 case 10:
114                 {
115                         unsigned char in[12];
116                         memcpy(in, pData, length);
117                         in[10] = 0x80;
118                         in[11] = 0x00;
119                         uint32 * pUiIn = (uint32 *) in;
120                         b0 = pUiIn[0];
121                         b1 = pUiIn[1];
122                         b2 = pUiIn[2];
123                 }
124                 break;
125                 default:
126                 {
127                         unsigned char in[32];
128                         memcpy(in, pData, length);
129                         in[length] = 0x80;
130                         memset(in + length + 1, 0, 32 - length - 1);
131                         uint32 * pUiIn = (uint32 *) in;
132                         b0 = pUiIn[0];
133                         b1 = pUiIn[1];
134                         b2 = pUiIn[2];
135                         b3 = pUiIn[3];
136                         b4 = pUiIn[4];
137                         b5 = pUiIn[5];
138                         b6 = pUiIn[6];
139                         b7 = pUiIn[7]; // max 14 2byte chars (ntlm)
140                         b8 = pUiIn[8];
141                 }
142                 break;
143         }
144
145         b14 = length << 3;
146
147         a = 0x67452301;
148         b = 0xefcdab89;
149         c = 0x98badcfe;
150         d = 0x10325476;
151
152         /* Round 1 */
153         FF (a, b, c, d, b0, S11); /* 1 */
154         FF (d, a, b, c, b1, S12); /* 2 */
155         FF (c, d, a, b, b2, S13); /* 3 */
156         FF (b, c, d, a, b3, S14); /* 4 */
157         FF (a, b, c, d, b4, S11); /* 5 */
158         FF (d, a, b, c, b5, S12); /* 6 */
159         FF (c, d, a, b, b6, S13); /* 7 */
160         FF (b, c, d, a, b7, S14); /* 8 */
161         FF (a, b, c, d, 0, S11); /* 9 */
162         FF (d, a, b, c, 0, S12); /* 10 */
163         FF (c, d, a, b, 0, S13); /* 11 */
164         FF (b, c, d, a, 0, S14); /* 12 */
165         FF (a, b, c, d, 0, S11); /* 13 */
166         FF (d, a, b, c, 0, S12); /* 14 */
167         FF (c, d, a, b, b14, S13); /* 15 */
168         FF (b, c, d, a, 0, S14); /* 16 */
169
170         /* Round 2 */
171         GG (a, b, c, d, b0, S21); /* 17 */
172         GG (d, a, b, c, b4, S22); /* 18 */
173         GG (c, d, a, b, 0, S23); /* 19 */
174         GG (b, c, d, a, 0, S24); /* 20 */
175         GG (a, b, c, d, b1, S21); /* 21 */
176         GG (d, a, b, c, b5, S22); /* 22 */
177         GG (c, d, a, b, 0, S23); /* 23 */
178         GG (b, c, d, a, 0, S24); /* 24 */
179         GG (a, b, c, d, b2, S21); /* 25 */
180         GG (d, a, b, c, b6, S22); /* 26 */
181         GG (c, d, a, b, 0, S23); /* 27 */
182         GG (b, c, d, a, b14, S24); /* 28 */
183         GG (a, b, c, d, b3, S21); /* 29 */
184         GG (d, a, b, c, b7, S22); /* 30 */
185         GG (c, d, a, b, 0, S23); /* 31 */
186         GG (b, c, d, a, 0, S24); /* 32 */
187
188         /* Round 3 */
189         HH (a, b, c, d, b0, S31); /* 33 */
190         HH (d, a, b, c, 0, S32); /* 34 */
191         HH (c, d, a, b, b4, S33); /* 35 */
192         HH (b, c, d, a, 0, S34); /* 36 */
193         HH (a, b, c, d, b2, S31); /* 37 */
194         HH (d, a, b, c, 0, S32); /* 38 */
195         HH (c, d, a, b, b6, S33); /* 39 */
196         HH (b, c, d, a, b14, S34); /* 40 */
197         HH (a, b, c, d, b1, S31); /* 41 */
198         HH (d, a, b, c, 0, S32); /* 42 */
199         HH (c, d, a, b, b5, S33); /* 43 */
200         HH (b, c, d, a, 0, S34); /* 44 */
201         HH (a, b, c, d, b3, S31); /* 45 */
202         HH (d, a, b, c, 0, S32); /* 46 */
203         HH (c, d, a, b, b7, S33); /* 47 */
204         HH (b, c, d, a, 0, S34); /* 48 */
205
206         // Finally, add initial values, as this is the only pass we make.
207         a += 0x67452301;
208         b += 0xefcdab89;
209         c += 0x98badcfe;
210         d += 0x10325476;
211
212         uint32 buf[4] = { a, b, c, d};
213         memcpy(pDigest, buf, 16);
214
215         return;
216 }