Refine encryption(#655)
* Refine encryption - Add AES-CTR, blowfish and camellia ciphers aes-256-ctr aes-192-ctr aes-128-ctr bf-cfb camellia-128-cfb camellia-192-cfb camellia-256-cfb - Merge the previous PolarSSL and MbedTLS - Switch to MbedTLS's cipher layer functions - Add workaround to set cipher operation(encrypt/decrypt) Signed-off-by: Syrone Wong <wong.syrone@gmail.com> * Add function to get MbedTLS cipher context size and drop hard-coded ctx sizes Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
This commit is contained in:
Binary file not shown.
@@ -13,9 +13,9 @@ namespace Shadowsocks.Encryption
|
||||
static EncryptorFactory()
|
||||
{
|
||||
_registeredEncryptors = new Dictionary<string, Type>();
|
||||
foreach (string method in PolarSSLEncryptor.SupportedCiphers())
|
||||
foreach (string method in MbedTLSEncryptor.SupportedCiphers())
|
||||
{
|
||||
_registeredEncryptors.Add(method, typeof(PolarSSLEncryptor));
|
||||
_registeredEncryptors.Add(method, typeof(MbedTLSEncryptor));
|
||||
}
|
||||
foreach (string method in SodiumEncryptor.SupportedCiphers())
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
@@ -23,17 +24,18 @@ namespace Shadowsocks.Encryption
|
||||
|
||||
protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE];
|
||||
|
||||
protected Dictionary<string, int[]> ciphers;
|
||||
protected Dictionary<string, Dictionary<string, int[]>> ciphers;
|
||||
protected Dictionary<string, int[]> ciphersDetail;
|
||||
|
||||
private static readonly ConcurrentDictionary<string, byte[]> CachedKeys = new ConcurrentDictionary<string, byte[]>();
|
||||
protected byte[] _encryptIV;
|
||||
protected byte[] _decryptIV;
|
||||
protected bool _decryptIVReceived;
|
||||
protected bool _encryptIVSent;
|
||||
protected int _encryptIVOffset = 0;
|
||||
protected int _decryptIVOffset = 0;
|
||||
protected string _method;
|
||||
protected int _cipher;
|
||||
// cipher name in MbedTLS, useless when using LibSodium
|
||||
protected string _cipherMbedName;
|
||||
protected int[] _cipherInfo;
|
||||
protected byte[] _key;
|
||||
protected int keyLen;
|
||||
@@ -47,7 +49,7 @@ namespace Shadowsocks.Encryption
|
||||
InitKey(method, password);
|
||||
}
|
||||
|
||||
protected abstract Dictionary<string, int[]> getCiphers();
|
||||
protected abstract Dictionary<string, Dictionary<string, int[]>> getCiphers();
|
||||
|
||||
protected void InitKey(string method, string password)
|
||||
{
|
||||
@@ -55,14 +57,16 @@ namespace Shadowsocks.Encryption
|
||||
_method = method;
|
||||
string k = method + ":" + password;
|
||||
ciphers = getCiphers();
|
||||
_cipherInfo = ciphers[_method];
|
||||
ciphersDetail = ciphers[_method];
|
||||
_cipherMbedName = ciphersDetail.Keys.FirstOrDefault();
|
||||
_cipherInfo = ciphers[_method][_cipherMbedName];
|
||||
_cipher = _cipherInfo[2];
|
||||
if (_cipher == 0)
|
||||
{
|
||||
throw new Exception("method not found");
|
||||
}
|
||||
keyLen = ciphers[_method][0];
|
||||
ivLen = ciphers[_method][1];
|
||||
keyLen = _cipherInfo[0];
|
||||
ivLen = _cipherInfo[1];
|
||||
_key = CachedKeys.GetOrAdd(k, (nk) =>
|
||||
{
|
||||
byte[] passbuf = Encoding.UTF8.GetBytes(password);
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace Shadowsocks.Encryption
|
||||
{
|
||||
const string DLLNAME = "libsscrypto";
|
||||
|
||||
public const int MBEDTLS_ENCRYPT = 1;
|
||||
public const int MBEDTLS_DECRYPT = 0;
|
||||
|
||||
static MbedTLS()
|
||||
{
|
||||
string dllPath = Utils.GetTempPath("libsscrypto.dll");
|
||||
@@ -24,24 +27,53 @@ namespace Shadowsocks.Encryption
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
Logging.LogUsefulException(e);
|
||||
}
|
||||
LoadLibrary(dllPath);
|
||||
}
|
||||
|
||||
public static byte[] MD5(byte[] input)
|
||||
{
|
||||
byte[] output = new byte[16];
|
||||
md5(input, (uint)input.Length, output);
|
||||
return output;
|
||||
}
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern IntPtr LoadLibrary(string path);
|
||||
|
||||
public const int MD5_CTX_SIZE = 88;
|
||||
|
||||
public static byte[] MD5(byte[] input)
|
||||
{
|
||||
byte[] output = new byte[16];
|
||||
MbedTLS.md5(input, (uint)input.Length, output);
|
||||
return output;
|
||||
}
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr cipher_info_from_string(string cipher_name);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void md5(byte[] input, uint ilen, byte[] output);
|
||||
public static extern void cipher_init(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_setup(IntPtr ctx, IntPtr cipher_info);
|
||||
|
||||
// check operation
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_setkey(IntPtr ctx, byte[] key, int key_bitlen, int operation);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_set_iv(IntPtr ctx, byte[] iv, int iv_len);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_reset(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_update(IntPtr ctx, byte[] input, int ilen, byte[] output, ref int olen);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void cipher_free(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void md5(byte[] input, uint ilen, byte[] output);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void cipher_set_operation_ex(IntPtr ctx, int operation);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int cipher_get_size_ex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Shadowsocks.Encryption
|
||||
{
|
||||
public class MbedTLSEncryptor
|
||||
: IVEncryptor, IDisposable
|
||||
{
|
||||
const int CIPHER_RC4 = 1;
|
||||
const int CIPHER_AES = 2;
|
||||
const int CIPHER_BLOWFISH = 3;
|
||||
const int CIPHER_CAMELLIA = 4;
|
||||
|
||||
private IntPtr _encryptCtx = IntPtr.Zero;
|
||||
private IntPtr _decryptCtx = IntPtr.Zero;
|
||||
|
||||
public MbedTLSEncryptor(string method, string password, bool onetimeauth, bool isudp)
|
||||
: base(method, password, onetimeauth, isudp)
|
||||
{
|
||||
InitKey(method, password);
|
||||
}
|
||||
|
||||
private static Dictionary<string, Dictionary<string, int[]>> _ciphers = new Dictionary<string, Dictionary<string, int[]>> {
|
||||
{ "aes-128-cfb", new Dictionary<string, int[]> { { "AES-128-CFB128", new int[] { 16, 16, CIPHER_AES } } } },
|
||||
{ "aes-192-cfb", new Dictionary<string, int[]> { { "AES-192-CFB128", new int[] { 24, 16, CIPHER_AES } } } },
|
||||
{ "aes-256-cfb", new Dictionary<string, int[]> { { "AES-256-CFB128", new int[] { 32, 16, CIPHER_AES } } } },
|
||||
{ "aes-128-ctr", new Dictionary<string, int[]> { { "AES-128-CTR", new int[] { 16, 16, CIPHER_AES } } } },
|
||||
{ "aes-192-ctr", new Dictionary<string, int[]> { { "AES-192-CTR", new int[] { 24, 16, CIPHER_AES } } } },
|
||||
{ "aes-256-ctr", new Dictionary<string, int[]> { { "AES-256-CTR", new int[] { 32, 16, CIPHER_AES } } } },
|
||||
{ "bf-cfb", new Dictionary<string, int[]> { { "BLOWFISH-CFB64", new int[] { 16, 8, CIPHER_BLOWFISH } } } },
|
||||
{ "camellia-128-cfb", new Dictionary<string, int[]> { { "CAMELLIA-128-CFB128", new int[] { 16, 16, CIPHER_CAMELLIA } } } },
|
||||
{ "camellia-192-cfb", new Dictionary<string, int[]> { { "CAMELLIA-192-CFB128", new int[] { 24, 16, CIPHER_CAMELLIA } } } },
|
||||
{ "camellia-256-cfb", new Dictionary<string, int[]> { { "CAMELLIA-256-CFB128", new int[] { 32, 16, CIPHER_CAMELLIA } } } },
|
||||
{ "rc4-md5", new Dictionary<string, int[]> { { "ARC4-128", new int[] { 16, 16, CIPHER_RC4 } } } }
|
||||
};
|
||||
|
||||
public static List<string> SupportedCiphers()
|
||||
{
|
||||
return new List<string>(_ciphers.Keys);
|
||||
}
|
||||
|
||||
protected override Dictionary<string, Dictionary<string, int[]>> getCiphers()
|
||||
{
|
||||
return _ciphers;
|
||||
}
|
||||
|
||||
protected override void initCipher(byte[] iv, bool isCipher)
|
||||
{
|
||||
base.initCipher(iv, isCipher);
|
||||
IntPtr ctx = Marshal.AllocHGlobal(MbedTLS.cipher_get_size_ex());
|
||||
if (isCipher)
|
||||
{
|
||||
_encryptCtx = ctx;
|
||||
}
|
||||
else
|
||||
{
|
||||
_decryptCtx = ctx;
|
||||
}
|
||||
byte[] realkey;
|
||||
if (_method == "rc4-md5")
|
||||
{
|
||||
byte[] temp = new byte[keyLen + ivLen];
|
||||
realkey = new byte[keyLen];
|
||||
Array.Copy(_key, 0, temp, 0, keyLen);
|
||||
Array.Copy(iv, 0, temp, keyLen, ivLen);
|
||||
realkey = MbedTLS.MD5(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
realkey = _key;
|
||||
}
|
||||
MbedTLS.cipher_init(ctx);
|
||||
if (MbedTLS.cipher_setup( ctx, MbedTLS.cipher_info_from_string( _cipherMbedName ) ) != 0 )
|
||||
throw new Exception();
|
||||
// MbedTLS takes key length by bit
|
||||
// cipher_setkey() will set the correct key schedule
|
||||
if (MbedTLS.cipher_setkey(ctx, realkey, keyLen * 8, isCipher ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT) != 0 )
|
||||
throw new Exception();
|
||||
if (MbedTLS.cipher_set_iv(ctx, iv, ivLen) != 0)
|
||||
throw new Exception();
|
||||
if (MbedTLS.cipher_reset(ctx) != 0)
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf)
|
||||
{
|
||||
// C# could be multi-threaded
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(this.ToString());
|
||||
}
|
||||
IntPtr ctx;
|
||||
if (isCipher)
|
||||
{
|
||||
ctx = _encryptCtx;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx = _decryptCtx;
|
||||
}
|
||||
|
||||
if (_cipher == CIPHER_AES
|
||||
|| _cipher == CIPHER_BLOWFISH
|
||||
|| _cipher == CIPHER_CAMELLIA)
|
||||
{
|
||||
/*
|
||||
* operation workaround
|
||||
*
|
||||
* MBEDTLS_AES_{EN,DE}CRYPT
|
||||
* == MBEDTLS_BLOWFISH_{EN,DE}CRYPT
|
||||
* == MBEDTLS_CAMELLIA_{EN,DE}CRYPT
|
||||
* == MBEDTLS_{EN,DE}CRYPT
|
||||
* setter code in C:
|
||||
* ctx->operation = operation;
|
||||
*/
|
||||
MbedTLS.cipher_set_operation_ex(ctx, isCipher ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT);
|
||||
}
|
||||
if (MbedTLS.cipher_update(ctx, buf, length, outbuf, ref length) != 0 )
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
private bool _disposed;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~MbedTLSEncryptor()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_encryptCtx != IntPtr.Zero)
|
||||
{
|
||||
MbedTLS.cipher_free(_encryptCtx);
|
||||
Marshal.FreeHGlobal(_encryptCtx);
|
||||
_encryptCtx = IntPtr.Zero;
|
||||
}
|
||||
if (_decryptCtx != IntPtr.Zero)
|
||||
{
|
||||
MbedTLS.cipher_free(_decryptCtx);
|
||||
Marshal.FreeHGlobal(_decryptCtx);
|
||||
_decryptCtx = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Shadowsocks.Controller;
|
||||
using Shadowsocks.Properties;
|
||||
using Shadowsocks.Util;
|
||||
|
||||
namespace Shadowsocks.Encryption
|
||||
{
|
||||
public class PolarSSL
|
||||
{
|
||||
const string DLLNAME = "libsscrypto";
|
||||
|
||||
public const int AES_CTX_SIZE = 8 + 4 * 68;
|
||||
public const int AES_ENCRYPT = 1;
|
||||
public const int AES_DECRYPT = 0;
|
||||
|
||||
static PolarSSL()
|
||||
{
|
||||
string dllPath = Utils.GetTempPath("libsscrypto.dll");
|
||||
try
|
||||
{
|
||||
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
}
|
||||
LoadLibrary(dllPath);
|
||||
}
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern IntPtr LoadLibrary(string path);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void aes_init(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void aes_free(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int aes_setkey_enc(IntPtr ctx, byte[] key, int keysize);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int aes_crypt_cfb128(IntPtr ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output);
|
||||
|
||||
public const int ARC4_CTX_SIZE = 264;
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void arc4_init(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void arc4_free(IntPtr ctx);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void arc4_setup(IntPtr ctx, byte[] key, int keysize);
|
||||
|
||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int arc4_crypt(IntPtr ctx, int length, byte[] input, byte[] output);
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Shadowsocks.Encryption
|
||||
{
|
||||
public class PolarSSLEncryptor
|
||||
: IVEncryptor, IDisposable
|
||||
{
|
||||
const int CIPHER_AES = 1;
|
||||
const int CIPHER_RC4 = 2;
|
||||
|
||||
private IntPtr _encryptCtx = IntPtr.Zero;
|
||||
private IntPtr _decryptCtx = IntPtr.Zero;
|
||||
|
||||
public PolarSSLEncryptor(string method, string password, bool onetimeauth, bool isudp)
|
||||
: base(method, password, onetimeauth, isudp)
|
||||
{
|
||||
InitKey(method, password);
|
||||
}
|
||||
|
||||
private static Dictionary<string, int[]> _ciphers = new Dictionary<string, int[]> {
|
||||
{"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}},
|
||||
{"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}},
|
||||
{"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}},
|
||||
{"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}},
|
||||
};
|
||||
|
||||
public static List<string> SupportedCiphers()
|
||||
{
|
||||
return new List<string>(_ciphers.Keys);
|
||||
}
|
||||
|
||||
protected override Dictionary<string, int[]> getCiphers()
|
||||
{
|
||||
return _ciphers;
|
||||
}
|
||||
|
||||
protected override void initCipher(byte[] iv, bool isCipher)
|
||||
{
|
||||
base.initCipher(iv, isCipher);
|
||||
|
||||
IntPtr ctx;
|
||||
ctx = Marshal.AllocHGlobal(_cipherInfo[3]);
|
||||
if (isCipher)
|
||||
{
|
||||
_encryptCtx = ctx;
|
||||
}
|
||||
else
|
||||
{
|
||||
_decryptCtx = ctx;
|
||||
}
|
||||
byte[] realkey;
|
||||
if (_method == "rc4-md5")
|
||||
{
|
||||
byte[] temp = new byte[keyLen + ivLen];
|
||||
realkey = new byte[keyLen];
|
||||
Array.Copy(_key, 0, temp, 0, keyLen);
|
||||
Array.Copy(iv, 0, temp, keyLen, ivLen);
|
||||
realkey = MbedTLS.MD5(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
realkey = _key;
|
||||
}
|
||||
if (_cipher == CIPHER_AES)
|
||||
{
|
||||
PolarSSL.aes_init(ctx);
|
||||
// PolarSSL takes key length by bit
|
||||
// since we'll use CFB mode, here we both do enc, not dec
|
||||
PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8);
|
||||
}
|
||||
else if (_cipher == CIPHER_RC4)
|
||||
{
|
||||
PolarSSL.arc4_init(ctx);
|
||||
// PolarSSL RC4 takes key length by byte
|
||||
PolarSSL.arc4_setup(ctx, realkey, keyLen);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf)
|
||||
{
|
||||
// C# could be multi-threaded
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(this.ToString());
|
||||
}
|
||||
byte[] iv;
|
||||
int ivOffset;
|
||||
IntPtr ctx;
|
||||
if (isCipher)
|
||||
{
|
||||
iv = _encryptIV;
|
||||
ivOffset = _encryptIVOffset;
|
||||
ctx = _encryptCtx;
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = _decryptIV;
|
||||
ivOffset = _decryptIVOffset;
|
||||
ctx = _decryptCtx;
|
||||
}
|
||||
switch (_cipher)
|
||||
{
|
||||
case CIPHER_AES:
|
||||
PolarSSL.aes_crypt_cfb128(ctx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf);
|
||||
if (isCipher)
|
||||
{
|
||||
_encryptIVOffset = ivOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
_decryptIVOffset = ivOffset;
|
||||
}
|
||||
break;
|
||||
case CIPHER_RC4:
|
||||
PolarSSL.arc4_crypt(ctx, length, buf, outbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
private bool _disposed;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~PolarSSLEncryptor()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_encryptCtx != IntPtr.Zero)
|
||||
{
|
||||
switch (_cipher)
|
||||
{
|
||||
case CIPHER_AES:
|
||||
PolarSSL.aes_free(_encryptCtx);
|
||||
break;
|
||||
case CIPHER_RC4:
|
||||
PolarSSL.arc4_free(_encryptCtx);
|
||||
break;
|
||||
}
|
||||
Marshal.FreeHGlobal(_encryptCtx);
|
||||
_encryptCtx = IntPtr.Zero;
|
||||
}
|
||||
if (_decryptCtx != IntPtr.Zero)
|
||||
{
|
||||
switch (_cipher)
|
||||
{
|
||||
case CIPHER_AES:
|
||||
PolarSSL.aes_free(_decryptCtx);
|
||||
break;
|
||||
case CIPHER_RC4:
|
||||
PolarSSL.arc4_free(_decryptCtx);
|
||||
break;
|
||||
}
|
||||
Marshal.FreeHGlobal(_decryptCtx);
|
||||
_decryptCtx = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -27,13 +27,13 @@ namespace Shadowsocks.Encryption
|
||||
InitKey(method, password);
|
||||
}
|
||||
|
||||
private static Dictionary<string, int[]> _ciphers = new Dictionary<string, int[]> {
|
||||
{"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}},
|
||||
{"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}},
|
||||
{"chacha20-ietf", new int[]{32, 12, CIPHER_CHACHA20_IETF, PolarSSL.AES_CTX_SIZE}},
|
||||
private static Dictionary<string, Dictionary<string, int[]>> _ciphers = new Dictionary<string, Dictionary<string, int[]>> {
|
||||
{ "salsa20", new Dictionary<string, int[]> { { "salsa20", new int[] { 32, 8, CIPHER_SALSA20 } } } },
|
||||
{ "chacha20", new Dictionary<string, int[]> { { "chacha20", new int[] { 32, 8, CIPHER_CHACHA20 } } } },
|
||||
{ "chacha20-ietf", new Dictionary<string, int[]> { { "chacha20-ietf", new int[] { 32, 12, CIPHER_CHACHA20_IETF } } } }
|
||||
};
|
||||
|
||||
protected override Dictionary<string, int[]> getCiphers()
|
||||
protected override Dictionary<string, Dictionary<string, int[]>> getCiphers()
|
||||
{
|
||||
return _ciphers;
|
||||
}
|
||||
|
||||
+8
-1
@@ -204,7 +204,14 @@
|
||||
"chacha20-ietf",
|
||||
"aes-256-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-128-cfb"});
|
||||
"aes-128-cfb",
|
||||
"aes-256-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-128-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",});
|
||||
this.EncryptionSelect.Location = new System.Drawing.Point(83, 87);
|
||||
this.EncryptionSelect.Name = "EncryptionSelect";
|
||||
this.EncryptionSelect.Size = new System.Drawing.Size(160, 20);
|
||||
|
||||
@@ -156,8 +156,7 @@
|
||||
<Compile Include="Encryption\EncryptorFactory.cs" />
|
||||
<Compile Include="Encryption\IVEncryptor.cs" />
|
||||
<Compile Include="Encryption\MbedTLS.cs" />
|
||||
<Compile Include="Encryption\PolarSSL.cs" />
|
||||
<Compile Include="Encryption\PolarSSLEncryptor.cs" />
|
||||
<Compile Include="Encryption\MbedTLSEncryptor.cs" />
|
||||
<Compile Include="Encryption\Sodium.cs" />
|
||||
<Compile Include="Encryption\SodiumEncryptor.cs" />
|
||||
<Compile Include="Encryption\IEncryptor.cs" />
|
||||
|
||||
+8
-8
@@ -73,14 +73,14 @@ namespace test
|
||||
private static object locker = new object();
|
||||
|
||||
[TestMethod]
|
||||
public void TestPolarSSLEncryption()
|
||||
public void TestMbedTLSEncryption()
|
||||
{
|
||||
// run it once before the multi-threading test to initialize global tables
|
||||
RunSinglePolarSSLEncryptionThread();
|
||||
RunSingleMbedTLSEncryptionThread();
|
||||
List<Thread> threads = new List<Thread>();
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Thread t = new Thread(new ThreadStart(RunSinglePolarSSLEncryptionThread));
|
||||
Thread t = new Thread(new ThreadStart(RunSingleMbedTLSEncryptionThread));
|
||||
threads.Add(t);
|
||||
t.Start();
|
||||
}
|
||||
@@ -91,7 +91,7 @@ namespace test
|
||||
Assert.IsFalse(encryptionFailed);
|
||||
}
|
||||
|
||||
private void RunSinglePolarSSLEncryptionThread()
|
||||
private void RunSingleMbedTLSEncryptionThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -99,8 +99,8 @@ namespace test
|
||||
{
|
||||
IEncryptor encryptor;
|
||||
IEncryptor decryptor;
|
||||
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
|
||||
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
|
||||
encryptor = new MbedTLSEncryptor("aes-256-cfb", "barfoo!", false, false);
|
||||
decryptor = new MbedTLSEncryptor("aes-256-cfb", "barfoo!", false, false);
|
||||
RunEncryptionRound(encryptor, decryptor);
|
||||
}
|
||||
}
|
||||
@@ -139,8 +139,8 @@ namespace test
|
||||
var random = new Random();
|
||||
IEncryptor encryptor;
|
||||
IEncryptor decryptor;
|
||||
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
|
||||
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
|
||||
encryptor = new MbedTLSEncryptor("rc4-md5", "barfoo!", false, false);
|
||||
decryptor = new MbedTLSEncryptor("rc4-md5", "barfoo!", false, false);
|
||||
RunEncryptionRound(encryptor, decryptor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user