Browse Source

fix chacha20-ietf data size limitation by manually calculate IC and offset

pull/2865/head
Student Main 5 years ago
parent
commit
93b57eb132
1 changed files with 22 additions and 14 deletions
  1. +22
    -14
      shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs

+ 22
- 14
shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs View File

@@ -6,30 +6,38 @@ namespace Shadowsocks.Encryption.Stream
{
public class StreamChachaNaClEncryptor : StreamEncryptor
{
// yes, they update over all saved data everytime...
byte[] chachaBuf = new byte[65536];
int ptr = 0;
const int BlockSize = 64;
// when new data arrive, put it in correct offset of chunk
// and update it, ignore other data, get it in correct offset...
byte[] chachaBuf = new byte[32768 + BlockSize];
int remain = 0;
// increase counter only when a chunk fully recieved
int ic = 0;
public StreamChachaNaClEncryptor(string method, string password) : base(method, password)
{
}

protected override int CipherDecrypt(Span<byte> plain, Span<byte> cipher)
{
int len = cipher.Length;
cipher.CopyTo(chachaBuf.AsSpan(ptr));
var p = new ChaCha20(key, 0).Decrypt(chachaBuf, iv);
p.AsSpan(ptr, len).CopyTo(plain);
ptr += len;
return len;
return CipherUpdate(cipher, plain, false);
}

protected override int CipherEncrypt(Span<byte> plain, Span<byte> cipher)
{
int len = plain.Length;
plain.CopyTo(chachaBuf.AsSpan(ptr));
var p = new ChaCha20(key, 0).Encrypt(chachaBuf, iv);
p.AsSpan(ptr, len).CopyTo(cipher);
ptr += len;
return CipherUpdate(plain, cipher, true);
}

private int CipherUpdate(Span<byte> i, Span<byte> o, bool enc)
{
int len = i.Length;
int pad = remain;
i.CopyTo(chachaBuf.AsSpan(pad));
var chacha = new ChaCha20(key, ic);
var p = enc ? chacha.Encrypt(chachaBuf, iv) : chacha.Decrypt(chachaBuf, iv);
p.AsSpan(pad, len).CopyTo(o);
pad += len;
ic += pad / BlockSize;
remain = pad % BlockSize;
return len;
}



Loading…
Cancel
Save