Browse Source

Add chacha20-ietf-poly1305 and xchacha20-ietf-poly1305

Shadowsocks.Protocol
pull/3084/head
Bruce Wayne 3 years ago
parent
commit
cdfb9f599f
No known key found for this signature in database GPG Key ID: 6D396097F05051BF
9 changed files with 82 additions and 35 deletions
  1. +2
    -2
      Shadowsocks.Protocol/Shadowsocks/AeadClient.cs
  2. +4
    -29
      Shadowsocks.Protocol/Shadowsocks/Crypto/AeadAesGcmCrypto.cs
  3. +13
    -0
      Shadowsocks.Protocol/Shadowsocks/Crypto/AeadChaCha20Poly1305Crypto.cs
  4. +41
    -0
      Shadowsocks.Protocol/Shadowsocks/Crypto/AeadCrypto.cs
  5. +13
    -0
      Shadowsocks.Protocol/Shadowsocks/Crypto/AeadXChaCha20Poly1305Crypto.cs
  6. +2
    -0
      Shadowsocks.Protocol/Shadowsocks/Crypto/CryptoProvider.cs
  7. +4
    -1
      Shadowsocks.Protocol/Shadowsocks/Crypto/UnsafeNoneCrypto.cs
  8. +1
    -1
      Shadowsocks.Protocol/Shadowsocks/ICrypto.cs
  9. +2
    -2
      Shadowsocks.Protocol/Shadowsocks/UnsafeClient.cs

+ 2
- 2
Shadowsocks.Protocol/Shadowsocks/AeadClient.cs View File

@@ -42,7 +42,7 @@ namespace Shadowsocks.Protocol.Shadowsocks


public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server) public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server)
{ {
var up = cryptoParameter.GetCrypto();
using var up = cryptoParameter.GetCrypto();
var pmp = new ProtocolMessagePipe(server); var pmp = new ProtocolMessagePipe(server);
var salt = new SaltMessage(16, true); var salt = new SaltMessage(16, true);
await pmp.WriteAsync(salt); await pmp.WriteAsync(salt);
@@ -77,7 +77,7 @@ namespace Shadowsocks.Protocol.Shadowsocks


public async Task ConvertDownlink(IDuplexPipe client, IDuplexPipe server) public async Task ConvertDownlink(IDuplexPipe client, IDuplexPipe server)
{ {
var down = cryptoParameter.GetCrypto();
using var down = cryptoParameter.GetCrypto();


var pmp = new ProtocolMessagePipe(server); var pmp = new ProtocolMessagePipe(server);
var salt = await pmp.ReadAsync(new SaltMessage(cryptoParameter.KeySize)); var salt = await pmp.ReadAsync(new SaltMessage(cryptoParameter.KeySize));


+ 4
- 29
Shadowsocks.Protocol/Shadowsocks/Crypto/AeadAesGcmCrypto.cs View File

@@ -1,38 +1,13 @@
using System;
using System.Security.Cryptography;
using CryptoBase;


namespace Shadowsocks.Protocol.Shadowsocks.Crypto namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{ {
class AeadAesGcmCrypto : ICrypto
public class AeadAesGcmCrypto : AeadCrypto
{ {
AesGcm aes;

CryptoParameter parameter;
public AeadAesGcmCrypto(CryptoParameter parameter)
public AeadAesGcmCrypto(CryptoParameter parameter) : base(parameter)
{ {
this.parameter = parameter;
} }


public void Init(byte[] key, byte[] iv) => aes = new AesGcm(key);

public int Decrypt(ReadOnlySpan<byte> nonce, Span<byte> plain, ReadOnlySpan<byte> cipher)
{
aes.Decrypt(
nonce,
cipher[0..^parameter.TagSize],
cipher[^parameter.TagSize..],
plain[0..(cipher.Length - parameter.TagSize)]);
return cipher.Length - parameter.TagSize;
}

public int Encrypt(ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> plain, Span<byte> cipher)
{
aes.Encrypt(
nonce,
plain,
cipher[0..plain.Length],
cipher.Slice(plain.Length, parameter.TagSize));
return plain.Length + parameter.TagSize;
}
public override void Init(byte[] key, byte[] iv) => crypto = AEADCryptoCreate.AesGcm(key);
} }
} }

+ 13
- 0
Shadowsocks.Protocol/Shadowsocks/Crypto/AeadChaCha20Poly1305Crypto.cs View File

@@ -0,0 +1,13 @@
using CryptoBase;

namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{
public class AeadChaCha20Poly1305Crypto : AeadCrypto
{
public AeadChaCha20Poly1305Crypto(CryptoParameter parameter) : base(parameter)
{
}

public override void Init(byte[] key, byte[] iv) => crypto = AEADCryptoCreate.ChaCha20Poly1305(key);
}
}

+ 41
- 0
Shadowsocks.Protocol/Shadowsocks/Crypto/AeadCrypto.cs View File

@@ -0,0 +1,41 @@
using CryptoBase.Abstractions.SymmetricCryptos;
using System;

namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{
public abstract class AeadCrypto : ICrypto
{
protected IAEADCrypto? crypto;

private readonly CryptoParameter _parameter;

protected AeadCrypto(CryptoParameter parameter)
{
_parameter = parameter;
}

public abstract void Init(byte[] key, byte[] iv);

public int Decrypt(ReadOnlySpan<byte> nonce, Span<byte> plain, ReadOnlySpan<byte> cipher)
{
crypto!.Decrypt(
nonce,
cipher[..^_parameter.TagSize],
cipher[^_parameter.TagSize..],
plain[..(cipher.Length - _parameter.TagSize)]);
return cipher.Length - _parameter.TagSize;
}

public int Encrypt(ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> plain, Span<byte> cipher)
{
crypto!.Encrypt(
nonce,
plain,
cipher.Slice(0, plain.Length),
cipher.Slice(plain.Length, _parameter.TagSize));
return plain.Length + _parameter.TagSize;
}

public void Dispose() => crypto?.Dispose();
}
}

+ 13
- 0
Shadowsocks.Protocol/Shadowsocks/Crypto/AeadXChaCha20Poly1305Crypto.cs View File

@@ -0,0 +1,13 @@
using CryptoBase;

namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{
public class AeadXChaCha20Poly1305Crypto : AeadCrypto
{
public AeadXChaCha20Poly1305Crypto(CryptoParameter parameter) : base(parameter)
{
}

public override void Init(byte[] key, byte[] iv) => crypto = AEADCryptoCreate.XChaCha20Poly1305(key);
}
}

+ 2
- 0
Shadowsocks.Protocol/Shadowsocks/Crypto/CryptoProvider.cs View File

@@ -7,6 +7,8 @@ namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{ {
static Dictionary<string, CryptoParameter> parameters = new Dictionary<string, CryptoParameter> static Dictionary<string, CryptoParameter> parameters = new Dictionary<string, CryptoParameter>
{ {
["xchacha20-ietf-poly1305"] = new CryptoParameter { KeySize = 32, NonceSize = 24, TagSize = 16, Crypto = typeof(AeadXChaCha20Poly1305Crypto) },
["chacha20-ietf-poly1305"] = new CryptoParameter { KeySize = 32, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadChaCha20Poly1305Crypto) },
["aes-256-gcm"] = new CryptoParameter { KeySize = 32, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) }, ["aes-256-gcm"] = new CryptoParameter { KeySize = 32, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) },
["aes-192-gcm"] = new CryptoParameter { KeySize = 24, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) }, ["aes-192-gcm"] = new CryptoParameter { KeySize = 24, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) },
["aes-128-gcm"] = new CryptoParameter { KeySize = 16, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) }, ["aes-128-gcm"] = new CryptoParameter { KeySize = 16, NonceSize = 12, TagSize = 16, Crypto = typeof(AeadAesGcmCrypto) },


+ 4
- 1
Shadowsocks.Protocol/Shadowsocks/Crypto/UnsafeNoneCrypto.cs View File

@@ -6,7 +6,6 @@ namespace Shadowsocks.Protocol.Shadowsocks.Crypto
{ {
public UnsafeNoneCrypto(CryptoParameter parameter) public UnsafeNoneCrypto(CryptoParameter parameter)
{ {
} }


public int Decrypt(ReadOnlySpan<byte> nonce, Span<byte> plain, ReadOnlySpan<byte> cipher) public int Decrypt(ReadOnlySpan<byte> nonce, Span<byte> plain, ReadOnlySpan<byte> cipher)
@@ -24,5 +23,9 @@ namespace Shadowsocks.Protocol.Shadowsocks.Crypto
public void Init(byte[] key, byte[] iv) public void Init(byte[] key, byte[] iv)
{ {
} }

public void Dispose()
{
}
} }
} }

