private static byte[] Decrypt(byte[] data, int index)
{
byte keyNameSize = data[1];
if (keyNameSize == 0 || keyNameSize != 8)
{
throw new BLTEDecoderException("keyNameSize == 0 || keyNameSize != 8");
}
byte[] keyNameBytes = new byte[keyNameSize];
Array.Copy(data, 2, keyNameBytes, 0, keyNameSize);
ulong keyName = BitConverter.ToUInt64(keyNameBytes, 0);
byte IVSize = data[keyNameSize + 2];
if (IVSize != 4 || IVSize > 0x10)
{
throw new BLTEDecoderException("IVSize != 4 || IVSize > 0x10");
}
byte[] IVpart = new byte[IVSize];
Array.Copy(data, keyNameSize + 3, IVpart, 0, IVSize);
if (data.Length < IVSize + keyNameSize + 4)
{
throw new BLTEDecoderException("data.Length < IVSize + keyNameSize + 4");
}
int dataOffset = keyNameSize + IVSize + 3;
byte encType = data[dataOffset];
if (encType != ENCRYPTION_SALSA20 && encType != ENCRYPTION_ARC4) // 'S' or 'A'
{
throw new BLTEDecoderException("encType != 0x53 && encType != 0x41");
}
dataOffset++;
// expand to 8 bytes
byte[] IV = new byte[8];
Array.Copy(IVpart, IV, IVpart.Length);
// magic
for (int shift = 0, i = 0; i < sizeof(int); shift += 8, i++)
{
IV[i] ^= (byte)((index >> shift) & 0xFF);
}
byte[] key = KeyService.GetKey(keyName);
if (key == null)
{
throw new BLTEDecoderException("unknown keyname {0:X16}", keyName);
}
if (encType == ENCRYPTION_SALSA20)
{
ICryptoTransform decryptor = KeyService.SalsaInstance.CreateDecryptor(key, IV);
return(decryptor.TransformFinalBlock(data, dataOffset, data.Length - dataOffset));
}
else
{
// ARC4 ?
throw new BLTEDecoderException("encType A not implemented");
}
}