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