diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/AesFastEngine.cs b/MinecraftClient/Crypto/Streams/BouncyAes/AesFastEngine.cs
index a1b54456..069ba31a 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/AesFastEngine.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/AesFastEngine.cs
@@ -30,6 +30,11 @@ namespace Org.BouncyCastle.Crypto.Engines
* This file contains the fast version with 8Kbytes of static tables for round precomputation
*
*/
+ ///
+ /// Unfortunately this class has a few side channel issues.
+ /// In an environment where encryption/decryption may be closely observed it should not be used.
+ ///
+ [Obsolete("Use AesEngine instead")]
public class AesFastEngine
: IBlockCipher
{
@@ -573,12 +578,22 @@ namespace Org.BouncyCastle.Crypto.Engines
private const uint m1 = 0x80808080;
private const uint m2 = 0x7f7f7f7f;
private const uint m3 = 0x0000001b;
+ private const uint m4 = 0xC0C0C0C0;
+ private const uint m5 = 0x3f3f3f3f;
private static uint FFmulX(uint x)
{
return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3);
}
+ private static uint FFmulX2(uint x)
+ {
+ uint t0 = (x & m5) << 2;
+ uint t1 = (x & m4);
+ t1 ^= (t1 >> 1);
+ return t0 ^ (t1 >> 2) ^ (t1 >> 5);
+ }
+
/*
The following defines provide alternative definitions of FFmulX that might
give improved performance if a fast 32-bit multiply is not available.
@@ -591,12 +606,13 @@ namespace Org.BouncyCastle.Crypto.Engines
private static uint Inv_Mcol(uint x)
{
- uint f2 = FFmulX(x);
- uint f4 = FFmulX(f2);
- uint f8 = FFmulX(f4);
- uint f9 = x ^ f8;
-
- return f2 ^ f4 ^ f8 ^ Shift(f2 ^ f9, 8) ^ Shift(f4 ^ f9, 16) ^ Shift(f9, 24);
+ uint t0, t1;
+ t0 = x;
+ t1 = t0 ^ Shift(t0, 8);
+ t0 ^= FFmulX(t1);
+ t1 ^= FFmulX2(t0);
+ t0 ^= t1 ^ Shift(t1, 16);
+ return t0;
}
private static uint SubWord(uint x)
@@ -613,16 +629,14 @@ namespace Org.BouncyCastle.Crypto.Engines
* AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
* This code is written assuming those are the only possible values
*/
- private uint[][] GenerateWorkingKey(
- byte[] key,
- bool forEncryption)
+ private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
{
- int KC = key.Length / 4; // key length in words
-
- if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.Length))
+ int keyLen = key.Length;
+ if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
throw new ArgumentException("Key length not 128/192/256 bits.");
- ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
+ int KC = keyLen >> 2;
+ this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block
for (int i = 0; i <= ROUNDS; ++i)
@@ -630,32 +644,109 @@ namespace Org.BouncyCastle.Crypto.Engines
W[i] = new uint[4];
}
- //
- // copy the key into the round key array
- //
-
- int t = 0;
- for (int i = 0; i < key.Length; t++)
+ switch (KC)
{
- W[t >> 2][t & 3] = Pack.LE_To_UInt32(key, i);
- i+=4;
- }
-
- //
- // while not enough round key material calculated
- // calculate new values
- //
- int k = (ROUNDS + 1) << 2;
- for (int i = KC; (i < k); i++)
+ case 4:
{
- uint temp = W[(i-1)>>2][(i-1)&3];
- if ((i % KC) == 0) {
- temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1];
- } else if ((KC > 6) && ((i % KC) == 4)) {
- temp = SubWord(temp);
+ uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
+ uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
+ uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
+ uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
+
+ for (int i = 1; i <= 10; ++i)
+ {
+ uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1];
+ t0 ^= u; W[i][0] = t0;
+ t1 ^= t0; W[i][1] = t1;
+ t2 ^= t1; W[i][2] = t2;
+ t3 ^= t2; W[i][3] = t3;
}
- W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp;
+ break;
+ }
+ case 6:
+ {
+ uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
+ uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
+ uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
+ uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
+ uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
+ uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
+
+ uint rcon = 1;
+ uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
+ t0 ^= u; W[1][2] = t0;
+ t1 ^= t0; W[1][3] = t1;
+ t2 ^= t1; W[2][0] = t2;
+ t3 ^= t2; W[2][1] = t3;
+ t4 ^= t3; W[2][2] = t4;
+ t5 ^= t4; W[2][3] = t5;
+
+ for (int i = 3; i < 12; i += 3)
+ {
+ u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
+ t0 ^= u; W[i ][0] = t0;
+ t1 ^= t0; W[i ][1] = t1;
+ t2 ^= t1; W[i ][2] = t2;
+ t3 ^= t2; W[i ][3] = t3;
+ t4 ^= t3; W[i + 1][0] = t4;
+ t5 ^= t4; W[i + 1][1] = t5;
+ u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
+ t0 ^= u; W[i + 1][2] = t0;
+ t1 ^= t0; W[i + 1][3] = t1;
+ t2 ^= t1; W[i + 2][0] = t2;
+ t3 ^= t2; W[i + 2][1] = t3;
+ t4 ^= t3; W[i + 2][2] = t4;
+ t5 ^= t4; W[i + 2][3] = t5;
+ }
+
+ u = SubWord(Shift(t5, 8)) ^ rcon;
+ t0 ^= u; W[12][0] = t0;
+ t1 ^= t0; W[12][1] = t1;
+ t2 ^= t1; W[12][2] = t2;
+ t3 ^= t2; W[12][3] = t3;
+
+ break;
+ }
+ case 8:
+ {
+ uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
+ uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
+ uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
+ uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
+ uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
+ uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
+ uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6;
+ uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7;
+
+ uint u, rcon = 1;
+
+ for (int i = 2; i < 14; i += 2)
+ {
+ u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1;
+ t0 ^= u; W[i ][0] = t0;
+ t1 ^= t0; W[i ][1] = t1;
+ t2 ^= t1; W[i ][2] = t2;
+ t3 ^= t2; W[i ][3] = t3;
+ u = SubWord(t3);
+ t4 ^= u; W[i + 1][0] = t4;
+ t5 ^= t4; W[i + 1][1] = t5;
+ t6 ^= t5; W[i + 1][2] = t6;
+ t7 ^= t6; W[i + 1][3] = t7;
+ }
+
+ u = SubWord(Shift(t7, 8)) ^ rcon;
+ t0 ^= u; W[14][0] = t0;
+ t1 ^= t0; W[14][1] = t1;
+ t2 ^= t1; W[14][2] = t2;
+ t3 ^= t2; W[14][3] = t3;
+
+ break;
+ }
+ default:
+ {
+ throw new InvalidOperationException("Should never get here");
+ }
}
if (!forEncryption)
@@ -675,7 +766,6 @@ namespace Org.BouncyCastle.Crypto.Engines
private int ROUNDS;
private uint[][] WorkingKey;
- private uint C0, C1, C2, C3;
private bool forEncryption;
private const int BLOCK_SIZE = 16;
@@ -687,6 +777,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
}
+ internal static string GetTypeName(object obj)
+ {
+ return obj.GetType().FullName;
+ }
+
/**
* initialise an AES cipher.
*
@@ -702,7 +797,8 @@ namespace Org.BouncyCastle.Crypto.Engines
KeyParameter keyParameter = parameters as KeyParameter;
if (keyParameter == null)
- throw new ArgumentException("invalid parameter passed to AES init - " + parameters.GetType().Name);
+ throw new ArgumentException("invalid parameter passed to AES init - "
+ + GetTypeName(parameters));
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
@@ -724,11 +820,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public virtual int ProcessBlock(
- byte[] input,
- int inOff,
- byte[] output,
- int outOff)
+ public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (WorkingKey == null)
throw new InvalidOperationException("AES engine not initialised");
@@ -736,19 +828,15 @@ namespace Org.BouncyCastle.Crypto.Engines
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
- UnPackBlock(input, inOff);
-
if (forEncryption)
{
- EncryptBlock(WorkingKey);
+ EncryptBlock(input, inOff, output, outOff, WorkingKey);
}
else
{
- DecryptBlock(WorkingKey);
+ DecryptBlock(input, inOff, output, outOff, WorkingKey);
}
- PackBlock(output, outOff);
-
return BLOCK_SIZE;
}
@@ -756,34 +844,19 @@ namespace Org.BouncyCastle.Crypto.Engines
{
}
- private void UnPackBlock(
- byte[] bytes,
- int off)
+ private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
- C0 = Pack.LE_To_UInt32(bytes, off);
- C1 = Pack.LE_To_UInt32(bytes, off + 4);
- C2 = Pack.LE_To_UInt32(bytes, off + 8);
- C3 = Pack.LE_To_UInt32(bytes, off + 12);
- }
+ uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
+ uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
+ uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
+ uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
- private void PackBlock(
- byte[] bytes,
- int off)
- {
- Pack.UInt32_To_LE(C0, bytes, off);
- Pack.UInt32_To_LE(C1, bytes, off + 4);
- Pack.UInt32_To_LE(C2, bytes, off + 8);
- Pack.UInt32_To_LE(C3, bytes, off + 12);
- }
-
- private void EncryptBlock(uint[][] KW)
- {
uint[] kw = KW[0];
- uint t0 = this.C0 ^ kw[0];
- uint t1 = this.C1 ^ kw[1];
- uint t2 = this.C2 ^ kw[2];
+ uint t0 = C0 ^ kw[0];
+ uint t1 = C1 ^ kw[1];
+ uint t2 = C2 ^ kw[2];
- uint r0, r1, r2, r3 = this.C3 ^ kw[3];
+ uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = 1;
while (r < ROUNDS - 1)
{
@@ -808,20 +881,30 @@ namespace Org.BouncyCastle.Crypto.Engines
// the final round's table is a simple function of S so we don't use a whole other four tables for it
kw = KW[r];
- this.C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ kw[0];
- this.C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ kw[1];
- this.C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ kw[2];
- this.C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ kw[3];
+ C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ kw[0];
+ C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ kw[1];
+ C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ kw[2];
+ C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ kw[3];
+
+ Pack.UInt32_To_LE(C0, output, outOff + 0);
+ Pack.UInt32_To_LE(C1, output, outOff + 4);
+ Pack.UInt32_To_LE(C2, output, outOff + 8);
+ Pack.UInt32_To_LE(C3, output, outOff + 12);
}
- private void DecryptBlock(uint[][] KW)
+ private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
- uint[] kw = KW[ROUNDS];
- uint t0 = this.C0 ^ kw[0];
- uint t1 = this.C1 ^ kw[1];
- uint t2 = this.C2 ^ kw[2];
+ uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
+ uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
+ uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
+ uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
- uint r0, r1, r2, r3 = this.C3 ^ kw[3];
+ uint[] kw = KW[ROUNDS];
+ uint t0 = C0 ^ kw[0];
+ uint t1 = C1 ^ kw[1];
+ uint t2 = C2 ^ kw[2];
+
+ uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = ROUNDS - 1;
while (r > 1)
{
@@ -846,10 +929,15 @@ namespace Org.BouncyCastle.Crypto.Engines
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
kw = KW[0];
- this.C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ kw[0];
- this.C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ kw[1];
- this.C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ kw[2];
- this.C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ kw[3];
+ C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ kw[0];
+ C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ kw[1];
+ C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ kw[2];
+ C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ kw[3];
+
+ Pack.UInt32_To_LE(C0, output, outOff + 0);
+ Pack.UInt32_To_LE(C1, output, outOff + 4);
+ Pack.UInt32_To_LE(C2, output, outOff + 8);
+ Pack.UInt32_To_LE(C3, output, outOff + 12);
}
}
}
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/CfbBlockCipher.cs b/MinecraftClient/Crypto/Streams/BouncyAes/CfbBlockCipher.cs
index 43371653..ed0be407 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/CfbBlockCipher.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/CfbBlockCipher.cs
@@ -29,6 +29,9 @@ namespace Org.BouncyCastle.Crypto.Modes
IBlockCipher cipher,
int bitBlockSize)
{
+ if (bitBlockSize < 8 || (bitBlockSize & 7) != 0)
+ throw new ArgumentException("CFB" + bitBlockSize + " not supported", "bitBlockSize");
+
this.cipher = cipher;
this.blockSize = bitBlockSize / 8;
this.IV = new byte[cipher.GetBlockSize()];
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/Check.cs b/MinecraftClient/Crypto/Streams/BouncyAes/Check.cs
index 96a05c64..aacda144 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/Check.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/Check.cs
@@ -12,13 +12,13 @@ namespace Org.BouncyCastle.Crypto
internal static void DataLength(byte[] buf, int off, int len, string msg)
{
- if (off + len > buf.Length)
+ if (off > (buf.Length - len))
throw new DataLengthException(msg);
}
internal static void OutputLength(byte[] buf, int off, int len, string msg)
{
- if (off + len > buf.Length)
+ if (off > (buf.Length - len))
throw new OutputLengthException(msg);
}
}
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/CipherStream.cs b/MinecraftClient/Crypto/Streams/BouncyAes/CipherStream.cs
index b6920854..058d7f73 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/CipherStream.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/CipherStream.cs
@@ -2,8 +2,6 @@ using System;
using System.Diagnostics;
using System.IO;
-using Org.BouncyCastle.Crypto;
-
namespace Org.BouncyCastle.Crypto.IO
{
public class CipherStream
@@ -201,7 +199,23 @@ namespace Org.BouncyCastle.Crypto.IO
set { throw new NotSupportedException(); }
}
- public override void Close()
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (outCipher != null)
+ {
+ byte[] data = outCipher.DoFinal();
+ stream.Write(data, 0, data.Length);
+ stream.Flush();
+ }
+ Platform.Dispose(stream);
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
{
if (outCipher != null)
{
@@ -210,9 +224,11 @@ namespace Org.BouncyCastle.Crypto.IO
stream.Flush();
}
stream.Close();
+ base.Close();
}
+#endif
- public override void Flush()
+ public override void Flush()
{
// Note: outCipher.DoFinal is only called during Close()
stream.Flush();
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/CryptoException.cs b/MinecraftClient/Crypto/Streams/BouncyAes/CryptoException.cs
index 67f0d86f..73d450be 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/CryptoException.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/CryptoException.cs
@@ -2,7 +2,7 @@ using System;
namespace Org.BouncyCastle.Crypto
{
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class CryptoException
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/DataLengthException.cs b/MinecraftClient/Crypto/Streams/BouncyAes/DataLengthException.cs
index e9efc0bd..447ff2a1 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/DataLengthException.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/DataLengthException.cs
@@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto
* insufficient input. In general this exception will Get thrown rather
* than an ArrayOutOfBounds exception.
*/
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class DataLengthException
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/KeyParameter.cs b/MinecraftClient/Crypto/Streams/BouncyAes/KeyParameter.cs
index 33dff96d..043adf27 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/KeyParameter.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/KeyParameter.cs
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
throw new ArgumentNullException("key");
if (keyOff < 0 || keyOff > key.Length)
throw new ArgumentOutOfRangeException("keyOff");
- if (keyLen < 0 || (keyOff + keyLen) > key.Length)
+ if (keyLen < 0 || keyLen > (key.Length - keyOff))
throw new ArgumentOutOfRangeException("keyLen");
this.key = new byte[keyLen];
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/OutputLengthException.cs b/MinecraftClient/Crypto/Streams/BouncyAes/OutputLengthException.cs
index e1cf4492..437589f4 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/OutputLengthException.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/OutputLengthException.cs
@@ -2,7 +2,7 @@
namespace Org.BouncyCastle.Crypto
{
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class OutputLengthException
diff --git a/MinecraftClient/Crypto/Streams/BouncyAes/Pack.cs b/MinecraftClient/Crypto/Streams/BouncyAes/Pack.cs
index 087cb7ce..8ba738d4 100644
--- a/MinecraftClient/Crypto/Streams/BouncyAes/Pack.cs
+++ b/MinecraftClient/Crypto/Streams/BouncyAes/Pack.cs
@@ -20,11 +20,41 @@ namespace Org.BouncyCastle.Crypto.Utilities
bs[off + 1] = (byte)(n);
}
- internal static ushort BE_To_UInt16(byte[] bs)
+ internal static void UInt16_To_BE(ushort[] ns, byte[] bs, int off)
{
- uint n = (uint)bs[0] << 8
- | (uint)bs[1];
- return (ushort)n;
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ UInt16_To_BE(ns[i], bs, off);
+ off += 2;
+ }
+ }
+
+ internal static void UInt16_To_BE(ushort[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ UInt16_To_BE(ns[nsOff + i], bs, bsOff);
+ bsOff += 2;
+ }
+ }
+
+ internal static byte[] UInt16_To_BE(ushort n)
+ {
+ byte[] bs = new byte[2];
+ UInt16_To_BE(n, bs, 0);
+ return bs;
+ }
+
+ internal static byte[] UInt16_To_BE(ushort[] ns)
+ {
+ return UInt16_To_BE(ns, 0, ns.Length);
+ }
+
+ internal static byte[] UInt16_To_BE(ushort[] ns, int nsOff, int nsLen)
+ {
+ byte[] bs = new byte[2 * nsLen];
+ UInt16_To_BE(ns, nsOff, nsLen, bs, 0);
+ return bs;
}
internal static ushort BE_To_UInt16(byte[] bs, int off)
@@ -34,11 +64,27 @@ namespace Org.BouncyCastle.Crypto.Utilities
return (ushort)n;
}
- internal static byte[] UInt32_To_BE(uint n)
+ internal static void BE_To_UInt16(byte[] bs, int bsOff, ushort[] ns, int nsOff)
{
- byte[] bs = new byte[4];
- UInt32_To_BE(n, bs, 0);
- return bs;
+ ns[nsOff] = BE_To_UInt16(bs, bsOff);
+ }
+
+ internal static ushort[] BE_To_UInt16(byte[] bs)
+ {
+ return BE_To_UInt16(bs, 0, bs.Length);
+ }
+
+ internal static ushort[] BE_To_UInt16(byte[] bs, int off, int len)
+ {
+ if ((len & 1) != 0)
+ throw new ArgumentException("must be a multiple of 2", "len");
+
+ ushort[] ns = new ushort[len / 2];
+ for (int i = 0; i < len; i += 2)
+ {
+ BE_To_UInt16(bs, off + i, ns, i >> 1);
+ }
+ return ns;
}
internal static void UInt32_To_BE(uint n, byte[] bs)
@@ -57,13 +103,6 @@ namespace Org.BouncyCastle.Crypto.Utilities
bs[off + 3] = (byte)(n);
}
- internal static byte[] UInt32_To_BE(uint[] ns)
- {
- byte[] bs = new byte[4 * ns.Length];
- UInt32_To_BE(ns, bs, 0);
- return bs;
- }
-
internal static void UInt32_To_BE(uint[] ns, byte[] bs, int off)
{
for (int i = 0; i < ns.Length; ++i)
@@ -73,6 +112,29 @@ namespace Org.BouncyCastle.Crypto.Utilities
}
}
+ internal static void UInt32_To_BE(uint[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ UInt32_To_BE(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
+ internal static byte[] UInt32_To_BE(uint n)
+ {
+ byte[] bs = new byte[4];
+ UInt32_To_BE(n, bs, 0);
+ return bs;
+ }
+
+ internal static byte[] UInt32_To_BE(uint[] ns)
+ {
+ byte[] bs = new byte[4 * ns.Length];
+ UInt32_To_BE(ns, bs, 0);
+ return bs;
+ }
+
internal static uint BE_To_UInt32(byte[] bs)
{
return (uint)bs[0] << 24
@@ -98,6 +160,15 @@ namespace Org.BouncyCastle.Crypto.Utilities
}
}
+ internal static void BE_To_UInt32(byte[] bs, int bsOff, uint[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = BE_To_UInt32(bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
internal static byte[] UInt64_To_BE(ulong n)
{
byte[] bs = new byte[8];
@@ -117,11 +188,29 @@ namespace Org.BouncyCastle.Crypto.Utilities
UInt32_To_BE((uint)(n), bs, off + 4);
}
- internal static ulong BE_To_UInt64(byte[] bs)
+ internal static byte[] UInt64_To_BE(ulong[] ns)
{
- uint hi = BE_To_UInt32(bs);
- uint lo = BE_To_UInt32(bs, 4);
- return ((ulong)hi << 32) | (ulong)lo;
+ byte[] bs = new byte[8 * ns.Length];
+ UInt64_To_BE(ns, bs, 0);
+ return bs;
+ }
+
+ internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ UInt64_To_BE(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
+ internal static void UInt64_To_BE(ulong[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ UInt64_To_BE(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
}
internal static ulong BE_To_UInt64(byte[] bs, int off)
@@ -131,6 +220,24 @@ namespace Org.BouncyCastle.Crypto.Utilities
return ((ulong)hi << 32) | (ulong)lo;
}
+ internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ ns[i] = BE_To_UInt64(bs, off);
+ off += 8;
+ }
+ }
+
+ internal static void BE_To_UInt64(byte[] bs, int bsOff, ulong[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = BE_To_UInt64(bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
internal static void UInt16_To_LE(ushort n, byte[] bs)
{
bs[0] = (byte)(n);
@@ -196,6 +303,15 @@ namespace Org.BouncyCastle.Crypto.Utilities
}
}
+ internal static void UInt32_To_LE(uint[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ UInt32_To_LE(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
internal static uint LE_To_UInt32(byte[] bs)
{
return (uint)bs[0]
@@ -230,6 +346,17 @@ namespace Org.BouncyCastle.Crypto.Utilities
}
}
+ internal static uint[] LE_To_UInt32(byte[] bs, int off, int count)
+ {
+ uint[] ns = new uint[count];
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ ns[i] = LE_To_UInt32(bs, off);
+ off += 4;
+ }
+ return ns;
+ }
+
internal static byte[] UInt64_To_LE(ulong n)
{
byte[] bs = new byte[8];
@@ -249,6 +376,31 @@ namespace Org.BouncyCastle.Crypto.Utilities
UInt32_To_LE((uint)(n >> 32), bs, off + 4);
}
+ internal static byte[] UInt64_To_LE(ulong[] ns)
+ {
+ byte[] bs = new byte[8 * ns.Length];
+ UInt64_To_LE(ns, bs, 0);
+ return bs;
+ }
+
+ internal static void UInt64_To_LE(ulong[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ UInt64_To_LE(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
+ internal static void UInt64_To_LE(ulong[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ UInt64_To_LE(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
internal static ulong LE_To_UInt64(byte[] bs)
{
uint lo = LE_To_UInt32(bs);
@@ -262,5 +414,23 @@ namespace Org.BouncyCastle.Crypto.Utilities
uint hi = LE_To_UInt32(bs, off + 4);
return ((ulong)hi << 32) | (ulong)lo;
}
+
+ internal static void LE_To_UInt64(byte[] bs, int off, ulong[] ns)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ ns[i] = LE_To_UInt64(bs, off);
+ off += 8;
+ }
+ }
+
+ internal static void LE_To_UInt64(byte[] bs, int bsOff, ulong[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = LE_To_UInt64(bs, bsOff);
+ bsOff += 8;
+ }
+ }
}
}