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
127 - 1 < len; blkStart += BYTE_BLOCK_LENGTH) {
128 process(b, offset + blkStart);
129 }
130 pos = 0;
131 }
132
133
134 if (blkStart < len) {
135 System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
136 }
137 }
138
139
140
141
142 protected byte[] engineDigest() {
143 byte[] p = pad();
144 engineUpdate(p, 0, p.length);
145 byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16),
146 (byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
147 (byte) (b >>> 16), (byte) (b >>> 24), (byte) c,
148 (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
149 (byte) d, (byte) (d >>> 8), (byte) (d >>> 16),
150 (byte) (d >>> 24) };
151
152 engineReset();
153
154 return digest;
155 }
156
157
158
159
160 protected int engineDigest(byte[] buf, int offset, int len)
161 throws DigestException {
162 if (offset < 0 || offset + len >= buf.length) {
163 throw new DigestException(
164 "Wrong offset or not enough space to store the digest");
165 }
166 int destLength = Math.min(len, BYTE_DIGEST_LENGTH);
167 System.arraycopy(engineDigest(), 0, buf, offset, destLength);
168 return destLength;
169 }
170
171
172
173
174 protected void engineReset() {
175 a = A;
176 b = B;
177 c = C;
178 d = D;
179 msgLength = 0;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 private byte[] pad() {
194 int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
195 int padLength = (pos < 56) ? (64 - pos) : (128 - pos);
196 byte[] pad = new byte[padLength];
197
198
199 pad[0] = (byte) 0x80;
200
201 long bits = msgLength << 3;
202 int index = padLength - 8;
203 for (int i = 0; i < 8; i++) {
204 pad[index++] = (byte) (bits >>> (i << 3));
205 }
206
207 return pad;
208 }
209
210
211
212
213
214
215
216
217 private void process(byte[] in, int offset) {
218
219 int aa = a;
220 int bb = b;
221 int cc = c;
222 int dd = d;
223
224
225 int[] X = new int[16];
226 for (int i = 0; i < 16; i++) {
227 X[i] = (in[offset++] & 0xff) | (in[offset++] & 0xff) << 8
228 | (in[offset++] & 0xff) << 16 | (in[offset++] & 0xff) << 24;
229 }
230
231
232 a += ((b & c) | (~b & d)) + X[0];
233 a = a << 3 | a >>> (32 - 3);
234 d += ((a & b) | (~a & c)) + X[1];
235 d = d << 7 | d >>> (32 - 7);
236 c += ((d & a) | (~d & b)) + X[2];
237 c = c << 11 | c >>> (32 - 11);
238 b += ((c & d) | (~c & a)) + X[3];
239 b = b << 19 | b >>> (32 - 19);
240 a += ((b & c) | (~b & d)) + X[4];
241 a = a << 3 | a >>> (32 - 3);
242 d += ((a & b) | (~a & c)) + X[5];
243 d = d << 7 | d >>> (32 - 7);
244 c += ((d & a) | (~d & b)) + X[6];
245 c = c << 11 | c >>> (32 - 11);
246 b += ((c & d) | (~c & a)) + X[7];
247 b = b << 19 | b >>> (32 - 19);
248 a += ((b & c) | (~b & d)) + X[8];
249 a = a << 3 | a >>> (32 - 3);
250 d += ((a & b) | (~a & c)) + X[9];
251 d = d << 7 | d >>> (32 - 7);
252 c += ((d & a) | (~d & b)) + X[10];
253 c = c << 11 | c >>> (32 - 11);
254 b += ((c & d) | (~c & a)) + X[11];
255 b = b << 19 | b >>> (32 - 19);
256 a += ((b & c) | (~b & d)) + X[12];
257 a = a << 3 | a >>> (32 - 3);
258 d += ((a & b) | (~a & c)) + X[13];
259 d = d << 7 | d >>> (32 - 7);
260 c += ((d & a) | (~d & b)) + X[14];
261 c = c << 11 | c >>> (32 - 11);
262 b += ((c & d) | (~c & a)) + X[15];
263 b = b << 19 | b >>> (32 - 19);
264
265
266 a += ((b & (c | d)) | (c & d)) + X[0] + 0x5a827999;
267 a = a << 3 | a >>> (32 - 3);
268 d += ((a & (b | c)) | (b & c)) + X[4] + 0x5a827999;
269 d = d << 5 | d >>> (32 - 5);
270 c += ((d & (a | b)) | (a & b)) + X[8] + 0x5a827999;
271 c = c << 9 | c >>> (32 - 9);
272 b += ((c & (d | a)) | (d & a)) + X[12] + 0x5a827999;
273 b = b << 13 | b >>> (32 - 13);
274 a += ((b & (c | d)) | (c & d)) + X[1] + 0x5a827999;
275 a = a << 3 | a >>> (32 - 3);
276 d += ((a & (b | c)) | (b & c)) + X[5] + 0x5a827999;
277 d = d << 5 | d >>> (32 - 5);
278 c += ((d & (a | b)) | (a & b)) + X[9] + 0x5a827999;
279 c = c << 9 | c >>> (32 - 9);
280 b += ((c & (d | a)) | (d & a)) + X[13] + 0x5a827999;
281 b = b << 13 | b >>> (32 - 13);
282 a += ((b & (c | d)) | (c & d)) + X[2] + 0x5a827999;
283 a = a << 3 | a >>> (32 - 3);
284 d += ((a & (b | c)) | (b & c)) + X[6] + 0x5a827999;
285 d = d << 5 | d >>> (32 - 5);
286 c += ((d & (a | b)) | (a & b)) + X[10] + 0x5a827999;
287 c = c << 9 | c >>> (32 - 9);
288 b += ((c & (d | a)) | (d & a)) + X[14] + 0x5a827999;
289 b = b << 13 | b >>> (32 - 13);
290 a += ((b & (c | d)) | (c & d)) + X[3] + 0x5a827999;
291 a = a << 3 | a >>> (32 - 3);
292 d += ((a & (b | c)) | (b & c)) + X[7] + 0x5a827999;
293 d = d << 5 | d >>> (32 - 5);
294 c += ((d & (a | b)) | (a & b)) + X[11] + 0x5a827999;
295 c = c << 9 | c >>> (32 - 9);
296 b += ((c & (d | a)) | (d & a)) + X[15] + 0x5a827999;
297 b = b << 13 | b >>> (32 - 13);
298
299
300 a += (b ^ c ^ d) + X[0] + 0x6ed9eba1;
301 a = a << 3 | a >>> (32 - 3);
302 d += (a ^ b ^ c) + X[8] + 0x6ed9eba1;
303 d = d << 9 | d >>> (32 - 9);
304 c += (d ^ a ^ b) + X[4] + 0x6ed9eba1;
305 c = c << 11 | c >>> (32 - 11);
306 b += (c ^ d ^ a) + X[12] + 0x6ed9eba1;
307 b = b << 15 | b >>> (32 - 15);
308 a += (b ^ c ^ d) + X[2] + 0x6ed9eba1;
309 a = a << 3 | a >>> (32 - 3);
310 d += (a ^ b ^ c) + X[10] + 0x6ed9eba1;
311 d = d << 9 | d >>> (32 - 9);
312 c += (d ^ a ^ b) + X[6] + 0x6ed9eba1;
313 c = c << 11 | c >>> (32 - 11);
314 b += (c ^ d ^ a) + X[14] + 0x6ed9eba1;
315 b = b << 15 | b >>> (32 - 15);
316 a += (b ^ c ^ d) + X[1] + 0x6ed9eba1;
317 a = a << 3 | a >>> (32 - 3);
318 d += (a ^ b ^ c) + X[9] + 0x6ed9eba1;
319 d = d << 9 | d >>> (32 - 9);
320 c += (d ^ a ^ b) + X[5] + 0x6ed9eba1;
321 c = c << 11 | c >>> (32 - 11);
322 b += (c ^ d ^ a) + X[13] + 0x6ed9eba1;
323 b = b << 15 | b >>> (32 - 15);
324 a += (b ^ c ^ d) + X[3] + 0x6ed9eba1;
325 a = a << 3 | a >>> (32 - 3);
326 d += (a ^ b ^ c) + X[11] + 0x6ed9eba1;
327 d = d << 9 | d >>> (32 - 9);
328 c += (d ^ a ^ b) + X[7] + 0x6ed9eba1;
329 c = c << 11 | c >>> (32 - 11);
330 b += (c ^ d ^ a) + X[15] + 0x6ed9eba1;
331 b = b << 15 | b >>> (32 - 15);
332
333
334 a += aa;
335 b += bb;
336 c += cc;
337 d += dd;
338 }
339 }