diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index 22f1698d..916a8d65 100755 Binary files a/shadowsocks-csharp/Data/libsscrypto.dll.gz and b/shadowsocks-csharp/Data/libsscrypto.dll.gz differ diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index 41bd5c64..79594876 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -13,9 +13,9 @@ namespace Shadowsocks.Encryption static EncryptorFactory() { _registeredEncryptors = new Dictionary(); - 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()) { diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index 6d84de56..e5f21717 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -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 ciphers; + protected Dictionary> ciphers; + protected Dictionary ciphersDetail; private static readonly ConcurrentDictionary CachedKeys = new ConcurrentDictionary(); 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 getCiphers(); + protected abstract Dictionary> 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); diff --git a/shadowsocks-csharp/Encryption/MbedTLS.cs b/shadowsocks-csharp/Encryption/MbedTLS.cs index 27bdce8c..d29b26e5 100644 --- a/shadowsocks-csharp/Encryption/MbedTLS.cs +++ b/shadowsocks-csharp/Encryption/MbedTLS.cs @@ -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); } - [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); + md5(input, (uint)input.Length, output); return output; } + [DllImport("Kernel32.dll")] + private static extern IntPtr LoadLibrary(string path); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr cipher_info_from_string(string cipher_name); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + 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 extern static void md5(byte[] input, uint ilen, byte[] output); + public static extern int cipher_get_size_ex(); } } diff --git a/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs b/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs new file mode 100644 index 00000000..969b9dd2 --- /dev/null +++ b/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs @@ -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> _ciphers = new Dictionary> { + { "aes-128-cfb", new Dictionary { { "AES-128-CFB128", new int[] { 16, 16, CIPHER_AES } } } }, + { "aes-192-cfb", new Dictionary { { "AES-192-CFB128", new int[] { 24, 16, CIPHER_AES } } } }, + { "aes-256-cfb", new Dictionary { { "AES-256-CFB128", new int[] { 32, 16, CIPHER_AES } } } }, + { "aes-128-ctr", new Dictionary { { "AES-128-CTR", new int[] { 16, 16, CIPHER_AES } } } }, + { "aes-192-ctr", new Dictionary { { "AES-192-CTR", new int[] { 24, 16, CIPHER_AES } } } }, + { "aes-256-ctr", new Dictionary { { "AES-256-CTR", new int[] { 32, 16, CIPHER_AES } } } }, + { "bf-cfb", new Dictionary { { "BLOWFISH-CFB64", new int[] { 16, 8, CIPHER_BLOWFISH } } } }, + { "camellia-128-cfb", new Dictionary { { "CAMELLIA-128-CFB128", new int[] { 16, 16, CIPHER_CAMELLIA } } } }, + { "camellia-192-cfb", new Dictionary { { "CAMELLIA-192-CFB128", new int[] { 24, 16, CIPHER_CAMELLIA } } } }, + { "camellia-256-cfb", new Dictionary { { "CAMELLIA-256-CFB128", new int[] { 32, 16, CIPHER_CAMELLIA } } } }, + { "rc4-md5", new Dictionary { { "ARC4-128", new int[] { 16, 16, CIPHER_RC4 } } } } + }; + + public static List SupportedCiphers() + { + return new List(_ciphers.Keys); + } + + protected override Dictionary> 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 + } +} diff --git a/shadowsocks-csharp/Encryption/PolarSSL.cs b/shadowsocks-csharp/Encryption/PolarSSL.cs deleted file mode 100755 index ddf59564..00000000 --- a/shadowsocks-csharp/Encryption/PolarSSL.cs +++ /dev/null @@ -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); - } -} diff --git a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs deleted file mode 100755 index 8e521862..00000000 --- a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs +++ /dev/null @@ -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 _ciphers = new Dictionary { - {"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 SupportedCiphers() - { - return new List(_ciphers.Keys); - } - - protected override Dictionary 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 - } -} diff --git a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs index b3877f86..8052fda5 100755 --- a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs @@ -27,13 +27,13 @@ namespace Shadowsocks.Encryption InitKey(method, password); } - private static Dictionary _ciphers = new Dictionary { - {"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> _ciphers = new Dictionary> { + { "salsa20", new Dictionary { { "salsa20", new int[] { 32, 8, CIPHER_SALSA20 } } } }, + { "chacha20", new Dictionary { { "chacha20", new int[] { 32, 8, CIPHER_CHACHA20 } } } }, + { "chacha20-ietf", new Dictionary { { "chacha20-ietf", new int[] { 32, 12, CIPHER_CHACHA20_IETF } } } } }; - protected override Dictionary getCiphers() + protected override Dictionary> getCiphers() { return _ciphers; } diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 834ec361..50207095 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -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); diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 8e9c153a..c4c87271 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -156,8 +156,7 @@ - - + diff --git a/test/UnitTest.cs b/test/UnitTest.cs index 7cbcee1c..6fa4f21d 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -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 threads = new List(); 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); } }