+ 1
- 1
Shadowsocks.Protocol/Shadowsocks/ICrypto.cs View File

@@ -3,7 +3,7 @@ using System;
namespace Shadowsocks.Protocol.Shadowsocks namespace Shadowsocks.Protocol.Shadowsocks
{ {
// stream cipher simply ignore nonce // stream cipher simply ignore nonce
public interface ICrypto
public interface ICrypto : IDisposable
{ {
void Init(byte[] key, byte[] iv); void Init(byte[] key, byte[] iv);
int Encrypt(ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> plain, Span<byte> cipher); int Encrypt(ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> plain, Span<byte> cipher);


+ 2
- 2
Shadowsocks.Protocol/Shadowsocks/UnsafeClient.cs View File

@@ -24,7 +24,7 @@ namespace Shadowsocks.Protocol.Shadowsocks


public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server) public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server)
{ {
var up = parameter.GetCrypto();
using var up = parameter.GetCrypto();
var pmp = new ProtocolMessagePipe(server); var pmp = new ProtocolMessagePipe(server);
var key = CryptoUtils.SSKDF(password, parameter.KeySize); var key = CryptoUtils.SSKDF(password, parameter.KeySize);


@@ -54,7 +54,7 @@ namespace Shadowsocks.Protocol.Shadowsocks


public async Task ConvertDownlink(IDuplexPipe client, IDuplexPipe server) public async Task ConvertDownlink(IDuplexPipe client, IDuplexPipe server)
{ {
var down = parameter.GetCrypto();
using var down = parameter.GetCrypto();


var pmp = new ProtocolMessagePipe(server); var pmp = new ProtocolMessagePipe(server);
var salt = await pmp.ReadAsync(new SaltMessage(parameter.NonceSize)); var salt = await pmp.ReadAsync(new SaltMessage(parameter.NonceSize));


Loading…
Cancel
Save