Browse Source

doc, lint

pull/2865/head
Student Main 5 years ago
parent
commit
af405a668a
11 changed files with 103 additions and 75 deletions
  1. +12
    -11
      README.md
  2. +4
    -7
      shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs
  3. +20
    -8
      shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs
  4. +6
    -9
      shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs
  5. +12
    -4
      shadowsocks-csharp/Encryption/CipherInfo.cs
  6. +9
    -2
      shadowsocks-csharp/Encryption/CryptoUtils.cs
  7. +8
    -15
      shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs
  8. +12
    -12
      shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs
  9. +3
    -0
      shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs
  10. +17
    -5
      shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs
  11. +0
    -2
      shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs

+ 12
- 11
README.md View File

@@ -125,17 +125,18 @@ especially for feature development.
#### Open Source Components / Libraries #### Open Source Components / Libraries
``` ```
Caseless.Fody (MIT) https://github.com/Fody/Caseless
Costura.Fody (MIT) https://github.com/Fody/Costura
Fody (MIT) https://github.com/Fody/Fody
GlobalHotKey (GPLv3) https://github.com/kirmir/GlobalHotKey
Newtonsoft.Json (MIT) https://www.newtonsoft.com/json
StringEx.CS () https://github.com/LazyMode/StringEx
ZXing.Net (Apache 2.0) https://github.com/micjahn/ZXing.Net
libsscrypto (GPLv2) https://github.com/shadowsocks/libsscrypto
Privoxy (GPLv2) https://www.privoxy.org
Sysproxy () https://github.com/Noisyfox/sysproxy
Caseless.Fody (MIT) https://github.com/Fody/Caseless
Costura.Fody (MIT) https://github.com/Fody/Costura
Fody (MIT) https://github.com/Fody/Fody
GlobalHotKey (GPLv3) https://github.com/kirmir/GlobalHotKey
Newtonsoft.Json (MIT) https://www.newtonsoft.com/json
StringEx.CS () https://github.com/LazyMode/StringEx
ZXing.Net (Apache 2.0) https://github.com/micjahn/ZXing.Net
BouncyCastle.NetCore (MIT) https://github.com/chrishaly/bc-csharp
NaCl.Core (MIT) https://github.com/idaviddesmet/NaCl.Core
Privoxy (GPLv2) https://www.privoxy.org
Sysproxy () https://github.com/Noisyfox/sysproxy
``` ```


+ 4
- 7
shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs View File

@@ -1,9 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;


