@@ -0,0 +1,75 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using NaCl.Core; | |||
using NaCl.Core.Base; | |||
namespace Shadowsocks.Encryption.AEAD | |||
{ | |||
public class AEADNaClEncryptor : AEADEncryptor | |||
{ | |||
SnufflePoly1305 enc; | |||
SnufflePoly1305 dec; | |||
public AEADNaClEncryptor(string method, string password) : base(method, password) | |||
{ | |||
} | |||
public override void InitCipher(byte[] salt, bool isEncrypt, bool isUdp) | |||
{ | |||
base.InitCipher(salt, isEncrypt, isUdp); | |||
DeriveSessionKey(isEncrypt ? _encryptSalt : _decryptSalt, | |||
_Masterkey, _sessionKey); | |||
SnufflePoly1305 tmp; | |||
switch (_cipher) | |||
{ | |||
default: | |||
case CipherChaCha20Poly1305: | |||
tmp = new ChaCha20Poly1305(_sessionKey); | |||
break; | |||
case CipherXChaCha20Poly1305: | |||
tmp = new XChaCha20Poly1305(_sessionKey); | |||
break; | |||
} | |||
if (isEncrypt) enc = tmp; | |||
else dec = tmp; | |||
} | |||
public override void cipherDecrypt(byte[] ciphertext, uint clen, byte[] plaintext, ref uint plen) | |||
{ | |||
var pt = dec.Decrypt(ciphertext, null, _decNonce); | |||
pt.CopyTo(plaintext, 0); | |||
plen = (uint)pt.Length; | |||
} | |||
public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen) | |||
{ | |||
var ct = enc.Encrypt(plaintext, null, _encNonce); | |||
ct.CopyTo(ciphertext, 0); | |||
clen = (uint)ct.Length; | |||
} | |||
public override void Dispose() | |||
{ | |||
} | |||
const int CipherChaCha20Poly1305 = 1; | |||
const int CipherXChaCha20Poly1305 = 2; | |||
private static readonly Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> | |||
{ | |||
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, 1)}, | |||
{"xchacha20-ietf-poly1305", new EncryptorInfo(32, 32, 24, 16, 2)}, | |||
//{"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)}, | |||
}; | |||
protected override Dictionary<string, EncryptorInfo> getCiphers() | |||
{ | |||
return _ciphers; | |||
} | |||
} | |||
} |
@@ -5,8 +5,13 @@ | |||
<package id="Costura.Fody" version="3.3.3" targetFramework="net472" /> | |||
<package id="Fody" version="4.2.1" targetFramework="net472" developmentDependency="true" /> | |||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" /> | |||
<package id="NaCl.Core" version="1.2.0" targetFramework="net472" /> | |||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" /> | |||
<package id="NLog" version="4.6.8" targetFramework="net472" /> | |||
<package id="StringEx.CS" version="0.3.1" targetFramework="net472" developmentDependency="true" /> | |||
<package id="System.Buffers" version="4.4.0" targetFramework="net472" /> | |||
<package id="System.Memory" version="4.5.2" targetFramework="net472" /> | |||
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" /> | |||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" /> | |||
<package id="ZXing.Net" version="0.16.5" targetFramework="net472" /> | |||
</packages> |
@@ -82,6 +82,9 @@ | |||
</Reference> | |||
<Reference Include="Microsoft.CSharp" /> | |||
<Reference Include="Microsoft.VisualBasic" /> | |||
<Reference Include="NaCl.Core, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\NaCl.Core.1.2.0\lib\net47\NaCl.Core.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
</Reference> | |||
@@ -90,13 +93,26 @@ | |||
</Reference> | |||
<Reference Include="PresentationCore" /> | |||
<Reference Include="System" /> | |||
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Configuration" /> | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Data.DataSetExtensions" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.IO.Compression" /> | |||
<Reference Include="System.Management" /> | |||
<Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Net" /> | |||
<Reference Include="System.Numerics" /> | |||
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.Serialization" /> | |||
<Reference Include="System.ServiceModel" /> | |||
<Reference Include="System.Transactions" /> | |||
@@ -120,10 +136,12 @@ | |||
<Compile Include="Encryption\AEAD\AEADBouncyCastleEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADNaClEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADNativeEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADOpenSSLEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADSodiumEncryptor.cs" /> | |||
<Compile Include="Encryption\CircularBuffer\ByteCircularBuffer.cs" /> | |||
<Compile Include="Encryption\CryptoUtils.cs" /> | |||
<Compile Include="Encryption\EncryptorBase.cs" /> | |||
<Compile Include="Encryption\EncryptorFactory.cs" /> | |||
<Compile Include="Encryption\Exception\CryptoException.cs" /> | |||
@@ -310,6 +310,72 @@ namespace Shadowsocks.Test | |||
Assert.IsFalse(encryptionFailed); | |||
} | |||
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!"); | |||
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); | |||
} | |||
} | |||
catch | |||
{ | |||
encryptionFailed = true; | |||
throw; | |||
} | |||
} | |||
[TestMethod] | |||
public void TesNaClAEADEncryption() | |||
{ | |||
encryptionFailed = false; | |||
// run it once before the multi-threading test to initialize global tables | |||
RunSingleNaClAEADEncryptionThread(); | |||
List<Thread> threads = new List<Thread>(); | |||
for (int i = 0; i < 10; i++) | |||
{ | |||
Thread t = new Thread(new ThreadStart(RunSingleNaClAEADEncryptionThread)); threads.Add(t); | |||
t.Start(); | |||
} | |||
foreach (Thread t in threads) | |||
{ | |||
t.Join(); | |||
} | |||
RNG.Close(); | |||
Assert.IsFalse(encryptionFailed); | |||
} | |||
private void RunSingleNaClAEADEncryptionThread() | |||
{ | |||
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; | |||
} | |||
} | |||
[TestMethod] | |||
public void TestNativeEncryption() | |||
{ | |||
@@ -357,29 +423,6 @@ namespace Shadowsocks.Test | |||
} | |||
} | |||
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!"); | |||
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); | |||
} | |||
} | |||
catch | |||
{ | |||
encryptionFailed = true; | |||
throw; | |||
} | |||
} | |||
[TestMethod] | |||
public void TestOpenSSLAEADEncryption() | |||
{ | |||