Rewrite BlowfishKeyProvider.ProcessPredata using safe code.

Fixes #2441.  This error would occur when the memory
regions were allocated at particular addresses when
running a mono-compiled binary on a .net runtime.

The data would be copied to the pointer returned
from a fixed() statement, but the managed array
would *not* be updated with the new data.  This
caused DecryptKey to silently return a bogus key
full of zeros, and the mix file header decryption
would subsequently fail.
This commit is contained in:
Paul Chote
2015-09-25 21:50:45 +01:00
parent 0e9257abcf
commit 7dcb896f3d

View File

@@ -119,12 +119,6 @@ namespace OpenRA.FileFormats
pubkey.Len = BitLenBigNum(pubkey.KeyOne, 64) - 1;
}
uint LenPreData()
{
var a = (pubkey.Len - 1) / 8;
return (55 / a + 1) * (a + 1);
}
static int CompareBigNum(uint[] n1, uint[] n2, uint len)
{
while (len > 0)
@@ -462,46 +456,37 @@ namespace OpenRA.FileFormats
}
}
static unsafe void Memcopy(byte* dest, byte* src, int len)
{
while (len-- != 0) *dest++ = *src++;
}
unsafe void ProcessPredata(byte* pre, uint pre_len, byte* buf)
byte[] ProcessPredata(byte[] src)
{
var dest = new byte[256];
var n2 = new uint[64];
var n3 = new uint[64];
var a = (pubkey.Len - 1) / 8;
var a = (int)((pubkey.Len - 1) / 8);
var pre_len = (55 / a + 1) * (a + 1);
var srcOffset = 0;
var destOffset = 0;
while (a + 1 <= pre_len)
{
InitBigNum(n2, 0, 64);
fixed (uint* pn2 = &n2[0])
Memcopy((byte*)pn2, pre, (int)a + 1);
CalcKey(n3, n2, pubkey.KeyTwo, pubkey.KeyOne, 64);
fixed (uint* pn3 = &n3[0])
Memcopy(buf, (byte*)pn3, (int)a);
Buffer.BlockCopy(src, srcOffset, n2, 0, a + 1);
CalcKey(n3, n2, pubkey.KeyTwo, pubkey.KeyOne, 64);
Buffer.BlockCopy(n3, 0, dest, destOffset, a);
pre_len -= a + 1;
pre += a + 1;
buf += a;
srcOffset += a + 1;
destOffset += a;
}
return dest;
}
public byte[] DecryptKey(byte[] src)
{
InitPublicKey();
var dest = new byte[256];
unsafe
{
fixed (byte* pdest = &dest[0])
fixed (byte* psrc = &src[0])
ProcessPredata(psrc, LenPreData(), pdest);
}
return dest.Take(56).ToArray();
return ProcessPredata(src).Take(56).ToArray();
}
}
}