namespace Shadowsocks.Encryption.AEAD namespace Shadowsocks.Encryption.AEAD
{ {
@@ -34,7 +31,7 @@ namespace Shadowsocks.Encryption.AEAD


public override int CipherEncrypt(Span<byte> plain, Span<byte> cipher) public override int CipherEncrypt(Span<byte> plain, Span<byte> cipher)
{ {
using var aes = new AesGcm(sessionKey);
using AesGcm aes = new AesGcm(sessionKey);
aes.Encrypt(nonce.AsSpan(), plain, cipher.Slice(0, plain.Length), cipher.Slice(plain.Length, tagLen)); aes.Encrypt(nonce.AsSpan(), plain, cipher.Slice(0, plain.Length), cipher.Slice(plain.Length, tagLen));
return plain.Length + tagLen; return plain.Length + tagLen;
} }
@@ -42,9 +39,9 @@ namespace Shadowsocks.Encryption.AEAD
public override int CipherDecrypt(Span<byte> plain, Span<byte> cipher) public override int CipherDecrypt(Span<byte> plain, Span<byte> cipher)
{ {
int clen = cipher.Length - tagLen; int clen = cipher.Length - tagLen;
using var aes = new AesGcm(sessionKey);
var ciphertxt = cipher.Slice(0, clen);
var tag = cipher.Slice(clen);
using AesGcm aes = new AesGcm(sessionKey);
Span<byte> ciphertxt = cipher.Slice(0, clen);
Span<byte> tag = cipher.Slice(clen);
aes.Decrypt(nonce.AsSpan(), ciphertxt, tag, plain.Slice(0, clen)); aes.Decrypt(nonce.AsSpan(), ciphertxt, tag, plain.Slice(0, clen));
return clen; return clen;
} }


+ 20
- 8
shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs View File

@@ -1,11 +1,11 @@
using NLog; using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Encryption.Exception;
using Shadowsocks.Encryption.Stream;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Text; using System.Text;
using Shadowsocks.Controller;
using Shadowsocks.Encryption.Exception;
using Shadowsocks.Encryption.Stream;
namespace Shadowsocks.Encryption.AEAD namespace Shadowsocks.Encryption.AEAD
{ {
@@ -48,7 +48,7 @@ namespace Shadowsocks.Encryption.AEAD
{ {
CipherInfo = getCiphers()[method.ToLower()]; CipherInfo = getCiphers()[method.ToLower()];
cipherFamily = CipherInfo.Type; cipherFamily = CipherInfo.Type;
var parameter = (AEADCipherParameter)CipherInfo.CipherParameter;
AEADCipherParameter parameter = (AEADCipherParameter)CipherInfo.CipherParameter;
keyLen = parameter.KeySize; keyLen = parameter.KeySize;
saltLen = parameter.SaltSize; saltLen = parameter.SaltSize;
tagLen = parameter.TagSize; tagLen = parameter.TagSize;
@@ -65,8 +65,16 @@ namespace Shadowsocks.Encryption.AEAD
{ {
byte[] passbuf = Encoding.UTF8.GetBytes(password); byte[] passbuf = Encoding.UTF8.GetBytes(password);
// init master key // init master key
if (masterKey == null) masterKey = new byte[keyLen];
if (masterKey.Length != keyLen) Array.Resize(ref masterKey, keyLen);
if (masterKey == null)
{
masterKey = new byte[keyLen];
}
if (masterKey.Length != keyLen)
{
Array.Resize(ref masterKey, keyLen);
}
DeriveKey(passbuf, masterKey, keyLen); DeriveKey(passbuf, masterKey, keyLen);
// init session key // init session key
sessionKey = new byte[keyLen]; sessionKey = new byte[keyLen];
@@ -142,8 +150,12 @@ namespace Shadowsocks.Encryption.AEAD
{ {
// calculate next chunk size // calculate next chunk size
int bufSize = tmp.Length; int bufSize = tmp.Length;
if (bufSize <= 0) return;
var chunklength = (int)Math.Min(bufSize, ChunkLengthMask);
if (bufSize <= 0)
{
return;
}
int chunklength = (int)Math.Min(bufSize, ChunkLengthMask);
// read next chunk // read next chunk
byte[] chunkBytes = tmp.Slice(0, chunklength).ToArray(); byte[] chunkBytes = tmp.Slice(0, chunklength).ToArray();
tmp = tmp.Slice(chunklength); tmp = tmp.Slice(chunklength);


+ 6
- 9
shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NaCl.Core;
using NaCl.Core;
using NaCl.Core.Base; using NaCl.Core.Base;
using System;
using System.Collections.Generic;


namespace Shadowsocks.Encryption.AEAD namespace Shadowsocks.Encryption.AEAD
{ {
@@ -48,17 +45,17 @@ namespace Shadowsocks.Encryption.AEAD
break; break;
} }
} }
public override int CipherEncrypt(Span<byte> plain, Span<byte> cipher) public override int CipherEncrypt(Span<byte> plain, Span<byte> cipher)
{ {
var ct = enc.Encrypt(plain, null, nonce);
byte[] ct = enc.Encrypt(plain, null, nonce);
ct.CopyTo(cipher); ct.CopyTo(cipher);
return ct.Length; return ct.Length;
} }


public override int CipherDecrypt(Span<byte> plain, Span<byte> cipher) public override int CipherDecrypt(Span<byte> plain, Span<byte> cipher)
{ {
var pt = enc.Decrypt(cipher, null, nonce);
byte[] pt = enc.Decrypt(cipher, null, nonce);
pt.CopyTo(plain); pt.CopyTo(plain);
return pt.Length; return pt.Length;
} }


+ 12
- 4
shadowsocks-csharp/Encryption/CipherInfo.cs View File

@@ -1,5 +1,4 @@
using Shadowsocks.Controller; using Shadowsocks.Controller;
using System;


namespace Shadowsocks.Encryption namespace Shadowsocks.Encryption
{ {
@@ -37,7 +36,10 @@ namespace Shadowsocks.Encryption
public class StreamCipherParameter : CipherParameter public class StreamCipherParameter : CipherParameter
{ {
public int IvSize; public int IvSize;
public override string ToString() => $"stream (key:{KeySize * 8}, iv:{IvSize * 8})";
public override string ToString()
{
return $"stream (key:{KeySize * 8}, iv:{IvSize * 8})";
}
} }


public class AEADCipherParameter : CipherParameter public class AEADCipherParameter : CipherParameter
@@ -45,7 +47,10 @@ namespace Shadowsocks.Encryption
public int SaltSize; public int SaltSize;
public int TagSize; public int TagSize;
public int NonceSize; public int NonceSize;
public override string ToString() => $"aead (key:{KeySize * 8}, salt:{SaltSize * 8}, tag:{TagSize * 8}, nonce:{NonceSize * 8})";
public override string ToString()
{
return $"aead (key:{KeySize * 8}, salt:{SaltSize * 8}, tag:{TagSize * 8}, nonce:{NonceSize * 8})";
}
} }


public class CipherInfo public class CipherInfo
@@ -95,7 +100,10 @@ namespace Shadowsocks.Encryption
} }
public string ToString(bool verbose) public string ToString(bool verbose)
{ {
if (!verbose) return ToString();
if (!verbose)
{
return ToString();
}


return $"{Name} {StandardState} {CipherParameter}"; return $"{Name} {StandardState} {CipherParameter}";
} }


+ 9
- 2
shadowsocks-csharp/Encryption/CryptoUtils.cs View File

@@ -54,7 +54,10 @@ namespace Shadowsocks.Encryption
bool o = true; // overflow flag bool o = true; // overflow flag
for (int i = 0; i < salt.Length; i++) for (int i = 0; i < salt.Length; i++)
{ {
if (!o) continue;
if (!o)
{
continue;
}


salt[i]++; salt[i]++;
o = salt[i] == 0; o = salt[i] == 0;
@@ -66,7 +69,11 @@ namespace Shadowsocks.Encryption
bool o = true; // overflow flag bool o = true; // overflow flag
for (int i = 0; i < salt.Length; i++) for (int i = 0; i < salt.Length; i++)
{ {
if (!o) continue;
if (!o)
{
continue;
}

salt[i]++; salt[i]++;
o = salt[i] == 0; o = salt[i] == 0;
} }


+ 8
- 15
shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs View File

@@ -2,9 +2,8 @@
// changes: 5th parameter for ProcessBlock, to process without change internal state // changes: 5th parameter for ProcessBlock, to process without change internal state




using System;

using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using System;


namespace Org.BouncyCastle.Crypto.Modes namespace Org.BouncyCastle.Crypto.Modes
{ {
@@ -34,10 +33,10 @@ namespace Org.BouncyCastle.Crypto.Modes
int bitBlockSize) int bitBlockSize)
{ {
this.cipher = cipher; this.cipher = cipher;
this.blockSize = bitBlockSize / 8;
this.IV = new byte[cipher.GetBlockSize()];
this.cfbV = new byte[cipher.GetBlockSize()];
this.cfbOutV = new byte[cipher.GetBlockSize()];
blockSize = bitBlockSize / 8;
IV = new byte[cipher.GetBlockSize()];
cfbV = new byte[cipher.GetBlockSize()];
cfbOutV = new byte[cipher.GetBlockSize()];
} }
/** /**
* return the underlying block cipher that we are wrapping. * return the underlying block cipher that we are wrapping.
@@ -63,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Modes
bool forEncryption, bool forEncryption,
ICipherParameters parameters) ICipherParameters parameters)
{ {
this.encrypting = forEncryption;
encrypting = forEncryption;
if (parameters is ParametersWithIV) if (parameters is ParametersWithIV)
{ {
ParametersWithIV ivParam = (ParametersWithIV)parameters; ParametersWithIV ivParam = (ParametersWithIV)parameters;
@@ -89,15 +88,9 @@ namespace Org.BouncyCastle.Crypto.Modes
* @return the name of the underlying algorithm followed by "/CFB" * @return the name of the underlying algorithm followed by "/CFB"
* and the block size in bits. * and the block size in bits.
*/ */
public string AlgorithmName
{
get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); }
}
public string AlgorithmName => cipher.AlgorithmName + "/CFB" + (blockSize * 8);


public bool IsPartialBlockOkay
{
get { return true; }
}
public bool IsPartialBlockOkay => true;


/** /**
* return the block size we are operating at. * return the block size we are operating at.


+ 12
- 12
shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs View File

@@ -1,8 +1,6 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;


@@ -13,12 +11,10 @@ namespace Shadowsocks.Encryption.Stream
{ {
byte[] cfbBuf = new byte[MaxInputSize + 128]; byte[] cfbBuf = new byte[MaxInputSize + 128];
int ptr = 0; int ptr = 0;
//ExtendedCfbBufferedBlockCipher c;
ExtendedCfbBlockCipher b;
readonly ExtendedCfbBlockCipher b;
public StreamAesBouncyCastleEncryptor(string method, string password) : base(method, password) public StreamAesBouncyCastleEncryptor(string method, string password) : base(method, password)
{ {
b = new ExtendedCfbBlockCipher(new AesEngine(), 128); b = new ExtendedCfbBlockCipher(new AesEngine(), 128);
// c = new ExtendedCfbBufferedBlockCipher(b);
} }


protected override void initCipher(byte[] iv, bool isEncrypt) protected override void initCipher(byte[] iv, bool isEncrypt)
@@ -59,14 +55,18 @@ namespace Shadowsocks.Encryption.Stream
tmp.CopyTo(ob.Slice(readPtr)); tmp.CopyTo(ob.Slice(readPtr));
readPtr += blkSize; readPtr += blkSize;
} }
if (readPtr != blkSize * blkCount) throw new System.Exception();
b.ProcessBlock(cfbBuf, readPtr, tmp, 0, false);
tmp.CopyTo(ob.Slice(readPtr));
Array.Copy(cfbBuf, readPtr, cfbBuf, 0, restSize);
if (restSize != 0)
{
readPtr = blkSize * blkCount;
// process last (partial) block without update state
b.ProcessBlock(cfbBuf, readPtr, tmp, 0, false);
tmp.CopyTo(ob.Slice(readPtr));
// write back the partial block block
Array.Copy(cfbBuf, readPtr, cfbBuf, 0, restSize);
}
// cut correct part to output
ob.Slice(ptr, o.Length).CopyTo(o); ob.Slice(ptr, o.Length).CopyTo(o);
ptr = restSize; ptr = restSize;


} }


#region Cipher Info #region Cipher Info


+ 3
- 0
shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs View File

@@ -9,6 +9,9 @@ namespace Shadowsocks.Encryption.Stream
const int BlockSize = 64; const int BlockSize = 64;
// tcp is stream, which can split into chunks at unexpected position... // tcp is stream, which can split into chunks at unexpected position...
// so we need some special handling, as we can't read all data before encrypt // so we need some special handling, as we can't read all data before encrypt
// we did it in AEADEncryptor.cs for AEAD, it can operate at block level
// but we need do it ourselves in stream cipher.


// when new data arrive, put it on correct offset // when new data arrive, put it on correct offset
// and update it, ignore other data, get it in correct offset... // and update it, ignore other data, get it in correct offset...


+ 17
- 5
shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs View File

@@ -29,7 +29,7 @@ namespace Shadowsocks.Encryption.Stream
{ {
CipherInfo = getCiphers()[method.ToLower()]; CipherInfo = getCiphers()[method.ToLower()];
cipherFamily = CipherInfo.Type; cipherFamily = CipherInfo.Type;
var parameter = (StreamCipherParameter)CipherInfo.CipherParameter;
StreamCipherParameter parameter = (StreamCipherParameter)CipherInfo.CipherParameter;
keyLen = parameter.KeySize; keyLen = parameter.KeySize;
ivLen = parameter.IvSize; ivLen = parameter.IvSize;
@@ -44,7 +44,11 @@ namespace Shadowsocks.Encryption.Stream
{ {
byte[] passbuf = Encoding.UTF8.GetBytes(password); byte[] passbuf = Encoding.UTF8.GetBytes(password);
key ??= new byte[keyLen]; key ??= new byte[keyLen];
if (key.Length != keyLen) Array.Resize(ref key, keyLen);
if (key.Length != keyLen)
{
Array.Resize(ref key, keyLen);
}
LegacyDeriveKey(passbuf, key, keyLen); LegacyDeriveKey(passbuf, key, keyLen);
} }
@@ -72,7 +76,11 @@ namespace Shadowsocks.Encryption.Stream
protected virtual void initCipher(byte[] iv, bool isEncrypt) protected virtual void initCipher(byte[] iv, bool isEncrypt)
{ {
if (ivLen == 0) return;
if (ivLen == 0)
{
return;
}
this.iv = new byte[ivLen]; this.iv = new byte[ivLen];
Array.Copy(iv, this.iv, ivLen); Array.Copy(iv, this.iv, ivLen);
} }
@@ -115,7 +123,7 @@ namespace Shadowsocks.Encryption.Stream
{ {
Span<byte> tmp = buf.AsSpan(0, length); Span<byte> tmp = buf.AsSpan(0, length);
logger.Trace($"{instanceId} decrypt TCP, read iv: {!ivReady}"); logger.Trace($"{instanceId} decrypt TCP, read iv: {!ivReady}");
// is first packet, need read iv // is first packet, need read iv
if (!ivReady) if (!ivReady)
{ {
@@ -137,7 +145,11 @@ namespace Shadowsocks.Encryption.Stream
byte[] iv = sharedBuffer.AsSpan(0, ivLen).ToArray(); byte[] iv = sharedBuffer.AsSpan(0, ivLen).ToArray();
initCipher(iv, false); initCipher(iv, false);
} }
else initCipher(Array.Empty<byte>(), false);
else
{
initCipher(Array.Empty<byte>(), false);
}
tmp = sharedBuffer.AsSpan(ivLen, recieveCtr - ivLen); tmp = sharedBuffer.AsSpan(ivLen, recieveCtr - ivLen);
} }


+ 0
- 2
shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs View File

@@ -1,7 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;


namespace Shadowsocks.Encryption.Stream namespace Shadowsocks.Encryption.Stream
{ {


Loading…
Cancel
Save