1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-10 06:46:59 -05:00

Fix Twofish x64 multiblock tail handling

Only call the one-block assembly helper when one block remains after the three-block loop.

This prevents zero-block and multiple-of-three requests from reading and writing one extra block past the caller buffer.

Add a Twofish multiblock self-test covering block counts 0 through 9.
This commit is contained in:
Mounir IDRASSI
2026-06-03 20:54:42 +09:00
parent 61978021d2
commit a24cbe55bd
2 changed files with 43 additions and 2 deletions
+41
View File
@@ -1379,6 +1379,47 @@ static BOOL DoAutoTestAlgorithms (void)
} }
if (i != TWOFISH_TEST_COUNT) if (i != TWOFISH_TEST_COUNT)
bFailed = TRUE; bFailed = TRUE;
// Twofish EncipherBlocks()/DecipherBlocks()
{
enum { TwofishMultiBlockTestMaxBlocks = 9 };
uint8 testData[(TwofishMultiBlockTestMaxBlocks + 1) * 16];
uint8 expectedData[(TwofishMultiBlockTestMaxBlocks + 1) * 16];
uint8 originalData[(TwofishMultiBlockTestMaxBlocks + 1) * 16];
size_t blockCount, block, bytePos;
size_t blockSize = CipherGetBlockSize (TWOFISH);
size_t dataSize = sizeof (testData);
memcpy (key, twofish_vectors[0].key, 32);
CipherInit (TWOFISH, key, ks_tmp);
for (blockCount = 0; blockCount <= TwofishMultiBlockTestMaxBlocks; ++blockCount)
{
for (bytePos = 0; bytePos < dataSize; ++bytePos)
{
originalData[bytePos] = (uint8) (bytePos * 13 + blockCount);
testData[bytePos] = originalData[bytePos];
expectedData[bytePos] = originalData[bytePos];
}
for (block = 0; block < blockCount; ++block)
EncipherBlock (TWOFISH, expectedData + block * blockSize, ks_tmp);
EncipherBlocks (TWOFISH, testData, ks_tmp, blockCount);
if (memcmp (testData, expectedData, dataSize) != 0)
{
bFailed = TRUE;
break;
}
DecipherBlocks (TWOFISH, testData, ks_tmp, blockCount);
if (memcmp (testData, originalData, dataSize) != 0)
{
bFailed = TRUE;
break;
}
}
}
/* Camellia */ /* Camellia */
+2 -2
View File
@@ -89,7 +89,7 @@ void twofish_encrypt_blocks(TwofishInstance *instance, const uint8* in_blk, uint
{ {
twofish_enc_blk2 (instance, out_blk, in_blk); twofish_enc_blk2 (instance, out_blk, in_blk);
} }
else else if (blockCount == 1)
{ {
twofish_enc_blk (instance, out_blk, in_blk); twofish_enc_blk (instance, out_blk, in_blk);
} }
@@ -110,7 +110,7 @@ void twofish_decrypt_blocks(TwofishInstance *instance, const uint8* in_blk, uint
{ {
twofish_dec_blk2 (instance, out_blk, in_blk); twofish_dec_blk2 (instance, out_blk, in_blk);
} }
else else if (blockCount == 1)
{ {
twofish_dec_blk (instance, out_blk, in_blk); twofish_dec_blk (instance, out_blk, in_blk);
} }