mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-19 06:17:43 +01:00
WIP
This commit is contained in:
parent
b8db381216
commit
a0c0fe9faf
2 changed files with 67 additions and 20 deletions
|
|
@ -55,37 +55,80 @@ namespace Dalamud.Bootstrap.Crypto
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
public void EncryptInPlace(Span<byte> buffer)
|
public void Encrypt(ReadOnlySpan<byte> source, Span<byte> destination)
|
||||||
{
|
{
|
||||||
|
CheckBuffer(source, destination);
|
||||||
|
|
||||||
// TODO: this is shit
|
// TODO: this is shit
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DecryptInPlace(Span<byte> buffer)
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <param name="destination">A buffer to store decrypted data be stored.</param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown when either the length of the buffer is not multiple of the block size. (i.e. 8 bytes)
|
||||||
|
/// or `source` and `destination` are overlapped in the memory.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// `source` and `destination` must not overlap in the memory.
|
||||||
|
/// </remarks>
|
||||||
|
public void Decrypt(ReadOnlySpan<byte> source, Span<byte> destination)
|
||||||
{
|
{
|
||||||
if (CheckBufferLength(buffer.Length))
|
CheckBuffer(source, destination);
|
||||||
{
|
|
||||||
throw new ArgumentException("TODO: buffer length", nameof(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (byte* pBuffer = buffer)
|
fixed (byte* pSrc = source)
|
||||||
|
fixed (byte* pDst = destination)
|
||||||
{
|
{
|
||||||
for (byte* it = pBuffer; it < pBuffer + buffer.Length; it += 8)
|
ref var a = source.[4];
|
||||||
|
for (byte* it = pDst; it < pDst + buffer.Length; it += 8)
|
||||||
{
|
{
|
||||||
DecryptBlockInPlace(it, it);
|
DecryptBlock(it, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void EncryptBlockInPlace(byte* input, byte* output)
|
/// <summary>
|
||||||
|
/// This is a helper function that throws exception when prerequisites for encrypting or decrypting data are not met.
|
||||||
|
/// </summary>
|
||||||
|
private static void CheckBuffer(ReadOnlySpan<byte> source, ReadOnlySpan<byte> destination)
|
||||||
|
{
|
||||||
|
if (source.Length > destination.Length)
|
||||||
|
{
|
||||||
|
var message = $"The destination buffer is too small to store data. (Destination buffer is smaller than source)";
|
||||||
|
throw new ArgumentException(message, nameof(destination));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.Overlaps(destination))
|
||||||
|
{
|
||||||
|
var message = $"Source buffer and destination buffer must not overlap.";
|
||||||
|
throw new ArgumentException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckBufferLength(source.Length))
|
||||||
|
{
|
||||||
|
var message = $"The length of the source buffer must be aligned to the block size. (i.e. 8 bytes)";
|
||||||
|
throw new ArgumentException(message, nameof(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckBufferLength(destination.Length))
|
||||||
|
{
|
||||||
|
var message = $"The length of the destination buffer must be aligned to the block size. (i.e. 8 bytes)";
|
||||||
|
throw new ArgumentException(message, nameof(destination));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe void EncryptBlock(byte* input, byte* output)
|
||||||
{
|
{
|
||||||
var inputBlock = (uint*)input;
|
var inputBlock = (uint*)input;
|
||||||
var outputBlock = (uint*)output;
|
var outputBlock = (uint*)output;
|
||||||
|
|
||||||
var xl = inputBlock[0];
|
var xl = UinputBlock[0];
|
||||||
var xr = inputBlock[1];
|
var xr = inputBlock[1];
|
||||||
|
|
||||||
// will be elided by JIT
|
// will be elided by JIT
|
||||||
|
|
@ -108,14 +151,17 @@ namespace Dalamud.Bootstrap.Crypto
|
||||||
outputBlock[1] = xr;
|
outputBlock[1] = xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void DecryptBlockInPlace(byte* input, byte* output)
|
/// <summary>
|
||||||
|
/// Decrypts a block
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// `input` and `output` are assumed to be unaligned to 4 bytes. (left and right part of the block)
|
||||||
|
/// </remarks>
|
||||||
|
private unsafe void DecryptBlock(byte* input, byte* output)
|
||||||
{
|
{
|
||||||
var inputBlock = (uint*)input;
|
var xl = Unsafe.ReadUnaligned<uint>(input);
|
||||||
var outputBlock = (uint*)output;
|
var xr = Unsafe.ReadUnaligned<uint>(input + 4);
|
||||||
|
|
||||||
var xl = inputBlock[0];
|
|
||||||
var xr = inputBlock[1];
|
|
||||||
|
|
||||||
// will be elided by JIT
|
// will be elided by JIT
|
||||||
if (!BitConverter.IsLittleEndian)
|
if (!BitConverter.IsLittleEndian)
|
||||||
{
|
{
|
||||||
|
|
@ -132,8 +178,8 @@ namespace Dalamud.Bootstrap.Crypto
|
||||||
xr = BinaryPrimitives.ReverseEndianness(xr);
|
xr = BinaryPrimitives.ReverseEndianness(xr);
|
||||||
}
|
}
|
||||||
|
|
||||||
outputBlock[0] = xl;
|
Unsafe.WriteUnaligned(output, xl);
|
||||||
outputBlock[1] = xr;
|
Unsafe.WriteUnaligned(output + 4, xr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Resources.Extensions" Version="4.7.0" /> <!-- Required by CoreHook to build -->
|
<PackageReference Include="System.Resources.Extensions" Version="4.7.0" /> <!-- Required by CoreHook to build -->
|
||||||
|
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.7.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue