1 /********************************************************************************
2  *
3  * jMule - a Java massive parallel file sharing client
4  *
5  * Copyright (C) by the jMuleGroup ( see the CREDITS file )
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details ( see the LICENSE file ).
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc.,  59 Temple Plac(int)e, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * $Id: BrokenMd5Hasher.java,v 1.1 2005-11-16 13:36:23 parg Exp $
22  *
23  ********************************************************************************/
24 
25 package org.gudy.azureus2.core3.util;
26 
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 
30 /**
31  * Use this class for getting a MD5 message digest.
32  * Create a MD5 and reuse it after a message digest calculation. There can be as
33  * many MD5 objects as you want to have multiple calculations same time.
34  * The message can be passed in one or a sequenze of parts wrapped in a
35  * ByteBuffer to the update of the same MD5 instance. To finish the calculation
36  * use final, it will reset the MD5 instance for a new calculation.
37  *
38  * @author emarant
39  * @version $Revision: 1.1 $
40  * <br>Last changed by $Author: parg $ on $Date: 2005-11-16 13:36:23 $
41  */
42 public final class BrokenMd5Hasher {
43 
44     private ByteBuffer buffer = ByteBuffer.allocate(64).order(ByteOrder.LITTLE_ENDIAN);
45     private int stateA = 0x67452301;
46     private int stateB = 0xEFCDAB89;
47     private int stateC = 0x98BADCFE;
48     private int stateD = 0x10325476;
49     private long count = 0;
50 
51     /**
52     * Constructor returns a MD6 ready for use.
53     */
BrokenMd5Hasher()54     public BrokenMd5Hasher(){
55     }
56 
57     public byte[]
calculateHash( byte[] data )58     calculateHash(
59     	byte[]		data )
60     {
61     	ByteBuffer input_buffer = ByteBuffer.wrap(data);
62 
63     	reset();
64 
65     	update(input_buffer);
66 
67     	ByteBuffer result_buffer = ByteBuffer.allocate(16);
68 
69     	finalDigest(result_buffer);
70 
71     	byte[] result = new byte[16];
72 
73     	result_buffer.position(0);
74 
75     	for(int i = 0 ; i < result.length ; i++) {
76 
77     		result[i] = result_buffer.get();
78     	}
79 
80     	return result;
81     }
82 
83     /**
84     * Resets the MD5 to initial state for a new message digest calculation.
85     */
reset()86     public void reset(){
87         stateA = 0x67452301;
88         stateB = 0xEFCDAB89;
89         stateC = 0x98BADCFE;
90         stateD = 0x10325476;
91         count = 0;
92         buffer.rewind();
93         for(int i=0;i<64;i++){
94             buffer.put((byte)0);
95         }
96         buffer.rewind();
97     }
98 
99     /**
100     * Starts or continues a MD5 message digest calculation.
101     * input.remaining() should be a multiple of 64 to be most efficant, but
102     * other amounts work too. Only remaining bytes of the ByteBuffer are used
103     * and input.position() will be input.limit() after return.
104     * @param input hold a part of the message. input.order() have to be ByteOrder.LITTLE_ENDIAN
105     */
update(ByteBuffer input)106     public void update(ByteBuffer input){
107         int index, partLen, i, inputLen;
108         inputLen = input.remaining();
109         index = ((int)count) & 63;
110         count += inputLen;
111         partLen = 64 - index;
112         i = 0;
113         if (inputLen >= partLen){
114             if (index>0){
115                 int t = input.limit();
116                 input.limit(input.position()+partLen);
117                 buffer.put(input);
118                 buffer.rewind();
119                 input.limit(t);
120                 transform(buffer);
121                 buffer.rewind();
122                 i = partLen;
123                 index = partLen;
124             }
125 
126             while(i + 63 < inputLen){
127                 transform(input);
128                 i += 64;
129             }
130         }
131         if (i<inputLen){
132             buffer.put(input);
133         }
134     }
135 
136     public void
update( byte[] data )137     update(
138     	byte[]		data )
139     {
140     	update( ByteBuffer.wrap( data ));
141     }
142 
143     public byte[]
getDigest()144     getDigest()
145     {
146     	ByteBuffer result_buffer = ByteBuffer.allocate(16);
147 
148     	finalDigest(result_buffer);
149 
150     	byte[] result = new byte[16];
151 
152     	result_buffer.position(0);
153 
154     	for(int i = 0 ; i < result.length ; i++) {
155 
156     		result[i] = result_buffer.get();
157     	}
158 
159     	return result;
160     }
161 
162     /**
163     * Finishs a MD5 message digest calculation.
164     * The result is stored in digest and the MD5-object is <b>reset</b> and so
165     * ready for a new message digest calculation.
166     *
167     * @param digest should be a ByteBuffer with digest.remaining() &gt;= 16
168     *
169     */
finalDigest(ByteBuffer digest)170     public void finalDigest(ByteBuffer digest){
171         int index;
172 
173         index = ((int)count) & 63;
174         if (index < 56){
175             buffer.put((byte)0x80);
176             for(int i = index ; i < 55 ;i++)
177                 buffer.put((byte)0);
178             buffer.putLong(count << 3);
179             buffer.rewind();
180             transform(buffer);
181             buffer.rewind();
182         }else{
183             buffer.put((byte)0x80);
184             for(int i = index ; i < 63 ; i++)
185                 buffer.put((byte)0);
186             buffer.rewind();
187             transform(buffer);
188             buffer.rewind();
189             for(int i=0;i<56;i++)
190                 buffer.put((byte)0);
191             buffer.putLong(count << 3);
192             buffer.rewind();
193             transform(buffer);
194             buffer.rewind();
195         }
196         // save the result in digest
197         digest.putInt(stateA);
198         digest.putInt(stateB);
199         digest.putInt(stateC);
200         digest.putInt(stateD);
201 
202         reset();
203     }
204 
transform(ByteBuffer block)205     private void transform(ByteBuffer block) {
206         int a, b, c, d;
207         long e, f, g, h, i, j, k, l;
208 
209         a = stateA;
210         b = stateB;
211         c = stateC;
212         d = stateD;
213         e = block.getLong();// 0   1
214         f = block.getLong();// 2   3
215         g = block.getLong();// 4   5
216         h = block.getLong();// 6   7
217         i = block.getLong();// 8   9
218         j = block.getLong();//10  11
219         k = block.getLong();//12  13
220         l = block.getLong();//14  15
221 
222         a = FF(a, b, c, d, (int)e,  7, 0xd76aa478);
223         d = FF(d, a, b, c, (int)(e >>> 32), 12, 0xe8c7b756);
224         c = FF(c, d, a, b, (int)f, 17, 0x242070db);
225         b = FF(b, c, d, a, (int)(f >>> 32), 22, 0xc1bdceee);
226         a = FF(a, b, c, d, (int)g,  7, 0xf57c0faf);
227         d = FF(d, a, b, c, (int)(g >>> 32), 12, 0x4787c62a);
228         c = FF(c, d, a, b, (int)h, 17, 0xa8304613);
229         b = FF(b, c, d, a, (int)(h >>> 32), 22, 0xfd469501);
230         a = FF(a, b, c, d, (int)i,  7, 0x698098d8);
231         d = FF(d, a, b, c, (int)(i >>> 32), 12, 0x8b44f7af);
232         c = FF(c, d, a, b, (int)j, 17, 0xffff5bb1);
233         b = FF(b, c, d, a, (int)(j >>> 32), 22, 0x895cd7be);
234         a = FF(a, b, c, d, (int)k,  7, 0x6b901122);
235         d = FF(d, a, b, c, (int)(k >>> 32), 12, 0xfd987193);
236         c = FF(c, d, a, b, (int)l, 17, 0xa679438e);
237         b = FF(b, c, d, a, (int)(l >>> 32), 22, 0x49b40821);
238 
239         a = GG(a, b, c, d, (int)(e >>>32),  5, 0xf61e2562);
240         d = GG(d, a, b, c, (int)h,  9, 0xc040b340);
241         c = GG(c, d, a, b, (int)(j >>> 32), 14, 0x265e5a51);
242         b = GG(b, c, d, a, (int)e, 20, 0xe9b6c7aa);
243         a = GG(a, b, c, d, (int)(g >>> 32),  5, 0xd62f105d);
244         d = GG(d, a, b, c, (int)j,  9, 0x02441453);
245         c = GG(c, d, a, b, (int)(l >>> 32), 14, 0xd8a1e681);
246         b = GG(b, c, d, a, (int)g, 20, 0xe7d3fbc8);
247         a = GG(a, b, c, d, (int)(i >>> 32),  5, 0x21e1cde6);
248         d = GG(d, a, b, c, (int)l,  9, 0xc33707d6);
249         c = GG(c, d, a, b, (int)(f >>> 32), 14, 0xf4d50d87);
250         b = GG(b, c, d, a, (int)i, 20, 0x455a14ed);
251         a = GG(a, b, c, d, (int)(k >>> 32),  5, 0xa9e3e905);
252         d = GG(d, a, b, c, (int)f,  9, 0xfcefa3f8);
253         c = GG(c, d, a, b, (int)(h >>> 32), 14, 0x676f02d9);
254         b = GG(b, c, d, a, (int)k, 20, 0x8d2a4c8a);
255 
256         a = HH(a, b, c, d, (int)(g >>> 32),  4, 0xfffa3942);
257         d = HH(d, a, b, c, (int)i, 11, 0x8771f681);
258         c = HH(c, d, a, b, (int)(j >>> 32), 16, 0x6d9d6122);
259         b = HH(b, c, d, a, (int)l, 23, 0xfde5380c);
260         a = HH(a, b, c, d, (int)(e >>>32),  4, 0xa4beea44);
261         d = HH(d, a, b, c, (int)g, 11, 0x4bdecfa9);
262         c = HH(c, d, a, b, (int)(h >>> 32), 16, 0xf6bb4b60);
263         b = HH(b, c, d, a, (int)j, 23, 0xbebfbc70);
264         a = HH(a, b, c, d, (int)(k >>> 32),  4, 0x289b7ec6);
265         d = HH(d, a, b, c, (int)e, 11, 0xeaa127fa);
266         c = HH(c, d, a, b, (int)(f >>> 32), 16, 0xd4ef3085);
267         b = HH(b, c, d, a, (int)h, 23, 0x04881d05);
268         a = HH(a, b, c, d, (int)(i >>> 32),  4, 0xd9d4d039);
269         d = HH(d, a, b, c, (int)k, 11, 0xe6db99e5);
270         c = HH(c, d, a, b, (int)(l >>> 32), 16, 0x1fa27cf8);
271         b = HH(b, c, d, a, (int)f, 23, 0xc4ac5665);
272 
273         a = II(a, b, c, d, (int)e,  6, 0xf4292244);
274         d = II(d, a, b, c, (int)(h >>> 32), 10, 0x432aff97);
275         c = II(c, d, a, b, (int)l, 15, 0xab9423a7);
276         b = II(b, c, d, a, (int)(g >>> 32), 21, 0xfc93a039);
277         a = II(a, b, c, d, (int)k,  6, 0x655b59c3);
278         d = II(d, a, b, c, (int)(f >>> 32), 10, 0x8f0ccc92);
279         c = II(c, d, a, b, (int)j, 15, 0xffeff47d);
280         b = II(b, c, d, a, (int)(e >>>32), 21, 0x85845dd1);
281         a = II(a, b, c, d, (int)i,  6, 0x6fa87e4f);
282         d = II(d, a, b, c, (int)(l >>> 32), 10, 0xfe2ce6e0);
283         c = II(c, d, a, b, (int)h, 15, 0xa3014314);
284         b = II(b, c, d, a, (int)(k >>> 32), 21, 0x4e0811a1);
285         a = II(a, b, c, d, (int)g,  6, 0xf7537e82);
286         d = II(d, a, b, c, (int)(j >>> 32), 10, 0xbd3af235);
287         c = II(c, d, a, b, (int)f, 15, 0x2ad7d2bb);
288         b = II(b, c, d, a, (int)(i >>> 32), 21, 0xeb86d391);
289 
290         stateA += a;
291         stateB += b;
292         stateC += c;
293         stateD += d;
294     }
295 
FF(int a, int b, int c, int d, int x, int s, int t)296     private static int FF(int a, int b, int c, int d, int x, int s, int t) {
297         int r = a + x + t + (d ^ (b & (c ^ d)));
298         return (r << s | r >>> (32 - s)) + b;
299     }
300 
GG(int a, int b, int c, int d, int x, int s, int t)301     private static int GG(int a, int b, int c, int d, int x, int s, int t) {
302         int r = a + x + t + (c ^ (d & (b ^ c)));
303         return (r << s | r >>> (32 - s)) + b;
304     }
305 
HH(int a, int b, int c, int d, int x, int s, int t)306     private static int HH(int a, int b, int c, int d, int x, int s, int t) {
307         int r = a + x + t + (b ^ c ^ d);
308         return (r << s | r >>> (32 - s)) + b;
309     }
310 
II(int a, int b, int c, int d, int x, int s, int t)311     private static int II(int a, int b, int c, int d, int x, int s, int t) {
312         int r = a + x + t + (c ^ (b | ~d));
313         return (r << s | r >>> (32 - s)) + b;
314     }
315 }
316 
317