public void ProcessOutBoundPacket(IPEndPoint remoteEndPoint, ref byte[] data, ref int offset, ref int length) { int num = offset; Array.Copy(data, offset, data, offset + 5 + 16, length); offset += 21; bool flag = this.MatchesFilter(data, offset, length); PacketEncryptionLayer.EncryptionState encryptionState; bool flag2; if (!flag && this.TryGetEncryptionState(remoteEndPoint, out encryptionState, out flag2)) { object sendMutex = encryptionState.sendMutex; lock (sendMutex) { uint nextSentSequenceNum = encryptionState.GetNextSentSequenceNum(); FastBitConverter.GetBytes(data, offset + length, nextSentSequenceNum); PacketEncryptionLayer._tempHash = encryptionState.sendMac.ComputeHash(data, offset, length + 4); PacketEncryptionLayer.FastCopyMac(PacketEncryptionLayer._tempHash, 0, data, offset + length); length += 10; if (PacketEncryptionLayer._tempIV == null) { PacketEncryptionLayer._tempIV = new byte[16]; } PacketEncryptionLayer._random.GetBytes(PacketEncryptionLayer._tempIV); int num2 = (int)(PacketEncryptionLayer.GetRandomByte() % 64); int num3 = (length + num2 + 1) % 16; num2 -= num3; if (num2 < 0) { num2 += 16; } if (offset + length + num2 >= data.Length) { num2 -= 16; } for (int i = 0; i <= num2; i++) { data[offset + length + i] = (byte)num2; } length += num2 + 1; using (ICryptoTransform cryptoTransform = this._aes.CreateEncryptor(encryptionState.sendKey, PacketEncryptionLayer._tempIV)) { int num4 = num + 5 + 16; int num5; for (int j = length; j >= cryptoTransform.InputBlockSize; j -= num5) { int inputCount = cryptoTransform.CanTransformMultipleBlocks ? (j / cryptoTransform.InputBlockSize * cryptoTransform.InputBlockSize) : cryptoTransform.InputBlockSize; num5 = cryptoTransform.TransformBlock(data, offset, inputCount, data, num4); offset += num5; num4 += num5; } offset = num; length = num4 - num; } data[offset] = 1; FastBitConverter.GetBytes(data, offset + 1, nextSentSequenceNum); PacketEncryptionLayer.FastCopyBlock(PacketEncryptionLayer._tempIV, 0, data, offset + 5); } return; } if (this._filterUnencryptedTraffic && !flag) { length = 0; return; } offset--; length++; data[offset] = 0; }
private bool TryDecryptData(byte[] data, PacketEncryptionLayer.EncryptionState state, int startingOffset, ref int offset, ref int length) { object receiveMutex = state.receiveMutex; bool result; lock (receiveMutex) { uint num = BitConverter.ToUInt32(data, offset); offset += 4; length -= 4; if (!state.IsValidSequenceNum(num)) { result = false; } else { if (PacketEncryptionLayer._tempIV == null) { PacketEncryptionLayer._tempIV = new byte[16]; } if (PacketEncryptionLayer._tempHash == null) { PacketEncryptionLayer._tempHash = new byte[10]; } PacketEncryptionLayer.FastCopyBlock(data, offset, PacketEncryptionLayer._tempIV, 0); offset += PacketEncryptionLayer._tempIV.Length; length -= PacketEncryptionLayer._tempIV.Length; using (ICryptoTransform cryptoTransform = this._aes.CreateDecryptor(state.receiveKey, PacketEncryptionLayer._tempIV)) { int num2 = startingOffset; int num3; for (int i = length; i >= cryptoTransform.InputBlockSize; i -= num3) { int inputCount = cryptoTransform.CanTransformMultipleBlocks ? (i / cryptoTransform.InputBlockSize * cryptoTransform.InputBlockSize) : cryptoTransform.InputBlockSize; num3 = cryptoTransform.TransformBlock(data, offset, inputCount, data, num2); offset += num3; num2 += num3; } offset = startingOffset; length = num2 - offset; } int num4 = (int)data[offset + length - 1]; bool flag2 = true; if (num4 + 10 + 1 > length) { num4 = 0; flag2 = false; } length -= num4 + 10 + 1; PacketEncryptionLayer.FastCopyMac(data, offset + length, PacketEncryptionLayer._tempHash, 0); FastBitConverter.GetBytes(data, offset + length, num); byte[] array = state.receiveMac.ComputeHash(data, offset, length + 4); if (!flag2) { result = false; } else { for (int j = 0; j < 10; j++) { if (PacketEncryptionLayer._tempHash[j] != array[j]) { return(false); } } if (!state.PutSequenceNum(num)) { result = false; } else { result = true; } } } } return(result); }