View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.proxy.utils;
21  
22  import java.security.DigestException;
23  import java.security.MessageDigestSpi;
24  
25  /**
26   * MD4.java - An implementation of Ron Rivest's MD4 message digest algorithm.
27   * The MD4 algorithm is designed to be quite fast on 32-bit machines. In
28   * addition, the MD4 algorithm does not require any large substitution
29   * tables.
30   *
31   * @see The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a> Message-
32   *    Digest Algorithm by R. Rivest.
33   *
34   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
35   * @since MINA 2.0.0-M3
36   */
37  public class MD4 extends MessageDigestSpi {
38  
39      /**
40       * The MD4 algorithm message digest length is 16 bytes wide.
41       */
42      public static final int BYTE_DIGEST_LENGTH = 16;
43  
44      /**
45       * The MD4 algorithm block length is 64 bytes wide.
46       */
47      public static final int BYTE_BLOCK_LENGTH = 64;
48  
49      /**
50       * The initial values of the four registers. RFC gives the values 
51       * in LE so we converted it as JAVA uses BE endianness.
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       * The four registers initialized with the above IVs.
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       * Counts the total length of the data being digested.
74       */
75      private long msgLength;
76  
77      /**
78       * The internal buffer is {@link BLOCK_LENGTH} wide.
79       */
80      private final byte[] buffer = new byte[BYTE_BLOCK_LENGTH];
81  
82      /**
83       * Default constructor.
84       */
85      public MD4() {
86          // Do nothing
87      }
88  
89      /**
90       * Returns the digest length in bytes.
91       *
92       * @return the digest length in bytes.
93       */
94      protected int engineGetDigestLength() {
95          return BYTE_DIGEST_LENGTH;
96      }
97  
98      /**
99       * {@inheritDoc}
100      */
101     protected void engineUpdate(byte b) {
102         int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
103         buffer[pos] = b;
104         msgLength++;
105 
106         // If buffer contains enough data then process it.
107         if (pos == (BYTE_BLOCK_LENGTH - 1)) {
108             process(buffer, 0);
109         }
110     }
111 
112     /**
113      * {@inheritDoc}
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         // Process each full block
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         // Fill buffer with the remaining data
134         if (blkStart < len) {
135             System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
136         }
137     }
138 
139     /**
140      * {@inheritDoc}
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      * {@inheritDoc}
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      * {@inheritDoc}
173      */
174     protected void engineReset() {
175         a = A;
176         b = B;
177         c = C;
178         d = D;
179         msgLength = 0;
180     }
181 
182     /**
183      * Pads the buffer by appending the byte 0x80, then append as many zero 
184      * bytes as necessary to make the buffer length a multiple of 64 bytes.  
185      * The last 8 bytes will be filled with the length of the buffer in bits.
186      * If there's no room to store the length in bits in the block i.e the block 
187      * is larger than 56 bytes then an additionnal 64-bytes block is appended.
188      * 
189      * @see sections 3.1 & 3.2 of the RFC 1320.
190      * 
191      * @return the pad byte array
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         // First bit of the padding set to 1
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      * Process one 64-byte block. Algorithm is constituted by three rounds.
212      * Note that F, G and H functions were inlined for improved performance.
213      * 
214      * @param in the byte array to process
215      * @param offset the offset at which the 64-byte block is stored
216      */
217     private void process(byte[] in, int offset) {
218         // Save previous state.
219         int aa = a;
220         int bb = b;
221         int cc = c;
222         int dd = d;
223 
224         // Copy the block to process into X array
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         // Round 1
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         // Round 2
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         // Round 3
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         //Update state.
334         a += aa;
335         b += bb;
336         c += cc;
337         d += dd;
338     }
339 }