Browse Source

refactor crypto test

pull/2865/head
Student Main 5 years ago
parent
commit
8fc46bb9c4
2 changed files with 57 additions and 99 deletions
  1. +31
    -14
      shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs
  2. +26
    -85
      test/CryptographyTest.cs

+ 31
- 14
shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs View File

@@ -53,7 +53,8 @@ namespace Shadowsocks.Encryption.Stream
CipherInfo = ciphers[_method];
_innerLibName = CipherInfo.InnerLibName;
_cipher = CipherInfo.Type;
if (_cipher == 0) {
if (_cipher == 0)
{
throw new System.Exception("method not found");
}
keyLen = CipherInfo.KeySize;
@@ -73,10 +74,14 @@ namespace Shadowsocks.Encryption.Stream
byte[] result = new byte[password.Length + MD5_LEN];
int i = 0;
byte[] md5sum = null;
while (i < keylen) {
if (i == 0) {
while (i < keylen)
{
if (i == 0)
{
md5sum = CryptoUtils.MD5(password);
} else {
}
else
{
Array.Copy(md5sum, 0, result, 0, MD5_LEN);
Array.Copy(password, 0, result, MD5_LEN, password.Length);
md5sum = CryptoUtils.MD5(result);
@@ -88,10 +93,13 @@ namespace Shadowsocks.Encryption.Stream
protected virtual void initCipher(byte[] iv, bool isEncrypt)
{
if (isEncrypt) {
if (isEncrypt)
{
_encryptIV = new byte[ivLen];
Array.Copy(iv, _encryptIV, ivLen);
} else {
}
else
{
_decryptIV = new byte[ivLen];
Array.Copy(iv, _decryptIV, ivLen);
}
@@ -108,12 +116,13 @@ namespace Shadowsocks.Encryption.Stream
int cipherOffset = 0;
Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");
_encCircularBuffer.Put(buf, 0, length);
if (! _encryptIVSent) {
if (!_encryptIVSent)
{
// Generate IV
byte[] ivBytes = new byte[ivLen];
randBytes(ivBytes, ivLen);
initCipher(ivBytes, true);
Array.Copy(ivBytes, 0, outbuf, 0, ivLen);
cipherOffset = ivLen;
_encryptIVSent = true;
@@ -130,16 +139,22 @@ namespace Shadowsocks.Encryption.Stream
{
Debug.Assert(_decCircularBuffer != null, "_circularBuffer != null");
_decCircularBuffer.Put(buf, 0, length);
if (! _decryptIVReceived) {
if (_decCircularBuffer.Size <= ivLen) {
if (!_decryptIVReceived)
{
if (_decCircularBuffer.Size <= ivLen)
{
// we need more data
outlength = 0;
return;
}
// start decryption
_decryptIVReceived = true;
byte[] iv = _decCircularBuffer.Get(ivLen);
initCipher(iv, false);
if (ivLen > 0)
{
byte[] iv = _decCircularBuffer.Get(ivLen);
initCipher(iv, false);
}
else initCipher(Array.Empty<byte>(), false);
}
byte[] cipher = _decCircularBuffer.ToArray();
cipherUpdate(false, cipher.Length, cipher, outbuf);
@@ -158,7 +173,8 @@ namespace Shadowsocks.Encryption.Stream
// Generate IV
randBytes(outbuf, ivLen);
initCipher(outbuf, true);
lock (_udpTmpBuf) {
lock (_udpTmpBuf)
{
cipherUpdate(true, length, buf, _udpTmpBuf);
outlength = length + ivLen;
Buffer.BlockCopy(_udpTmpBuf, 0, outbuf, ivLen, length);
@@ -170,7 +186,8 @@ namespace Shadowsocks.Encryption.Stream
// Get IV from first pos
initCipher(buf, false);
outlength = length - ivLen;
lock (_udpTmpBuf) {
lock (_udpTmpBuf)
{
// C# could be multi-threaded
Buffer.BlockCopy(buf, ivLen, _udpTmpBuf, 0, length - ivLen);
cipherUpdate(false, length - ivLen, _udpTmpBuf, outbuf);


+ 26
- 85
test/CryptographyTest.cs View File

@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shadowsocks.Encryption;
using Shadowsocks.Encryption.Stream;
using Shadowsocks.Encryption.AEAD;
using System;
using System.Collections.Generic;
using System.Threading;
@@ -59,41 +60,20 @@ namespace Shadowsocks.Test
}
}
private static bool encryptionFailed = false;
private static object locker = new object();
const string password = "barfoo!";
[TestMethod]
public void TestBouncyCastleAEADEncryption()
private void RunSingleEncryptionThread(Type enc, Type dec, string method)
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleBouncyCastleAEADEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleBouncyCastleAEADEncryptionThread)); threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
var ector = enc.GetConstructor(new Type[] { typeof(string), typeof(string) });
var dctor = dec.GetConstructor(new Type[] { typeof(string), typeof(string) });
private void RunSingleBouncyCastleAEADEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new Encryption.AEAD.AEADBouncyCastleEncryptor("aes-256-gcm", "barfoo!");
IEncryptor encryptor = (IEncryptor)ector.Invoke(new object[] { method, password });
IEncryptor decryptor = (IEncryptor)dctor.Invoke(new object[] { method, password });
encryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
decryptor = new Encryption.AEAD.AEADBouncyCastleEncryptor("aes-256-gcm", "barfoo!");
decryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
RunEncryptionRound(encryptor, decryptor);
}
@@ -105,16 +85,22 @@ namespace Shadowsocks.Test
}
}
[TestMethod]
public void TesNaClAEADEncryption()
private static bool encryptionFailed = false;
private void TestEncryptionMethod(Type enc, string method)
{
TestEncryptionMethod(enc, enc, method);
}
private void TestEncryptionMethod(Type enc, Type dec, string method)
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleNaClAEADEncryptionThread();
RunSingleEncryptionThread(enc, dec, method);
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleNaClAEADEncryptionThread)); threads.Add(t);
Thread t = new Thread(new ThreadStart(() => RunSingleEncryptionThread(enc, dec, method))); threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
@@ -125,68 +111,23 @@ namespace Shadowsocks.Test
Assert.IsFalse(encryptionFailed);
}
private void RunSingleNaClAEADEncryptionThread()
[TestMethod]
public void TestBouncyCastleAEADEncryption()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new Encryption.AEAD.AEADNaClEncryptor("chacha20-ietf-poly1305", "barfoo!");
encryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
decryptor = new Encryption.AEAD.AEADNaClEncryptor("chacha20-ietf-poly1305", "barfoo!");
decryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
TestEncryptionMethod(typeof(AEADBouncyCastleEncryptor), "aes-256-gcm");
}
[TestMethod]
public void TestNativeEncryption()
public void TestNaClAEADEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleNativeEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleNativeEncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
TestEncryptionMethod(typeof(AEADNaClEncryptor), "chacha20-ietf-poly1305");
}
private void RunSingleNativeEncryptionThread()
[TestMethod]
public void TestNativeEncryption()
{
try
{
for (int i = 0; i < 100; i++)
{
IEncryptor encryptorN;
IEncryptor decryptorN;
encryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
decryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
RunEncryptionRound(encryptorN, decryptorN);
}
}
catch
{
encryptionFailed = true;
throw;
}
//TestEncryptionMethod(typeof(StreamTableNativeEncryptor), "table");
TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4-md5");
}
}
}

Loading…
Cancel
Save