move to github
This commit is contained in:
26
Lidgren.Network/Encryption/NetAESEncryption.cs
Normal file
26
Lidgren.Network/Encryption/NetAESEncryption.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
public class NetAESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
public NetAESEncryption(NetPeer peer)
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
}
|
||||
|
||||
public NetAESEncryption(NetPeer peer, string key)
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Lidgren.Network/Encryption/NetBlockEncryptionBase.cs
Normal file
89
Lidgren.Network/Encryption/NetBlockEncryptionBase.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Base for a non-threadsafe encryption class
|
||||
/// </summary>
|
||||
public abstract class NetBlockEncryptionBase : NetEncryption
|
||||
{
|
||||
// temporary space for one block to avoid reallocating every time
|
||||
private byte[] m_tmp;
|
||||
|
||||
/// <summary>
|
||||
/// Block size in bytes for this cipher
|
||||
/// </summary>
|
||||
public abstract int BlockSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// NetBlockEncryptionBase constructor
|
||||
/// </summary>
|
||||
public NetBlockEncryptionBase(NetPeer peer)
|
||||
: base(peer)
|
||||
{
|
||||
m_tmp = new byte[BlockSize];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt am outgoing message with this algorithm; no writing can be done to the message after encryption, or message will be corrupted
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
{
|
||||
int payloadBitLength = msg.LengthBits;
|
||||
int numBytes = msg.LengthBytes;
|
||||
int blockSize = BlockSize;
|
||||
int numBlocks = (int)Math.Ceiling((double)numBytes / (double)blockSize);
|
||||
int dstSize = numBlocks * blockSize;
|
||||
|
||||
msg.EnsureBufferSize(dstSize * 8 + (4 * 8)); // add 4 bytes for payload length at end
|
||||
msg.LengthBits = dstSize * 8; // length will automatically adjust +4 bytes when payload length is written
|
||||
|
||||
for(int i=0;i<numBlocks;i++)
|
||||
{
|
||||
EncryptBlock(msg.m_data, (i * blockSize), m_tmp);
|
||||
Buffer.BlockCopy(m_tmp, 0, msg.m_data, (i * blockSize), m_tmp.Length);
|
||||
}
|
||||
|
||||
// add true payload length last
|
||||
msg.Write((UInt32)payloadBitLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt an incoming message encrypted with corresponding Encrypt
|
||||
/// </summary>
|
||||
/// <param name="msg">message to decrypt</param>
|
||||
/// <returns>true if successful; false if failed</returns>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
int numEncryptedBytes = msg.LengthBytes - 4; // last 4 bytes is true bit length
|
||||
int blockSize = BlockSize;
|
||||
int numBlocks = numEncryptedBytes / blockSize;
|
||||
if (numBlocks * blockSize != numEncryptedBytes)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < numBlocks; i++)
|
||||
{
|
||||
DecryptBlock(msg.m_data, (i * blockSize), m_tmp);
|
||||
Buffer.BlockCopy(m_tmp, 0, msg.m_data, (i * blockSize), m_tmp.Length);
|
||||
}
|
||||
|
||||
// read 32 bits of true payload length
|
||||
uint realSize = NetBitWriter.ReadUInt32(msg.m_data, 32, (numEncryptedBytes * 8));
|
||||
msg.m_bitLength = (int)realSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a block of bytes
|
||||
/// </summary>
|
||||
protected abstract void EncryptBlock(byte[] source, int sourceOffset, byte[] destination);
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt a block of bytes
|
||||
/// </summary>
|
||||
protected abstract void DecryptBlock(byte[] source, int sourceOffset, byte[] destination);
|
||||
}
|
||||
}
|
||||
76
Lidgren.Network/Encryption/NetCryptoProviderBase.cs
Normal file
76
Lidgren.Network/Encryption/NetCryptoProviderBase.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
public abstract class NetCryptoProviderBase : NetEncryption
|
||||
{
|
||||
protected SymmetricAlgorithm m_algorithm;
|
||||
|
||||
public NetCryptoProviderBase(NetPeer peer, SymmetricAlgorithm algo)
|
||||
: base(peer)
|
||||
{
|
||||
m_algorithm = algo;
|
||||
m_algorithm.GenerateKey();
|
||||
m_algorithm.GenerateIV();
|
||||
}
|
||||
|
||||
public override void SetKey(byte[] data, int offset, int count)
|
||||
{
|
||||
int len = m_algorithm.Key.Length;
|
||||
var key = new byte[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
key[i] = data[offset + (i % count)];
|
||||
m_algorithm.Key = key;
|
||||
|
||||
len = m_algorithm.IV.Length;
|
||||
key = new byte[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
key[len - 1 - i] = data[offset + (i % count)];
|
||||
m_algorithm.IV = key;
|
||||
}
|
||||
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
{
|
||||
int unEncLenBits = msg.LengthBits;
|
||||
|
||||
var ms = new MemoryStream();
|
||||
var cs = new CryptoStream(ms, m_algorithm.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(msg.m_data, 0, msg.LengthBytes);
|
||||
cs.Close();
|
||||
|
||||
// get results
|
||||
var arr = ms.ToArray();
|
||||
ms.Close();
|
||||
|
||||
msg.EnsureBufferSize((arr.Length + 4) * 8);
|
||||
msg.LengthBits = 0; // reset write pointer
|
||||
msg.Write((uint)unEncLenBits);
|
||||
msg.Write(arr);
|
||||
msg.LengthBits = (arr.Length + 4) * 8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
int unEncLenBits = (int)msg.ReadUInt32();
|
||||
|
||||
var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4);
|
||||
var cs = new CryptoStream(ms, m_algorithm.CreateDecryptor(), CryptoStreamMode.Read);
|
||||
|
||||
var result = m_peer.GetStorage(unEncLenBits);
|
||||
cs.Read(result, 0, NetUtility.BytesToHoldBits(unEncLenBits));
|
||||
cs.Close();
|
||||
|
||||
// TODO: recycle existing msg
|
||||
|
||||
msg.m_data = result;
|
||||
msg.m_bitLength = unEncLenBits;
|
||||
msg.m_readPosition = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Lidgren.Network/Encryption/NetDESEncryption.cs
Normal file
26
Lidgren.Network/Encryption/NetDESEncryption.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
public class NetDESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
public NetDESEncryption(NetPeer peer)
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
}
|
||||
|
||||
public NetDESEncryption(NetPeer peer, string key)
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public NetDESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Lidgren.Network/Encryption/NetEncryption.cs
Normal file
45
Lidgren.Network/Encryption/NetEncryption.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for an encryption algorithm
|
||||
/// </summary>
|
||||
public abstract class NetEncryption
|
||||
{
|
||||
/// <summary>
|
||||
/// NetPeer
|
||||
/// </summary>
|
||||
protected NetPeer m_peer;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public NetEncryption(NetPeer peer)
|
||||
{
|
||||
if (peer == null)
|
||||
throw new NetException("Peer must not be null");
|
||||
m_peer = peer;
|
||||
}
|
||||
|
||||
public void SetKey(string str)
|
||||
{
|
||||
var bytes = System.Text.Encoding.ASCII.GetBytes(str);
|
||||
SetKey(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
public abstract void SetKey(byte[] data, int offset, int count);
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt an outgoing message in place
|
||||
/// </summary>
|
||||
public abstract bool Encrypt(NetOutgoingMessage msg);
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt an incoming message in place
|
||||
/// </summary>
|
||||
public abstract bool Decrypt(NetIncomingMessage msg);
|
||||
}
|
||||
}
|
||||
26
Lidgren.Network/Encryption/NetRC2Encryption.cs
Normal file
26
Lidgren.Network/Encryption/NetRC2Encryption.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
public class NetRC2Encryption : NetCryptoProviderBase
|
||||
{
|
||||
public NetRC2Encryption(NetPeer peer)
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
}
|
||||
|
||||
public NetRC2Encryption(NetPeer peer, string key)
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public NetRC2Encryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Lidgren.Network/Encryption/NetTripleDESEncryption.cs
Normal file
26
Lidgren.Network/Encryption/NetTripleDESEncryption.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
public class NetTripleDESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
public NetTripleDESEncryption(NetPeer peer)
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
}
|
||||
|
||||
public NetTripleDESEncryption(NetPeer peer, string key)
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public NetTripleDESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Lidgren.Network/Encryption/NetXorEncryption.cs
Normal file
66
Lidgren.Network/Encryption/NetXorEncryption.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Example class; not very good encryption
|
||||
/// </summary>
|
||||
public class NetXorEncryption : NetEncryption
|
||||
{
|
||||
private byte[] m_key;
|
||||
|
||||
/// <summary>
|
||||
/// NetXorEncryption constructor
|
||||
/// </summary>
|
||||
public NetXorEncryption(NetPeer peer, byte[] key)
|
||||
: base(peer)
|
||||
{
|
||||
m_key = key;
|
||||
}
|
||||
|
||||
public override void SetKey(byte[] data, int offset, int count)
|
||||
{
|
||||
m_key = new byte[count];
|
||||
Array.Copy(data, offset, m_key, 0, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetXorEncryption constructor
|
||||
/// </summary>
|
||||
public NetXorEncryption(NetPeer peer, string key)
|
||||
: base(peer)
|
||||
{
|
||||
m_key = Encoding.UTF8.GetBytes(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt an outgoing message
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
{
|
||||
int numBytes = msg.LengthBytes;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
int offset = i % m_key.Length;
|
||||
msg.m_data[i] = (byte)(msg.m_data[i] ^ m_key[offset]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt an incoming message
|
||||
/// </summary>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
int numBytes = msg.LengthBytes;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
int offset = i % m_key.Length;
|
||||
msg.m_data[i] = (byte)(msg.m_data[i] ^ m_key[offset]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Lidgren.Network/Encryption/NetXteaEncryption.cs
Normal file
154
Lidgren.Network/Encryption/NetXteaEncryption.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
/* Copyright (c) 2010 Michael Lidgren
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Security;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods to encrypt and decrypt data using the XTEA algorithm
|
||||
/// </summary>
|
||||
public sealed class NetXtea : NetBlockEncryptionBase
|
||||
{
|
||||
private const int c_blockSize = 8;
|
||||
private const int c_keySize = 16;
|
||||
private const int c_delta = unchecked((int)0x9E3779B9);
|
||||
|
||||
private readonly int m_numRounds;
|
||||
private readonly uint[] m_sum0;
|
||||
private readonly uint[] m_sum1;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the block size for this cipher
|
||||
/// </summary>
|
||||
public override int BlockSize { get { return c_blockSize; } }
|
||||
|
||||
/// <summary>
|
||||
/// 16 byte key
|
||||
/// </summary>
|
||||
public NetXtea(NetPeer peer, byte[] key, int rounds)
|
||||
: base(peer)
|
||||
{
|
||||
if (key.Length < c_keySize)
|
||||
throw new NetException("Key too short!");
|
||||
|
||||
m_numRounds = rounds;
|
||||
m_sum0 = new uint[m_numRounds];
|
||||
m_sum1 = new uint[m_numRounds];
|
||||
uint[] tmp = new uint[8];
|
||||
|
||||
int num2;
|
||||
int index = num2 = 0;
|
||||
while (index < 4)
|
||||
{
|
||||
tmp[index] = BitConverter.ToUInt32(key, num2);
|
||||
index++;
|
||||
num2 += 4;
|
||||
}
|
||||
for (index = num2 = 0; index < 32; index++)
|
||||
{
|
||||
m_sum0[index] = ((uint)num2) + tmp[num2 & 3];
|
||||
num2 += -1640531527;
|
||||
m_sum1[index] = ((uint)num2) + tmp[(num2 >> 11) & 3];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 16 byte key
|
||||
/// </summary>
|
||||
public NetXtea(NetPeer peer, byte[] key)
|
||||
: this(peer, key, 32)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String to hash for key
|
||||
/// </summary>
|
||||
public NetXtea(NetPeer peer, string key)
|
||||
: this(peer, NetUtility.CreateSHA1Hash(key), 32)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetKey(byte[] data, int offset, int length)
|
||||
{
|
||||
var key = NetUtility.CreateSHA1Hash(data, offset, length);
|
||||
NetException.Assert(key.Length == 16);
|
||||
SetKey(key, 0, 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts a block of bytes
|
||||
/// </summary>
|
||||
protected override void EncryptBlock(byte[] source, int sourceOffset, byte[] destination)
|
||||
{
|
||||
uint v0 = BytesToUInt(source, sourceOffset);
|
||||
uint v1 = BytesToUInt(source, sourceOffset + 4);
|
||||
|
||||
for (int i = 0; i != m_numRounds; i++)
|
||||
{
|
||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ m_sum0[i];
|
||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ m_sum1[i];
|
||||
}
|
||||
|
||||
UIntToBytes(v0, destination, 0);
|
||||
UIntToBytes(v1, destination, 0 + 4);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts a block of bytes
|
||||
/// </summary>
|
||||
protected override void DecryptBlock(byte[] source, int sourceOffset, byte[] destination)
|
||||
{
|
||||
// Pack bytes into integers
|
||||
uint v0 = BytesToUInt(source, sourceOffset);
|
||||
uint v1 = BytesToUInt(source, sourceOffset + 4);
|
||||
|
||||
for (int i = m_numRounds - 1; i >= 0; i--)
|
||||
{
|
||||
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ m_sum1[i];
|
||||
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ m_sum0[i];
|
||||
}
|
||||
|
||||
UIntToBytes(v0, destination, 0);
|
||||
UIntToBytes(v1, destination, 0 + 4);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private static uint BytesToUInt(byte[] bytes, int offset)
|
||||
{
|
||||
uint retval = (uint)(bytes[offset] << 24);
|
||||
retval |= (uint)(bytes[++offset] << 16);
|
||||
retval |= (uint)(bytes[++offset] << 8);
|
||||
return (retval | bytes[++offset]);
|
||||
}
|
||||
|
||||
private static void UIntToBytes(uint value, byte[] destination, int destinationOffset)
|
||||
{
|
||||
destination[destinationOffset++] = (byte)(value >> 24);
|
||||
destination[destinationOffset++] = (byte)(value >> 16);
|
||||
destination[destinationOffset++] = (byte)(value >> 8);
|
||||
destination[destinationOffset++] = (byte)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user