Skip to content

Commit e9992cf

Browse files
Tests: verify that CRYPTOPP_ALIGN_DATA delivers the requested alignment (#1844)
The macro expands to nothing for compilers that are neither MSVC nor GCC/Clang, and the SIMD backends issue aligned loads against buffers declared with it, so a silent expansion to nothing would fault at run time. Nothing verified this so far. Add TC_IS_ALIGNED next to the existing alignment constants and check both of them from the platform self-test suites. The probe buffers stay below the alignment under test because the ABI already aligns larger objects by itself, which would make the check pass vacuously. The check is skipped in the Windows driver: a failing self-test there reaches TC_BUG_CHECK and would bugcheck the machine.
1 parent 24c7449 commit e9992cf

4 files changed

Lines changed: 54 additions & 0 deletions

File tree

‎src/Common/Tests.c‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <string.h>
2121
#include "Pkcs5.h"
2222
#include "cpu.h"
23+
#include "Volumes.h"
2324

2425
typedef struct {
2526
CRYPTOPP_ALIGN_DATA(16) unsigned __int8 key1[32];
@@ -1280,6 +1281,28 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
12801281
return (nTestsPerformed == 150);
12811282
}
12821283

1284+
#ifndef TC_WINDOWS_DRIVER
1285+
// Must stay smaller than the alignment under test: the ABI aligns larger objects by itself.
1286+
#define TC_ALIGNMENT_PROBE_SIZE 4
1287+
1288+
/* Verifies that CRYPTOPP_ALIGN_DATA actually delivers the alignment it requests. It expands
1289+
to nothing for compilers that are neither MSVC nor GCC/Clang (see Crypto/config.h), and the
1290+
SIMD backends issue aligned loads against buffers declared with it. */
1291+
static BOOL TestBufferAlignment (void)
1292+
{
1293+
static CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) unsigned char derivedKeyProbe[TC_ALIGNMENT_PROBE_SIZE];
1294+
static CRYPTOPP_ALIGN_DATA(TC_KEY_INFO_BUFFER_ALIGNMENT) unsigned char keyInfoProbe[TC_ALIGNMENT_PROBE_SIZE];
1295+
1296+
if (!TC_IS_ALIGNED (derivedKeyProbe, TC_DERIVED_KEY_BUFFER_ALIGNMENT))
1297+
return FALSE;
1298+
1299+
if (!TC_IS_ALIGNED (keyInfoProbe, TC_KEY_INFO_BUFFER_ALIGNMENT))
1300+
return FALSE;
1301+
1302+
return TRUE;
1303+
}
1304+
#endif
1305+
12831306
static BOOL DoAutoTestAlgorithms (void)
12841307
{
12851308
PCRYPTO_INFO ci;
@@ -1489,6 +1512,13 @@ static BOOL DoAutoTestAlgorithms (void)
14891512
bFailed = TRUE;
14901513

14911514
crypto_close (ci);
1515+
1516+
#ifndef TC_WINDOWS_DRIVER
1517+
/* Not run in the driver: a failing self-test there reaches TC_BUG_CHECK and would bugcheck the machine. */
1518+
if (!TestBufferAlignment ())
1519+
bFailed = TRUE;
1520+
#endif
1521+
14921522
return !bFailed;
14931523
}
14941524

‎src/Common/Volumes.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ extern "C" {
4141
// Required 16-byte alignment for KEY_INFO buffer to ensure optimal performance and compatibility with SIMD instructions.
4242
#define TC_KEY_INFO_BUFFER_ALIGNMENT 16
4343

44+
// TRUE if the address meets the given alignment.
45+
#define TC_IS_ALIGNED(address, alignment) ((((uint64) (address)) % (alignment)) == 0)
46+
4447
// Current volume format version (created by TrueCrypt 6.0+)
4548
#define TC_VOLUME_FORMAT_VERSION 2
4649

‎src/Volume/EncryptionTest.cpp‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,30 @@ namespace VeraCrypt
7070

7171
void EncryptionTest::TestAll ()
7272
{
73+
TestAlignment();
7374
TestAll (false);
7475
TestAll (true);
7576
}
7677

78+
// Must stay smaller than the alignment under test: the ABI aligns larger objects by itself.
79+
#define TC_ALIGNMENT_PROBE_SIZE 4
80+
81+
// Verifies that CRYPTOPP_ALIGN_DATA actually delivers the alignment it requests.
82+
// It expands to nothing for compilers that are neither MSVC nor GCC/Clang (see
83+
// Crypto/config.h), and the SIMD backends issue aligned loads against buffers
84+
// declared with it, so a silent expansion to nothing would fault at run time.
85+
void EncryptionTest::TestAlignment ()
86+
{
87+
static CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) uint8 derivedKeyProbe[TC_ALIGNMENT_PROBE_SIZE];
88+
static CRYPTOPP_ALIGN_DATA(TC_KEY_INFO_BUFFER_ALIGNMENT) uint8 keyInfoProbe[TC_ALIGNMENT_PROBE_SIZE];
89+
90+
if (!TC_IS_ALIGNED (derivedKeyProbe, TC_DERIVED_KEY_BUFFER_ALIGNMENT))
91+
throw TestFailed (SRC_POS);
92+
93+
if (!TC_IS_ALIGNED (keyInfoProbe, TC_KEY_INFO_BUFFER_ALIGNMENT))
94+
throw TestFailed (SRC_POS);
95+
}
96+
7797
void EncryptionTest::TestAll (bool enableCpuEncryptionSupport)
7898
{
7999
bool hwSupportEnabled = Cipher::IsHwSupportEnabled();

‎src/Volume/EncryptionTest.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace VeraCrypt
2525
static void TestAll (bool enableCpuEncryptionSupport);
2626

2727
protected:
28+
static void TestAlignment ();
2829
static void TestCiphers ();
2930
static void TestLegacyModes ();
3031
static void TestPkcs5 ();

0 commit comments

Comments
 (0)