mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Stage 1
This commit is contained in:
parent
1ca023be36
commit
3a4d8951d5
20 changed files with 1511 additions and 389 deletions
|
|
@ -2,6 +2,8 @@
|
|||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MinecraftClient.Crypto
|
||||
{
|
||||
|
|
@ -59,6 +61,11 @@ namespace MinecraftClient.Crypto
|
|||
BaseStream.Flush();
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return BaseStream.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
|
|
@ -101,6 +108,15 @@ namespace MinecraftClient.Crypto
|
|||
return (byte)(blockOutput[0] ^ inputBuf);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void EncryptBlock(ReadOnlySpan<byte> blockInput, Span<byte> blockOutput)
|
||||
{
|
||||
if (FastAes is not null)
|
||||
FastAes.EncryptEcb(blockInput, blockOutput);
|
||||
else
|
||||
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public override int Read(byte[] buffer, int outOffset, int required)
|
||||
{
|
||||
|
|
@ -122,23 +138,11 @@ namespace MinecraftClient.Crypto
|
|||
}
|
||||
|
||||
int processEnd = readed + curRead;
|
||||
if (FastAes is not null)
|
||||
for (int idx = readed; idx < processEnd; idx++)
|
||||
{
|
||||
for (int idx = readed; idx < processEnd; idx++)
|
||||
{
|
||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||
FastAes.EncryptEcb(blockInput, blockOutput);
|
||||
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int idx = readed; idx < processEnd; idx++)
|
||||
{
|
||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
||||
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||
}
|
||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||
EncryptBlock(blockInput, blockOutput);
|
||||
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,10 +165,7 @@ namespace MinecraftClient.Crypto
|
|||
{
|
||||
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||
|
||||
if (FastAes is not null)
|
||||
FastAes.EncryptEcb(WriteStreamIV, blockOutput);
|
||||
else
|
||||
Aes!.EncryptEcb(WriteStreamIV, blockOutput, PaddingMode.None);
|
||||
EncryptBlock(WriteStreamIV, blockOutput);
|
||||
|
||||
byte outputBuf = (byte)(blockOutput[0] ^ b);
|
||||
|
||||
|
|
@ -185,15 +186,88 @@ namespace MinecraftClient.Crypto
|
|||
for (int wirtten = 0; wirtten < required; ++wirtten)
|
||||
{
|
||||
ReadOnlySpan<byte> blockInput = new(outputBuf, wirtten, blockSize);
|
||||
if (FastAes is not null)
|
||||
FastAes.EncryptEcb(blockInput, blockOutput);
|
||||
else
|
||||
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
||||
EncryptBlock(blockInput, blockOutput);
|
||||
outputBuf[blockSize + wirtten] = (byte)(blockOutput[0] ^ input[offset + wirtten]);
|
||||
}
|
||||
BaseStream.WriteAsync(outputBuf, blockSize, required);
|
||||
BaseStream.Write(outputBuf, blockSize, required);
|
||||
|
||||
Array.Copy(outputBuf, required, WriteStreamIV, 0, blockSize);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (inStreamEnded || buffer.Length == 0)
|
||||
return 0;
|
||||
|
||||
byte[] inputBuf = new byte[blockSize + buffer.Length];
|
||||
Array.Copy(ReadStreamIV, inputBuf, blockSize);
|
||||
|
||||
for (int readed = 0; readed < buffer.Length;)
|
||||
{
|
||||
int curRead = await BaseStream.ReadAsync(inputBuf.AsMemory(blockSize + readed, buffer.Length - readed), cancellationToken);
|
||||
if (curRead == 0)
|
||||
{
|
||||
inStreamEnded = true;
|
||||
Array.Copy(inputBuf, readed, ReadStreamIV, 0, blockSize);
|
||||
return readed;
|
||||
}
|
||||
|
||||
int processEnd = readed + curRead;
|
||||
DecryptToOutputBuffer(inputBuf, buffer, readed, processEnd);
|
||||
readed = processEnd;
|
||||
}
|
||||
|
||||
Array.Copy(inputBuf, buffer.Length, ReadStreamIV, 0, blockSize);
|
||||
return buffer.Length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (buffer.Length == 0)
|
||||
return;
|
||||
|
||||
byte[] outputBuf = new byte[blockSize + buffer.Length];
|
||||
Array.Copy(WriteStreamIV, outputBuf, blockSize);
|
||||
EncryptToOutputBuffer(buffer, outputBuf);
|
||||
|
||||
await BaseStream.WriteAsync(outputBuf.AsMemory(blockSize, buffer.Length), cancellationToken);
|
||||
Array.Copy(outputBuf, buffer.Length, WriteStreamIV, 0, blockSize);
|
||||
}
|
||||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private void DecryptToOutputBuffer(byte[] inputBuf, Memory<byte> output, int start, int end)
|
||||
{
|
||||
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||
for (int idx = start; idx < end; idx++)
|
||||
{
|
||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||
EncryptBlock(blockInput, blockOutput);
|
||||
output.Span[idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private void EncryptToOutputBuffer(ReadOnlyMemory<byte> input, byte[] outputBuf)
|
||||
{
|
||||
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||
for (int written = 0; written < input.Length; ++written)
|
||||
{
|
||||
ReadOnlySpan<byte> blockInput = new(outputBuf, written, blockSize);
|
||||
EncryptBlock(blockInput, blockOutput);
|
||||
outputBuf[blockSize + written] = (byte)(blockOutput[0] ^ input.Span[written]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue