Ensure crypto works when the input and output buffers are the same

This commit is contained in:
Alex Barney 2019-11-19 21:05:33 -05:00
parent d0caf6ca4f
commit 191b3d41f6
5 changed files with 21 additions and 14 deletions

View file

@ -1,7 +1,9 @@
// ReSharper disable AssignmentIsFullyDiscarded
using System;
using LibHac.Crypto.Detail;
#if HAS_INTRINSICS
using LibHac.Crypto.Detail;
using AesNi = System.Runtime.Intrinsics.X86.Aes;
#endif

View file

@ -58,10 +58,11 @@ namespace LibHac.Crypto.Detail
for (int i = 0; i < blockCount; i++)
{
Vector128<byte> decBeforeIv = _aesCore.DecryptBlock(inBlock);
Vector128<byte> currentBlock = inBlock;
Vector128<byte> decBeforeIv = _aesCore.DecryptBlock(currentBlock);
outBlock = Sse2.Xor(decBeforeIv, iv);
iv = inBlock;
iv = currentBlock;
inBlock = ref Unsafe.Add(ref inBlock, 1);
outBlock = ref Unsafe.Add(ref outBlock, 1);

View file

@ -49,8 +49,8 @@ namespace LibHac.Crypto.Detail
if (leftover != 0)
{
ref Buffer16 inBlock =
ref Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(input)), blockCount);
Buffer16 inBlock =
Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(input)), blockCount);
ref Buffer16 outBlock =
ref Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(output)), blockCount);
@ -107,8 +107,8 @@ namespace LibHac.Crypto.Detail
Buffer16 finalTweak = tweak;
Gf128Mul(ref finalTweak);
ref Buffer16 inBlock =
ref Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(input)), blockCount);
Buffer16 inBlock =
Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(input)), blockCount);
ref Buffer16 outBlock =
ref Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(output)), blockCount);
@ -120,7 +120,9 @@ namespace LibHac.Crypto.Detail
XorBuffer(ref outBlock, ref tmp, ref finalTweak);
ref Buffer16 finalOutBlock = ref Unsafe.Add(ref outBlock, 1);
ref Buffer16 finalInBlock = ref Unsafe.Add(ref inBlock, 1);
Buffer16 finalInBlock = Unsafe.Add(ref Unsafe.As<byte, Buffer16>(ref MemoryMarshal.GetReference(input)),
blockCount + 1);
for (int i = 0; i < leftover; i++)
{

View file

@ -108,7 +108,7 @@ namespace LibHac.Crypto.Detail
var x = new Buffer16();
ref Buffer16 outBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref output);
ref Buffer16 nextInBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref Unsafe.Add(ref input, 1));
Buffer16 nextInBuf = Unsafe.As<Vector128<byte>, Buffer16>(ref Unsafe.Add(ref input, 1));
ref Buffer16 nextOutBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref Unsafe.Add(ref output, 1));
for (int i = 0; i < finalBlockLength; i++)
@ -134,7 +134,7 @@ namespace LibHac.Crypto.Detail
var x = new Buffer16();
ref Buffer16 outBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref output);
ref Buffer16 inBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref input);
Buffer16 inBuf = Unsafe.As<Vector128<byte>, Buffer16>(ref input);
ref Buffer16 prevOutBuf = ref Unsafe.As<Vector128<byte>, Buffer16>(ref prevOutBlock);
for (int i = 0; i < finalBlockLength; i++)

View file

@ -1,4 +1,5 @@
using LibHac.Crypto;
using System;
using LibHac.Crypto;
using Xunit;
namespace LibHac.Tests.CryptoTests
@ -7,11 +8,12 @@ namespace LibHac.Tests.CryptoTests
{
internal static void CipherTestCore(byte[] inputData, byte[] expected, ICipher cipher)
{
var outputData = new byte[expected.Length];
var transformBuffer = new byte[inputData.Length];
Buffer.BlockCopy(inputData, 0, transformBuffer, 0, inputData.Length);
cipher.Transform(inputData, outputData);
cipher.Transform(transformBuffer, transformBuffer);
Assert.Equal(expected, outputData);
Assert.Equal(expected, transformBuffer);
}
}
}