@@ -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="Costura.Fody" version="3.3.3" targetFramework="net472" /> | ||||
<package id="Fody" version="4.2.1" targetFramework="net472" developmentDependency="true" /> | <package id="Fody" version="4.2.1" targetFramework="net472" developmentDependency="true" /> | ||||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" /> | <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="Newtonsoft.Json" version="12.0.2" targetFramework="net472" /> | ||||
<package id="NLog" version="4.6.8" 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="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" /> | <package id="ZXing.Net" version="0.16.5" targetFramework="net472" /> | ||||
</packages> | </packages> |
@@ -82,6 +82,9 @@ | |||||
</Reference> | </Reference> | ||||
<Reference Include="Microsoft.CSharp" /> | <Reference Include="Microsoft.CSharp" /> | ||||
<Reference Include="Microsoft.VisualBasic" /> | <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"> | <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> | <HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | ||||
</Reference> | </Reference> | ||||
@@ -90,13 +93,26 @@ | |||||
</Reference> | </Reference> | ||||
<Reference Include="PresentationCore" /> | <Reference Include="PresentationCore" /> | ||||
<Reference Include="System" /> | <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.Configuration" /> | ||||
<Reference Include="System.Data" /> | <Reference Include="System.Data" /> | ||||
<Reference Include="System.Data.DataSetExtensions" /> | <Reference Include="System.Data.DataSetExtensions" /> | ||||
<Reference Include="System.Drawing" /> | <Reference Include="System.Drawing" /> | ||||
<Reference Include="System.IO.Compression" /> | <Reference Include="System.IO.Compression" /> | ||||
<Reference Include="System.Management" /> | <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.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.Runtime.Serialization" /> | ||||
<Reference Include="System.ServiceModel" /> | <Reference Include="System.ServiceModel" /> | ||||
<Reference Include="System.Transactions" /> | <Reference Include="System.Transactions" /> | ||||
@@ -120,10 +136,12 @@ | |||||
<Compile Include="Encryption\AEAD\AEADBouncyCastleEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADBouncyCastleEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADNaClEncryptor.cs" /> | |||||
<Compile Include="Encryption\AEAD\AEADNativeEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADNativeEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADOpenSSLEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADOpenSSLEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADSodiumEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADSodiumEncryptor.cs" /> | ||||
<Compile Include="Encryption\CircularBuffer\ByteCircularBuffer.cs" /> | <Compile Include="Encryption\CircularBuffer\ByteCircularBuffer.cs" /> | ||||
<Compile Include="Encryption\CryptoUtils.cs" /> | |||||
<Compile Include="Encryption\EncryptorBase.cs" /> | <Compile Include="Encryption\EncryptorBase.cs" /> | ||||
<Compile Include="Encryption\EncryptorFactory.cs" /> | <Compile Include="Encryption\EncryptorFactory.cs" /> | ||||
<Compile Include="Encryption\Exception\CryptoException.cs" /> | <Compile Include="Encryption\Exception\CryptoException.cs" /> | ||||
@@ -310,6 +310,72 @@ namespace Shadowsocks.Test | |||||
Assert.IsFalse(encryptionFailed); | 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] | [TestMethod] | ||||
public void TestNativeEncryption() | 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] | [TestMethod] | ||||
public void TestOpenSSLAEADEncryption() | public void TestOpenSSLAEADEncryption() | ||||
{ | { | ||||