View Javadoc

1   package org.apache.mina.proxy.utils;
2   
3   import java.security.DigestException;
4   import java.security.MessageDigestSpi;
5   
6   /**
7    * MD4.java - An implementation of Ron Rivest's MD4 message digest algorithm.
8    * The MD4 algorithm is designed to be quite fast on 32-bit machines. In
9    * addition, the MD4 algorithm does not require any large substitution
10   * tables.
11   *
12   * @see The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a> Message-
13   *    Digest Algorithm by R. Rivest.
14   *
15   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
16   * @since MINA 2.0.0-M3
17   */
18  public class MD4 extends MessageDigestSpi {
19  
20      /**
21       * The MD4 algorithm message digest length is 16 bytes wide.
22       */
23      public static final int BYTE_DIGEST_LENGTH = 16;
24  
25      /**
26       * The MD4 algorithm block length is 64 bytes wide.
27       */
28      public static final int BYTE_BLOCK_LENGTH = 64;
29  
30      /**
31       * The initial values of the four registers. RFC gives the values 
32       * in LE so we converted it as JAVA uses BE endianness.
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       * The four registers initialized with the above IVs.
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       * Counts the total length of the data being digested.
55       */
56      private long msgLength;
57  
58      /**
59       * The internal buffer is {@link BLOCK_LENGTH} wide.
60       */
61      private final byte[] buffer = new byte[BYTE_BLOCK_LENGTH];
62  
63      /**
64       * Default constructor.
65       */
66      public MD4() {
67          // Do nothing
68      }
69  
70      /**
71       * Returns the digest length in bytes.
72       *
73       * @return the digest length in bytes.
74       */
75      protected int engineGetDigestLength() {
76          return BYTE_DIGEST_LENGTH;
77      }
78  
79      /**
80       * {@inheritDoc}
81       */
82      protected void engineUpdate(byte b) {
83          int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
84          buffer[pos] = b;
85          msgLength++;
86  
87          // If buffer contains enough data then process it.
88          if (pos == (BYTE_BLOCK_LENGTH - 1)) {
89              process(buffer, 0);
90          }
91      }
92  
93      /**
94       * {@inheritDoc}
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         // Process each full block
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         // Fill buffer with the remaining data
115         if (blkStart < len) {
116             System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
117         }
118     }
119 
120     /**
121      * {@inheritDoc}
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      * {@inheritDoc}
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      * {@inheritDoc}
154      */
155     protected void engineReset() {
156         a = A;
157         b = B;
158         c = C;
159         d = D;
160         msgLength = 0;
161     }
162 
163     /**
164      * Pads the buffer by appending the byte 0x80, then append as many zero 
165      * bytes as necessary to make the buffer length a multiple of 64 bytes.  
166      * The last 8 bytes will be filled with the length of the buffer in bits.
167      * If there's no room to store the length in bits in the block i.e the block 
168      * is larger than 56 bytes then an additionnal 64-bytes block is appended.
169      * 
170      * @see sections 3.1 & 3.2 of the RFC 1320.
171      * 
172      * @return the pad byte array
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         // First bit of the padding set to 1
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      * Process one 64-byte block. Algorithm is constituted by three rounds.
193      * Note that F, G and H functions were inlined for improved performance.
194      * 
195      * @param in the byte array to process
196      * @param offset the offset at which the 64-byte block is stored
197      */
198     private void process(byte[] in, int offset) {
199         // Save previous state.
200         int aa = a;
201         int bb = b;
202         int cc = c;
203         int dd = d;
204 
205         // Copy the block to process into X array
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         // Round 1
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         // Round 2
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         // Round 3
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         //Update state.
315         a += aa;
316         b += bb;
317         c += cc;
318         d += dd;
319     }
320 }