Beispiel #1
0
void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
{
	/* Deprecated/legacy */

	int cipher = EAGetFirstCipher (cryptoInfo->ea);
	int cipherCount = EAGetCipherCount (cryptoInfo->ea);
	unsigned __int8 *p = buffer;
	unsigned __int8 *ks = cryptoInfo->ks;
	unsigned __int8 i[8];
	unsigned __int8 t[16];
	unsigned __int64 b;

	*(unsigned __int64 *)i = BE64(blockIndex);

	if (length % 16)
		GST_THROW_FATAL_EXCEPTION;

	// Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).

	for (b = 0; b < length >> 4; b++)
	{
		Gf128MulBy64Tab (i, t, &cryptoInfo->gf_ctx);
		Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		if (cipherCount > 1)
		{
			// Cipher cascade
			ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);

			for (cipher = EAGetLastCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
			{
				ks -= CipherGetKeyScheduleSize (cipher);
				DecipherBlock (cipher, p, ks);
			}
		}
		else
		{
			DecipherBlock (cipher, p, ks);
		}

		Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		p += 16;

		if (i[7] != 0xff)
			i[7]++;
		else
			*(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
	}

	FAST_ERASE64 (t, sizeof(t));
}
	void EncryptionModeLRW::EncryptBuffer (byte *data, uint64 length, uint64 blockIndex) const
	{
		size_t blockSize = Ciphers.front()->GetBlockSize();
		if (blockSize != 8 && blockSize != 16)
			throw ParameterIncorrect (SRC_POS);

		byte i[8];
		*(uint64 *)i = Endian::Big (blockIndex);

		byte t[Cipher::MaxBlockSize];

		for (unsigned int b = 0; b < length / blockSize; b++)
		{
			if (blockSize == 8)
			{
				Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr()));
				Xor64 ((uint64 *)data, (uint64 *)t);
			}
			else
			{
				Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr()));
				Xor128 ((uint64 *)data, (uint64 *)t);
			}

			for (CipherList::const_iterator iCipherList = Ciphers.begin();
				iCipherList != Ciphers.end();
				++iCipherList)
			{
				const Cipher &c = **iCipherList;

				if (c.GetBlockSize () != blockSize)
					throw ParameterIncorrect (SRC_POS);

				c.EncryptBlock (data);
			}

			if (blockSize == 8)
				Xor64 ((uint64 *)data, (uint64 *)t);
			else
				Xor128 ((uint64 *)data, (uint64 *)t);

			data += blockSize;
			IncrementBlockIndex (i);
		}

		Memory::Erase (t, sizeof (t));
	}