cache: use own Xtea implmentation instead of bouncycastle's

This commit is contained in:
Adam
2017-12-15 23:10:02 -05:00
parent 0049b8d34e
commit a94ccedbf0
3 changed files with 49 additions and 89 deletions

5
cache/pom.xml vendored
View File

@@ -74,11 +74,6 @@
<artifactId>gson</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk14</artifactId>
<version>1.54</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>

View File

@@ -30,11 +30,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import net.runelite.cache.util.BZip2;
import net.runelite.cache.io.InputStream;
import net.runelite.cache.io.OutputStream;
@@ -432,16 +427,8 @@ public class DataFile implements Closeable
return data;
}
try
{
Xtea xtea = new Xtea(keys);
return xtea.decrypt(data, length);
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex)
{
logger.warn("unable to xtea decrypt", ex);
return null;
}
Xtea xtea = new Xtea(keys);
return xtea.decrypt(data, length);
}
private static byte[] encrypt(byte[] data, int length, int[] keys)
@@ -451,15 +438,7 @@ public class DataFile implements Closeable
return data;
}
try
{
Xtea xtea = new Xtea(keys);
return xtea.encrypt(data, length);
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex)
{
logger.warn("unable to xtea encrypt", ex);
return null;
}
Xtea xtea = new Xtea(keys);
return xtea.encrypt(data, length);
}
}

View File

@@ -22,81 +22,67 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.cache.util;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Xtea
{
static
{
Security.addProvider(new BouncyCastleProvider());
}
private final Cipher cipher;
private final int[] keys;
private static final int GOLDEN_RATIO = 0x9E3779B9;
public Xtea(int[] keys) throws NoSuchAlgorithmException, NoSuchPaddingException
private static final int ROUNDS = 32;
private final int[] key;
public Xtea(int[] key)
{
this.cipher = Cipher.getInstance("XTEA/ECB/NoPadding");
this.keys = keys;
this.key = key;
}
private static byte[] packKey(int[] key)
public byte[] encrypt(byte[] data, int len)
{
ByteBuffer buffer = ByteBuffer.allocate(4 * key.length);
for (int i : key)
buffer.putInt(i);
return buffer.array();
}
public byte[] encrypt(byte[] data, int len) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(packKey(keys), cipher.getAlgorithm()));
byte[] out = cipher.update(data, 0, len - (len % cipher.getBlockSize()));
cipher.doFinal();
// add remaining data, which is not encrypted
if (out.length != len)
ByteBuf buf = Unpooled.wrappedBuffer(data, 0, len);
ByteBuf out = Unpooled.buffer(len);
int numBlocks = len / 8;
for (int block = 0; block < numBlocks; ++block)
{
assert len > out.length;
byte[] padded = Arrays.copyOf(out, len);
System.arraycopy(data, out.length, padded, out.length, len - out.length);
out = padded;
int v0 = buf.readInt();
int v1 = buf.readInt();
int sum = 0;
for (int i = 0; i < ROUNDS; ++i)
{
v0 += (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + key[sum & 3]);
sum += GOLDEN_RATIO;
v1 += (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + key[(sum >>> 11) & 3]);
}
out.writeInt(v0);
out.writeInt(v1);
}
return out;
out.writeBytes(buf);
return out.array();
}
public byte[] decrypt(byte[] data, int len) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
public byte[] decrypt(byte[] data, int len)
{
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(packKey(keys), cipher.getAlgorithm()));
byte[] out = cipher.update(data, 0, len - (len % cipher.getBlockSize()));
cipher.doFinal();
if (out.length != len)
ByteBuf buf = Unpooled.wrappedBuffer(data, 0, len);
ByteBuf out = Unpooled.buffer(len);
int numBlocks = len / 8;
for (int block = 0; block < numBlocks; ++block)
{
assert len > out.length;
byte[] padded = Arrays.copyOf(out, len);
System.arraycopy(data, out.length, padded, out.length, len - out.length);
out = padded;
int v0 = buf.readInt();
int v1 = buf.readInt();
int sum = GOLDEN_RATIO * ROUNDS;
for (int i = 0; i < ROUNDS; ++i)
{
v1 -= (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + key[(sum >>> 11) & 3]);
sum -= GOLDEN_RATIO;
v0 -= (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + key[sum & 3]);
}
out.writeInt(v0);
out.writeInt(v1);
}
return out;
out.writeBytes(buf);
return out.array();
}
}