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 - 1 < len; blkStart += BYTE_BLOCK_LENGTH) {
127                 process(b, offset + blkStart);
128             }
129             pos = 0;
130         }
131 
132         // Fill buffer with the remaining data
133         if (blkStart < len) {
134             System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
135         }
136     }
137 
138     /**
139      * {@inheritDoc}
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      * {@inheritDoc}
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      * {@inheritDoc}
167      */
168     protected void engineReset() {
169         a = A;
170         b = B;
171         c = C;
172         d = D;
173         msgLength = 0;
174     }
175 
176     /**
177      * Pads the buffer by appending the byte 0x80, then append as many zero 
178      * bytes as necessary to make the buffer length a multiple of 64 bytes.  
179      * The last 8 bytes will be filled with the length of the buffer in bits.
180      * If there's no room to store the length in bits in the block i.e the block 
181      * is larger than 56 bytes then an additionnal 64-bytes block is appended.
182      * 
183      * @see sections 3.1 & 3.2 of the RFC 1320.
184      * 
185      * @return the pad byte array
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         // First bit of the padding set to 1
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      * Process one 64-byte block. Algorithm is constituted by three rounds.
206      * Note that F, G and H functions were inlined for improved performance.
207      * 
208      * @param in the byte array to process
209      * @param offset the offset at which the 64-byte block is stored
210      */
211     private void process(byte[] in, int offset) {
212         // Save previous state.
213         int aa = a;
214         int bb = b;
215         int cc = c;
216         int dd = d;
217 
218         // Copy the block to process into X array
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         // Round 1
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         // Round 2
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         // Round 3
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         //Update state.
328         a += aa;
329         b += bb;
330         c += cc;
331         d += dd;
332     }
333 }