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)); }
size_t Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer) { if (input == 0 || inputLen <= 0) return 0; byte block[16], iv[4][4]; memcpy(iv,m_initVector,16); size_t numBlocks=inputLen/16; for (size_t i = numBlocks; i > 0; i--) { decrypt(input, block); Xor128(block,block,(byte*)iv); #if STRICT_ALIGN memcpy(iv, input, 16); memcpy(outBuf, block, 16); #else Copy128((byte*)iv,input); Copy128(outBuffer,block); #endif input += 16; outBuffer += 16; } memcpy(m_initVector,iv,16); return 16*numBlocks; }
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)); }
void Rijndael::decrypt(const byte a[16], byte b[16]) { int r; byte temp[4][4]; Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]); Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]); Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]); Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]); Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]); for(r = m_uRounds-1; r > 1; r--) { Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]); Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]); Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]); Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]); Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]); } Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]); b[ 0] = S5[temp[0][0]]; b[ 1] = S5[temp[3][1]]; b[ 2] = S5[temp[2][2]]; b[ 3] = S5[temp[1][3]]; b[ 4] = S5[temp[1][0]]; b[ 5] = S5[temp[0][1]]; b[ 6] = S5[temp[3][2]]; b[ 7] = S5[temp[2][3]]; b[ 8] = S5[temp[2][0]]; b[ 9] = S5[temp[1][1]]; b[10] = S5[temp[0][2]]; b[11] = S5[temp[3][3]]; b[12] = S5[temp[3][0]]; b[13] = S5[temp[2][1]]; b[14] = S5[temp[1][2]]; b[15] = S5[temp[0][3]]; Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]); }
void Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer) { if (inputLen <= 0) return; size_t numBlocks=inputLen/16; #ifdef USE_SSE if (AES_NI) { blockDecryptSSE(input,numBlocks,outBuffer); return; } #endif byte block[16], iv[4][4]; memcpy(iv,m_initVector,16); for (size_t i = numBlocks; i > 0; i--) { byte temp[4][4]; Xor128(temp,input,m_expandedKey[m_uRounds]); Xor128(block, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]); Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]); Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]); Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]); for(int r = m_uRounds-1; r > 1; r--) { Xor128(temp,block,m_expandedKey[r]); Xor128(block, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]); Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]); Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]); Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]); } Xor128(temp,block,m_expandedKey[1]); block[ 0] = S5[temp[0][0]]; block[ 1] = S5[temp[3][1]]; block[ 2] = S5[temp[2][2]]; block[ 3] = S5[temp[1][3]]; block[ 4] = S5[temp[1][0]]; block[ 5] = S5[temp[0][1]]; block[ 6] = S5[temp[3][2]]; block[ 7] = S5[temp[2][3]]; block[ 8] = S5[temp[2][0]]; block[ 9] = S5[temp[1][1]]; block[10] = S5[temp[0][2]]; block[11] = S5[temp[3][3]]; block[12] = S5[temp[3][0]]; block[13] = S5[temp[2][1]]; block[14] = S5[temp[1][2]]; block[15] = S5[temp[0][3]]; Xor128(block,block,m_expandedKey[0]); if (CBCMode) Xor128(block,block,iv); Copy128((byte*)iv,input); Copy128(outBuffer,block); input += 16; outBuffer += 16; } memcpy(m_initVector,iv,16); }