diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index 10200e0b..e900a782 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/AEAD/AEADSodiumEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs index 1cce0fa0..c78e5322 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs @@ -10,6 +10,7 @@ namespace Shadowsocks.Encryption.AEAD : AEADEncryptor, IDisposable { private const int CIPHER_CHACHA20IETFPOLY1305 = 1; + private const int CIPHER_AES256GCM = 2; private byte[] _sodiumEncSubkey; private byte[] _sodiumDecSubkey; @@ -24,6 +25,7 @@ namespace Shadowsocks.Encryption.AEAD private static Dictionary _ciphers = new Dictionary { {"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)}, + {"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)}, }; public static List SupportedCiphers() @@ -63,6 +65,13 @@ namespace Shadowsocks.Encryption.AEAD null, _encNonce, _sodiumEncSubkey); break; + case CIPHER_AES256GCM: + ret = Sodium.crypto_aead_aes256gcm_encrypt(ciphertext, ref encClen, + plaintext, (ulong)plen, + null, 0, + null, _encNonce, + _sodiumEncSubkey); + break; default: throw new System.Exception("not implemented"); } @@ -91,6 +100,13 @@ namespace Shadowsocks.Encryption.AEAD null, 0, _decNonce, _sodiumDecSubkey); break; + case CIPHER_AES256GCM: + ret = Sodium.crypto_aead_aes256gcm_decrypt(plaintext, ref decPlen, + null, + ciphertext, (ulong)clen, + null, 0, + _decNonce, _sodiumDecSubkey); + break; default: throw new System.Exception("not implemented"); } diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index 331570fd..35e03dc0 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -14,6 +14,18 @@ namespace Shadowsocks.Encryption static EncryptorFactory() { + var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers(); + var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers(); + if (Sodium.AES256GCMAvailable) + { + // prefer to aes-256-gcm in libsodium + AEADMbedTLSEncryptorSupportedCiphers.Remove("aes-256-gcm"); + } + else + { + AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm"); + } + foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers()) { _registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor)); @@ -22,11 +34,11 @@ namespace Shadowsocks.Encryption { _registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor)); } - foreach (string method in AEADMbedTLSEncryptor.SupportedCiphers()) + foreach (string method in AEADMbedTLSEncryptorSupportedCiphers) { _registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor)); } - foreach (string method in AEADSodiumEncryptor.SupportedCiphers()) + foreach (string method in AEADSodiumEncryptorSupportedCiphers) { _registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor)); } diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index 5cc853ad..8ab29762 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -14,6 +14,8 @@ namespace Shadowsocks.Encryption private static bool _initialized = false; private static readonly object _initLock = new object(); + public static bool AES256GCMAvailable { get; private set; } = false; + static Sodium() { string dllPath = Utils.GetTempPath(DLLNAME); @@ -42,6 +44,9 @@ namespace Shadowsocks.Encryption { _initialized = true; } + + AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1; + Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}"); } } } @@ -52,6 +57,9 @@ namespace Shadowsocks.Encryption [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] private static extern int sodium_init(); + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + private static extern int crypto_aead_aes256gcm_is_available(); + #region AEAD [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] @@ -65,6 +73,14 @@ namespace Shadowsocks.Encryption public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p, byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k); + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public static extern int crypto_aead_aes256gcm_encrypt(byte[] c, ref ulong clen_p, byte[] m, ulong mlen, + byte[] ad, ulong adlen, byte[] nsec, byte[] npub, byte[] k); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public static extern int crypto_aead_aes256gcm_decrypt(byte[] m, ref ulong mlen_p, byte[] nsec, byte[] c, + ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k); + #endregion #region Stream