Browse Source

Remove lock in SodiumEncryptor (#754)

- Use separate encrypt/decrypt buffer when creating instances
- Revert 3bc77d212a
tags/3.3.2
破娃酱 Syrone Wong 8 years ago
parent
commit
c7adac5fb0
1 changed files with 45 additions and 45 deletions
  1. +45
    -45
      shadowsocks-csharp/Encryption/SodiumEncryptor.cs

+ 45
- 45
shadowsocks-csharp/Encryption/SodiumEncryptor.cs View File

@@ -12,16 +12,18 @@ namespace Shadowsocks.Encryption
const int SODIUM_BLOCK_SIZE = 64; const int SODIUM_BLOCK_SIZE = 64;
static byte[] sodiumBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
protected int _encryptBytesRemaining; protected int _encryptBytesRemaining;
protected int _decryptBytesRemaining; protected int _decryptBytesRemaining;
protected ulong _encryptIC; protected ulong _encryptIC;
protected ulong _decryptIC; protected ulong _decryptIC;
protected byte[] _encryptBuf;
protected byte[] _decryptBuf;
public SodiumEncryptor(string method, string password, bool onetimeauth, bool isudp) public SodiumEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp) : base(method, password, onetimeauth, isudp)
{ {
_encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
_decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
} }
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> { private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> {
@@ -45,54 +47,52 @@ namespace Shadowsocks.Encryption
// TODO write a unidirection cipher so we don't have to if if if // TODO write a unidirection cipher so we don't have to if if if
int bytesRemaining; int bytesRemaining;
ulong ic; ulong ic;
byte[] sodiumBuf;
byte[] iv; byte[] iv;
// I'm tired. just add a big lock
// let's optimize for RAM instead of CPU
lock(sodiumBuf)
if (isCipher)
{
bytesRemaining = _encryptBytesRemaining;
ic = _encryptIC;
sodiumBuf = _encryptBuf;
iv = _encryptIV;
}
else
{ {
if (isCipher)
{
bytesRemaining = _encryptBytesRemaining;
ic = _encryptIC;
iv = _encryptIV;
}
else
{
bytesRemaining = _decryptBytesRemaining;
ic = _decryptIC;
iv = _decryptIV;
}
int padding = bytesRemaining;
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
bytesRemaining = _decryptBytesRemaining;
ic = _decryptIC;
sodiumBuf = _decryptBuf;
iv = _decryptIV;
}
int padding = bytesRemaining;
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
switch (_cipher)
{
case CIPHER_SALSA20:
Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20:
Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20_IETF:
Sodium.crypto_stream_chacha20_ietf_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, (uint)ic, _key);
break;
}
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
padding += length;
ic += (ulong)padding / SODIUM_BLOCK_SIZE;
bytesRemaining = padding % SODIUM_BLOCK_SIZE;
switch (_cipher)
{
case CIPHER_SALSA20:
Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20:
Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20_IETF:
Sodium.crypto_stream_chacha20_ietf_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, (uint)ic, _key);
break;
}
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
padding += length;
ic += (ulong)padding / SODIUM_BLOCK_SIZE;
bytesRemaining = padding % SODIUM_BLOCK_SIZE;
if (isCipher)
{
_encryptBytesRemaining = bytesRemaining;
_encryptIC = ic;
}
else
{
_decryptBytesRemaining = bytesRemaining;
_decryptIC = ic;
}
if (isCipher)
{
_encryptBytesRemaining = bytesRemaining;
_encryptIC = ic;
}
else
{
_decryptBytesRemaining = bytesRemaining;
_decryptIC = ic;
} }
} }


Loading…
Cancel
Save