1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy.utils;
21
22 import java.security.DigestException;
23 import java.security.MessageDigestSpi;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class MD4 extends MessageDigestSpi {
38
39
40
41
42 public static final int BYTE_DIGEST_LENGTH = 16;
43
44
45
46
47 public static final int BYTE_BLOCK_LENGTH = 64;
48
49
50
51
52
53 private final static int A = 0x67452301;
54
55 private final static int B = 0xefcdab89;
56
57 private final static int C = 0x98badcfe;
58
59 private final static int D = 0x10325476;
60
61
62
63
64 private int a = A;
65
66 private int b = B;
67
68 private int c = C;
69
70 private int d = D;
71
72
73
74
75 private long msgLength;
76
77
78
79
80 private final byte[] buffer = new byte[BYTE_BLOCK_LENGTH];
81
82
83
84
85 public MD4() {
86
87 }
88
89
90
91
92
93
94 protected int engineGetDigestLength() {
95 return BYTE_DIGEST_LENGTH;
96 }
97
98
99
100
101 protected void engineUpdate(byte b) {
102 int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
103 buffer[pos] = b;
104 msgLength++;
105
106
107 if (pos == (BYTE_BLOCK_LENGTH - 1)) {
108 process(buffer, 0);
109 }
110 }
111
112
113
114
115 protected void engineUpdate(byte[] b, int offset, int len) {
116 int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
117 int nbOfCharsToFillBuf = BYTE_BLOCK_LENGTH - pos;
118 int blkStart = 0;
119
120 msgLength += len;
121
122
123 if (len >= nbOfCharsToFillBuf) {
124 System.arraycopy(b, offset, buffer, pos, nbOfCharsToFillBuf);
125 process(buffer, 0);
126 for (blkStart = nbOfCharsToFillBuf; blkStart + BYTE_BLOCK_LENGTH - 1 < len; blkStart += BYTE_BLOCK_LENGTH) {
127 process(b, offset + blkStart);
128 }
129 pos = 0;
130 }
131
132
133 if (blkStart < len) {
134 System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
135 }
136 }
137
138
139
140
141 protected byte[] engineDigest() {
142 byte[] p = pad();
143 engineUpdate(p, 0, p.length);
144 byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16), (byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
145 (byte) (b >>> 16), (byte) (b >>> 24), (byte) c, (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
146 (byte) d, (byte) (d >>> 8), (byte) (d >>> 16), (byte) (d >>> 24) };
147
148 engineReset();
149
150 return digest;
151 }
152
153
154
155
156 protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
157 if (offset < 0 || offset + len >= buf.length) {
158 throw new DigestException("Wrong offset or not enough space to store the digest");
159 }
160 int destLength = Math.min(len, BYTE_DIGEST_LENGTH);
161 System.arraycopy(engineDigest(), 0, buf, offset, destLength);
162 return destLength;
163 }
164
165
166
167
168 protected void engineReset() {
169 a = A;
170 b = B;
171 c = C;
172 d = D;
173 msgLength = 0;
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187 private byte[] pad() {
188 int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
189 int padLength = (pos < 56) ? (64 - pos) : (128 - pos);
190 byte[] pad = new byte[padLength];
191
192
193 pad[0] = (byte) 0x80;
194
195 long bits = msgLength << 3;
196 int index = padLength - 8;
197 for (int i = 0; i < 8; i++) {
198 pad[index++] = (byte) (bits >>> (i << 3));
199 }
200
201 return pad;
202 }
203
204
205
206
207
208
209
210
211 private void process(byte[] in, int offset) {
212
213 int aa = a;
214 int bb = b;
215 int cc = c;
216 int dd = d;
217
218
219 int[] X = new int[16];
220 for (int i = 0; i < 16; i++) {
221 X[i] = (in[offset++] & 0xff) | (in[offset++] & 0xff) << 8 | (in[offset++] & 0xff) << 16
222 | (in[offset++] & 0xff) << 24;
223 }
224
225
226 a += ((b & c) | (~b & d)) + X[0];
227 a = a << 3 | a >>> (32 - 3);
228 d += ((a & b) | (~a & c)) + X[1];
229 d = d << 7 | d >>> (32 - 7);
230 c += ((d & a) | (~d & b)) + X[2];
231 c = c << 11 | c >>> (32 - 11);
232 b += ((c & d) | (~c & a)) + X[3];
233 b = b << 19 | b >>> (32 - 19);
234 a += ((b & c) | (~b & d)) + X[4];
235 a = a << 3 | a >>> (32 - 3);
236 d += ((a & b) | (~a & c)) + X[5];
237 d = d << 7 | d >>> (32 - 7);
238 c += ((d & a) | (~d & b)) + X[6];
239 c = c << 11 | c >>> (32 - 11);
240 b += ((c & d) | (~c & a)) + X[7];
241 b = b << 19 | b >>> (32 - 19);
242 a += ((b & c) | (~b & d)) + X[8];
243 a = a << 3 | a >>> (32 - 3);
244 d += ((a & b) | (~a & c)) + X[9];
245 d = d << 7 | d >>> (32 - 7);
246 c += ((d & a) | (~d & b)) + X[10];
247 c = c << 11 | c >>> (32 - 11);
248 b += ((c & d) | (~c & a)) + X[11];
249 b = b << 19 | b >>> (32 - 19);
250 a += ((b & c) | (~b & d)) + X[12];
251 a = a << 3 | a >>> (32 - 3);
252 d += ((a & b) | (~a & c)) + X[13];
253 d = d << 7 | d >>> (32 - 7);
254 c += ((d & a) | (~d & b)) + X[14];
255 c = c << 11 | c >>> (32 - 11);
256 b += ((c & d) | (~c & a)) + X[15];
257 b = b << 19 | b >>> (32 - 19);
258
259
260 a += ((b & (c | d)) | (c & d)) + X[0] + 0x5a827999;
261 a = a << 3 | a >>> (32 - 3);
262 d += ((a & (b | c)) | (b & c)) + X[4] + 0x5a827999;
263 d = d << 5 | d >>> (32 - 5);
264 c += ((d & (a | b)) | (a & b)) + X[8] + 0x5a827999;
265 c = c << 9 | c >>> (32 - 9);
266 b += ((c & (d | a)) | (d & a)) + X[12] + 0x5a827999;
267 b = b << 13 | b >>> (32 - 13);
268 a += ((b & (c | d)) | (c & d)) + X[1] + 0x5a827999;
269 a = a << 3 | a >>> (32 - 3);
270 d += ((a & (b | c)) | (b & c)) + X[5] + 0x5a827999;
271 d = d << 5 | d >>> (32 - 5);
272 c += ((d & (a | b)) | (a & b)) + X[9] + 0x5a827999;
273 c = c << 9 | c >>> (32 - 9);
274 b += ((c & (d | a)) | (d & a)) + X[13] + 0x5a827999;
275 b = b << 13 | b >>> (32 - 13);
276 a += ((b & (c | d)) | (c & d)) + X[2] + 0x5a827999;
277 a = a << 3 | a >>> (32 - 3);
278 d += ((a & (b | c)) | (b & c)) + X[6] + 0x5a827999;
279 d = d << 5 | d >>> (32 - 5);
280 c += ((d & (a | b)) | (a & b)) + X[10] + 0x5a827999;
281 c = c << 9 | c >>> (32 - 9);
282 b += ((c & (d | a)) | (d & a)) + X[14] + 0x5a827999;
283 b = b << 13 | b >>> (32 - 13);
284 a += ((b & (c | d)) | (c & d)) + X[3] + 0x5a827999;
285 a = a << 3 | a >>> (32 - 3);
286 d += ((a & (b | c)) | (b & c)) + X[7] + 0x5a827999;
287 d = d << 5 | d >>> (32 - 5);
288 c += ((d & (a | b)) | (a & b)) + X[11] + 0x5a827999;
289 c = c << 9 | c >>> (32 - 9);
290 b += ((c & (d | a)) | (d & a)) + X[15] + 0x5a827999;
291 b = b << 13 | b >>> (32 - 13);
292
293
294 a += (b ^ c ^ d) + X[0] + 0x6ed9eba1;
295 a = a << 3 | a >>> (32 - 3);
296 d += (a ^ b ^ c) + X[8] + 0x6ed9eba1;
297 d = d << 9 | d >>> (32 - 9);
298 c += (d ^ a ^ b) + X[4] + 0x6ed9eba1;
299 c = c << 11 | c >>> (32 - 11);
300 b += (c ^ d ^ a) + X[12] + 0x6ed9eba1;
301 b = b << 15 | b >>> (32 - 15);
302 a += (b ^ c ^ d) + X[2] + 0x6ed9eba1;
303 a = a << 3 | a >>> (32 - 3);
304 d += (a ^ b ^ c) + X[10] + 0x6ed9eba1;
305 d = d << 9 | d >>> (32 - 9);
306 c += (d ^ a ^ b) + X[6] + 0x6ed9eba1;
307 c = c << 11 | c >>> (32 - 11);
308 b += (c ^ d ^ a) + X[14] + 0x6ed9eba1;
309 b = b << 15 | b >>> (32 - 15);
310 a += (b ^ c ^ d) + X[1] + 0x6ed9eba1;
311 a = a << 3 | a >>> (32 - 3);
312 d += (a ^ b ^ c) + X[9] + 0x6ed9eba1;
313 d = d << 9 | d >>> (32 - 9);
314 c += (d ^ a ^ b) + X[5] + 0x6ed9eba1;
315 c = c << 11 | c >>> (32 - 11);
316 b += (c ^ d ^ a) + X[13] + 0x6ed9eba1;
317 b = b << 15 | b >>> (32 - 15);
318 a += (b ^ c ^ d) + X[3] + 0x6ed9eba1;
319 a = a << 3 | a >>> (32 - 3);
320 d += (a ^ b ^ c) + X[11] + 0x6ed9eba1;
321 d = d << 9 | d >>> (32 - 9);
322 c += (d ^ a ^ b) + X[7] + 0x6ed9eba1;
323 c = c << 11 | c >>> (32 - 11);
324 b += (c ^ d ^ a) + X[15] + 0x6ed9eba1;
325 b = b << 15 | b >>> (32 - 15);
326
327
328 a += aa;
329 b += bb;
330 c += cc;
331 d += dd;
332 }
333 }