From af405a668ad0d8541953b79eedb0485605b5169f Mon Sep 17 00:00:00 2001 From: Student Main Date: Sat, 28 Mar 2020 16:12:09 +0800 Subject: [PATCH] doc, lint --- README.md | 23 +++++++-------- .../AEAD/AEADAesGcmNativeEncryptor.cs | 11 +++----- .../Encryption/AEAD/AEADEncryptor.cs | 28 +++++++++++++------ .../Encryption/AEAD/AEADNaClEncryptor.cs | 15 ++++------ shadowsocks-csharp/Encryption/CipherInfo.cs | 16 ++++++++--- shadowsocks-csharp/Encryption/CryptoUtils.cs | 11 ++++++-- .../Stream/ExtendedCfbBlockCipher.cs | 23 ++++++--------- .../Stream/StreamAesBouncyCastleEncryptor.cs | 24 ++++++++-------- .../Stream/StreamChachaNaClEncryptor.cs | 3 ++ .../Encryption/Stream/StreamEncryptor.cs | 22 +++++++++++---- .../Stream/StreamPlainNativeEncryptor.cs | 2 -- 11 files changed, 103 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 6612822d..d881e017 100644 --- a/README.md +++ b/README.md @@ -125,17 +125,18 @@ especially for feature development. #### 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 ``` diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs index 6add700c..363da9db 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADAesGcmNativeEncryptor.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; namespace Shadowsocks.Encryption.AEAD { @@ -34,7 +31,7 @@ namespace Shadowsocks.Encryption.AEAD public override int CipherEncrypt(Span plain, Span 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)); return plain.Length + tagLen; } @@ -42,9 +39,9 @@ namespace Shadowsocks.Encryption.AEAD public override int CipherDecrypt(Span plain, Span cipher) { 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 ciphertxt = cipher.Slice(0, clen); + Span tag = cipher.Slice(clen); aes.Decrypt(nonce.AsSpan(), ciphertxt, tag, plain.Slice(0, clen)); return clen; } diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs index f53f3340..1a2151cf 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs @@ -1,11 +1,11 @@ using NLog; +using Shadowsocks.Controller; +using Shadowsocks.Encryption.Exception; +using Shadowsocks.Encryption.Stream; using System; using System.Collections.Generic; using System.Net; using System.Text; -using Shadowsocks.Controller; -using Shadowsocks.Encryption.Exception; -using Shadowsocks.Encryption.Stream; namespace Shadowsocks.Encryption.AEAD { @@ -48,7 +48,7 @@ namespace Shadowsocks.Encryption.AEAD { CipherInfo = getCiphers()[method.ToLower()]; cipherFamily = CipherInfo.Type; - var parameter = (AEADCipherParameter)CipherInfo.CipherParameter; + AEADCipherParameter parameter = (AEADCipherParameter)CipherInfo.CipherParameter; keyLen = parameter.KeySize; saltLen = parameter.SaltSize; tagLen = parameter.TagSize; @@ -65,8 +65,16 @@ namespace Shadowsocks.Encryption.AEAD { byte[] passbuf = Encoding.UTF8.GetBytes(password); // 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); // init session key sessionKey = new byte[keyLen]; @@ -142,8 +150,12 @@ namespace Shadowsocks.Encryption.AEAD { // calculate next chunk size 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 byte[] chunkBytes = tmp.Slice(0, chunklength).ToArray(); tmp = tmp.Slice(chunklength); diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs index 6e956420..d7579af6 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs @@ -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 System; +using System.Collections.Generic; namespace Shadowsocks.Encryption.AEAD { @@ -48,17 +45,17 @@ namespace Shadowsocks.Encryption.AEAD break; } } - + public override int CipherEncrypt(Span plain, Span cipher) { - var ct = enc.Encrypt(plain, null, nonce); + byte[] ct = enc.Encrypt(plain, null, nonce); ct.CopyTo(cipher); return ct.Length; } public override int CipherDecrypt(Span plain, Span cipher) { - var pt = enc.Decrypt(cipher, null, nonce); + byte[] pt = enc.Decrypt(cipher, null, nonce); pt.CopyTo(plain); return pt.Length; } diff --git a/shadowsocks-csharp/Encryption/CipherInfo.cs b/shadowsocks-csharp/Encryption/CipherInfo.cs index 8f4c2ebe..210a4027 100644 --- a/shadowsocks-csharp/Encryption/CipherInfo.cs +++ b/shadowsocks-csharp/Encryption/CipherInfo.cs @@ -1,5 +1,4 @@ using Shadowsocks.Controller; -using System; namespace Shadowsocks.Encryption { @@ -37,7 +36,10 @@ namespace Shadowsocks.Encryption public class StreamCipherParameter : CipherParameter { 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 @@ -45,7 +47,10 @@ namespace Shadowsocks.Encryption public int SaltSize; public int TagSize; 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 @@ -95,7 +100,10 @@ namespace Shadowsocks.Encryption } public string ToString(bool verbose) { - if (!verbose) return ToString(); + if (!verbose) + { + return ToString(); + } return $"{Name} {StandardState} {CipherParameter}"; } diff --git a/shadowsocks-csharp/Encryption/CryptoUtils.cs b/shadowsocks-csharp/Encryption/CryptoUtils.cs index 1a31a84e..0cf5c8db 100644 --- a/shadowsocks-csharp/Encryption/CryptoUtils.cs +++ b/shadowsocks-csharp/Encryption/CryptoUtils.cs @@ -54,7 +54,10 @@ namespace Shadowsocks.Encryption bool o = true; // overflow flag for (int i = 0; i < salt.Length; i++) { - if (!o) continue; + if (!o) + { + continue; + } salt[i]++; o = salt[i] == 0; @@ -66,7 +69,11 @@ namespace Shadowsocks.Encryption bool o = true; // overflow flag for (int i = 0; i < salt.Length; i++) { - if (!o) continue; + if (!o) + { + continue; + } + salt[i]++; o = salt[i] == 0; } diff --git a/shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs b/shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs index 013e73b2..322b9c4c 100644 --- a/shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs +++ b/shadowsocks-csharp/Encryption/Stream/ExtendedCfbBlockCipher.cs @@ -2,9 +2,8 @@ // changes: 5th parameter for ProcessBlock, to process without change internal state -using System; - using Org.BouncyCastle.Crypto.Parameters; +using System; namespace Org.BouncyCastle.Crypto.Modes { @@ -34,10 +33,10 @@ namespace Org.BouncyCastle.Crypto.Modes int bitBlockSize) { 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. @@ -63,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Modes bool forEncryption, ICipherParameters parameters) { - this.encrypting = forEncryption; + encrypting = forEncryption; if (parameters is ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)parameters; @@ -89,15 +88,9 @@ namespace Org.BouncyCastle.Crypto.Modes * @return the name of the underlying algorithm followed by "/CFB" * 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. diff --git a/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs index 02cba4ca..b602b045 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs @@ -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.Parameters; -using Org.BouncyCastle.Security; using System; using System.Collections.Generic; @@ -13,12 +11,10 @@ namespace Shadowsocks.Encryption.Stream { byte[] cfbBuf = new byte[MaxInputSize + 128]; int ptr = 0; - //ExtendedCfbBufferedBlockCipher c; - ExtendedCfbBlockCipher b; + readonly ExtendedCfbBlockCipher b; public StreamAesBouncyCastleEncryptor(string method, string password) : base(method, password) { b = new ExtendedCfbBlockCipher(new AesEngine(), 128); - // c = new ExtendedCfbBufferedBlockCipher(b); } protected override void initCipher(byte[] iv, bool isEncrypt) @@ -59,14 +55,18 @@ namespace Shadowsocks.Encryption.Stream tmp.CopyTo(ob.Slice(readPtr)); 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); ptr = restSize; - - } #region Cipher Info diff --git a/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs index 148fb7a1..8fd3512d 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs @@ -9,6 +9,9 @@ namespace Shadowsocks.Encryption.Stream const int BlockSize = 64; // 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 + + // 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 // and update it, ignore other data, get it in correct offset... diff --git a/shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs index e03c5860..604be0ca 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs @@ -29,7 +29,7 @@ namespace Shadowsocks.Encryption.Stream { CipherInfo = getCiphers()[method.ToLower()]; cipherFamily = CipherInfo.Type; - var parameter = (StreamCipherParameter)CipherInfo.CipherParameter; + StreamCipherParameter parameter = (StreamCipherParameter)CipherInfo.CipherParameter; keyLen = parameter.KeySize; ivLen = parameter.IvSize; @@ -44,7 +44,11 @@ namespace Shadowsocks.Encryption.Stream { byte[] passbuf = Encoding.UTF8.GetBytes(password); 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); } @@ -72,7 +76,11 @@ namespace Shadowsocks.Encryption.Stream protected virtual void initCipher(byte[] iv, bool isEncrypt) { - if (ivLen == 0) return; + if (ivLen == 0) + { + return; + } + this.iv = new byte[ivLen]; Array.Copy(iv, this.iv, ivLen); } @@ -115,7 +123,7 @@ namespace Shadowsocks.Encryption.Stream { Span tmp = buf.AsSpan(0, length); logger.Trace($"{instanceId} decrypt TCP, read iv: {!ivReady}"); - + // is first packet, need read iv if (!ivReady) { @@ -137,7 +145,11 @@ namespace Shadowsocks.Encryption.Stream byte[] iv = sharedBuffer.AsSpan(0, ivLen).ToArray(); initCipher(iv, false); } - else initCipher(Array.Empty(), false); + else + { + initCipher(Array.Empty(), false); + } + tmp = sharedBuffer.AsSpan(ivLen, recieveCtr - ivLen); } diff --git a/shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs index 5bd10946..d560b4bb 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamPlainNativeEncryptor.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Text; namespace Shadowsocks.Encryption.Stream {