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() >= 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