Browse Source

add polarssl

tags/2.3
clowwindy 10 years ago
parent
commit
41c5c5a483
5 changed files with 266 additions and 1 deletions
  1. BIN
      polarssl/polarssl.dll
  2. +1
    -1
      shadowsocks-csharp/Encrypt/EncryptorFactory.cs
  3. +44
    -0
      shadowsocks-csharp/Encrypt/PolarSSL.cs
  4. +219
    -0
      shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs
  5. +2
    -0
      shadowsocks-csharp/shadowsocks-csharp.csproj

BIN
polarssl/polarssl.dll View File


+ 1
- 1
shadowsocks-csharp/Encrypt/EncryptorFactory.cs View File

@@ -10,7 +10,7 @@ namespace shadowsocks_csharp.Encrypt
return new TableEncryptor(method, password);
}

return new OpensslEncryptor(method, password);
return new PolarSSLEncryptor(method, password);
}
}
}

+ 44
- 0
shadowsocks-csharp/Encrypt/PolarSSL.cs View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace shadowsocks_csharp.Encrypt
{
public class PolarSSL
{
const string DLLNAME = "polarssl";
public const int AES_CTX_SIZE = 8 + 4 * 68;
public const int AES_ENCRYPT = 1;
public const int AES_DECRYPT = 0;
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void aes_init(byte[] ctx);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void aes_free(byte[] ctx);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int aes_setkey_enc(byte[] ctx, byte[] key, int keysize);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int aes_crypt_cfb128(byte[] 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(byte[] ctx);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void arc4_free(byte[] ctx);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void arc4_setup(byte[] ctx, byte[] key, int keysize);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int arc4_crypt(byte[] ctx, int length, byte[] input, byte[] output);
}
}

+ 219
- 0
shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs View File

@@ -0,0 +1,219 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace shadowsocks_csharp.Encrypt
{
public class PolarSSLEncryptor
: EncryptorBase, IDisposable
{
const int CIPHER_AES = 1;
const int CIPHER_RC4 = 2;
const int CIPHER_BF = 3;
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}},
//{"bf-cfb", new int[]{16, 8, CIPHER_BF, PolarSSL.BF_CTX_SIZE}},
{"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}},
{"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}},
};
private static readonly Dictionary<string, byte[]> CachedKeys = new Dictionary<string, byte[]>();
private int _cipher;
private int[] _cipherInfo;
private byte[] _key;
private byte[] _encryptCtx;
private byte[] _decryptCtx;
private byte[] _encryptIV;
private byte[] _decryptIV;
private int _encryptIVOffset;
private int _decryptIVOffset;
private string _method;
private int keyLen;
private int ivLen;
public PolarSSLEncryptor(string method, string password)
: base(method, password)
{
InitKey(method, password);
}
private static void randBytes(byte[] buf, int length)
{
byte[] temp = new byte[length];
new Random().NextBytes(temp);
temp.CopyTo(buf, 0);
}
private void bytesToKey(byte[] password, byte[] key)
{
byte[] result = new byte[password.Length + 16];
int i = 0;
byte[] md5sum = null;
while (i < key.Length)
{
MD5 md5 = MD5.Create();
if (i == 0)
{
md5sum = md5.ComputeHash(password);
}
else
{
md5sum.CopyTo(result, 0);
password.CopyTo(result, md5sum.Length);
md5sum = md5.ComputeHash(result);
}
md5sum.CopyTo(key, i);
i += md5sum.Length;
}
}
private void InitKey(string method, string password)
{
method = method.ToLower();
_method = method;
string k = method + ":" + password;
_cipherInfo = ciphers[_method];
_cipher = _cipherInfo[2];
if (_cipher == 0)
{
throw new Exception("method not found");
}
keyLen = ciphers[_method][0];
ivLen = ciphers[_method][1];
if (CachedKeys.ContainsKey(k))
{
_key = CachedKeys[k];
}
else
{
byte[] passbuf = Encoding.UTF8.GetBytes(password);
_key = new byte[32];
byte[] iv = new byte[16];
bytesToKey(passbuf, _key);
CachedKeys[k] = _key;
}
}
private void InitCipher(ref byte[] ctx, byte[] iv, bool isCipher)
{
ctx = new byte[_cipherInfo[3]];
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 = MD5.Create().ComputeHash(temp);
}
else
{
realkey = _key;
}
if (_cipher == CIPHER_AES)
{
PolarSSL.aes_init(ctx);
if (isCipher)
{
// PolarSSL takes key length by bit
PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8);
_encryptIV = new byte[ivLen];
Array.Copy(iv, _encryptIV, ivLen);
}
else
{
// PolarSSL takes key length by bit
// since we'll use CFB mode, here we also do enc, not dec
PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8);
_decryptIV = new byte[ivLen];
Array.Copy(iv, _decryptIV, ivLen);
}
}
else if (_cipher == CIPHER_RC4)
{
PolarSSL.arc4_init(ctx);
PolarSSL.arc4_setup(ctx, realkey, keyLen);
}
}
static byte[] tempbuf = new byte[32768];
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
if (_encryptCtx == null)
{
randBytes(outbuf, ivLen);
InitCipher(ref _encryptCtx, outbuf, true);
outlength = length + ivLen;
switch (_cipher)
{
case CIPHER_AES:
PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf);
break;
case CIPHER_RC4:
PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf);
break;
}
outlength = length + ivLen;
Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, outlength);
}
else
{
outlength = length;
switch (_cipher)
{
case CIPHER_AES:
PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf);
break;
case CIPHER_RC4:
PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf);
break;
}
}
}
public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
if (_decryptCtx == null)
{
InitCipher(ref _decryptCtx, buf, false);
outlength = length - ivLen;
Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen);
switch (_cipher)
{
case CIPHER_AES:
PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf);
break;
case CIPHER_RC4:
PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf);
break;
}
}
else
{
outlength = length;
switch (_cipher)
{
case CIPHER_AES:
PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf);
break;
case CIPHER_RC4:
PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf);
break;
}
}
}
public override void Dispose()
{
}
}
}

+ 2
- 0
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -85,6 +85,8 @@
<Compile Include="Encrypt\EncryptorFactory.cs" />
<Compile Include="Encrypt\OpenSSL.cs" />
<Compile Include="Encrypt\OpensslEncryptor.cs" />
<Compile Include="Encrypt\PolarSSL.cs" />
<Compile Include="Encrypt\PolarSSLEncryptor.cs" />
<Compile Include="Encrypt\TableEncryptor.cs" />
<Compile Include="Encrypt\IEncryptor.cs" />
<Compile Include="PACServer.cs" />


Loading…
Cancel
Save