forked from vpnhood/VpnHood
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBufferCryptor.cs
54 lines (46 loc) · 1.54 KB
/
BufferCryptor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Security.Cryptography;
namespace VpnHood.Tunneling;
public class BufferCryptor : IDisposable
{
private readonly ICryptoTransform _cryptor;
public BufferCryptor(byte[] key)
{
//init cryptor
using var aes = Aes.Create();
aes.KeySize = key.Length * 8;
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
aes.Key = key;
_cryptor = aes.CreateEncryptor(aes.Key, aes.IV);
}
public void Dispose()
{
_cryptor.Dispose();
}
public void Cipher(byte[] buffer, int offset, int count, long cryptoPos)
{
//find block number
var blockSizeInByte = (uint)_cryptor.OutputBlockSize;
var blockNumber = (ulong)cryptoPos / blockSizeInByte + 1;
var keyPos = (ulong)cryptoPos % blockSizeInByte;
//buffer
var outputBuffer = new byte[blockSizeInByte];
var nonce = new byte[blockSizeInByte];
var init = false;
for (var i = offset; i < offset + count; i++)
{
//encrypt the nonce to form next xor buffer (unique key)
if (!init || keyPos % blockSizeInByte == 0)
{
BitConverter.GetBytes(blockNumber).CopyTo(nonce, 0);
_cryptor.TransformBlock(nonce, 0, nonce.Length, outputBuffer, 0);
if (init) keyPos = 0;
init = true;
blockNumber++;
}
buffer[i] ^= outputBuffer[keyPos]; //simple XOR with generated unique key
keyPos++;
}
}
}