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)); }