Skip to content

Commit b4c4290

Browse files
committed
Tests: check declared buffer alignment at compile time
Check wrapper type alignment in both test suites so incidental alignment can't hide an empty CRYPTOPP_ALIGN_DATA, including in ASan builds. Clarify that the compiler may fold the existing address checks.
1 parent 0ae91a9 commit b4c4290

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

‎src/Common/Tests.c‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,12 +1282,24 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
12821282
}
12831283

12841284
#ifndef TC_WINDOWS_DRIVER
1285-
// Must stay smaller than the alignment under test: the ABI aligns larger objects by itself.
12861285
#define TC_ALIGNMENT_PROBE_SIZE 4
12871286

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. */
1287+
/* Check type alignment at compile time: static probes can be aligned even with an
1288+
empty CRYPTOPP_ALIGN_DATA, for example in AddressSanitizer builds. */
1289+
typedef struct
1290+
{
1291+
CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) unsigned char buffer[TC_ALIGNMENT_PROBE_SIZE];
1292+
} DerivedKeyAlignmentProbe;
1293+
1294+
typedef struct
1295+
{
1296+
CRYPTOPP_ALIGN_DATA(TC_KEY_INFO_BUFFER_ALIGNMENT) unsigned char buffer[TC_ALIGNMENT_PROBE_SIZE];
1297+
} KeyInfoAlignmentProbe;
1298+
1299+
typedef char DerivedKeyAlignmentCheck[(__alignof (DerivedKeyAlignmentProbe) >= TC_DERIVED_KEY_BUFFER_ALIGNMENT) ? 1 : -1];
1300+
typedef char KeyInfoAlignmentCheck[(__alignof (KeyInfoAlignmentProbe) >= TC_KEY_INFO_BUFFER_ALIGNMENT) ? 1 : -1];
1301+
1302+
/* The compiler may fold the address checks using the declared alignment. */
12911303
static BOOL TestBufferAlignment (void)
12921304
{
12931305
static CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) unsigned char derivedKeyProbe[TC_ALIGNMENT_PROBE_SIZE];

‎src/Volume/EncryptionTest.cpp‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,26 @@ namespace VeraCrypt
7575
TestAll (true);
7676
}
7777

78-
// Must stay smaller than the alignment under test: the ABI aligns larger objects by itself.
7978
#define TC_ALIGNMENT_PROBE_SIZE 4
8079

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.
80+
// The compiler may fold the address checks using the declared alignment.
8581
void EncryptionTest::TestAlignment ()
8682
{
83+
// Check type alignment at compile time: static probes can be aligned even with an
84+
// empty CRYPTOPP_ALIGN_DATA, for example in AddressSanitizer builds.
85+
struct DerivedKeyAlignmentProbe
86+
{
87+
CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) uint8 buffer[TC_ALIGNMENT_PROBE_SIZE];
88+
};
89+
90+
struct KeyInfoAlignmentProbe
91+
{
92+
CRYPTOPP_ALIGN_DATA(TC_KEY_INFO_BUFFER_ALIGNMENT) uint8 buffer[TC_ALIGNMENT_PROBE_SIZE];
93+
};
94+
95+
static_assert (alignof (DerivedKeyAlignmentProbe) >= TC_DERIVED_KEY_BUFFER_ALIGNMENT, "Insufficient derived key buffer alignment");
96+
static_assert (alignof (KeyInfoAlignmentProbe) >= TC_KEY_INFO_BUFFER_ALIGNMENT, "Insufficient key info buffer alignment");
97+
8798
static CRYPTOPP_ALIGN_DATA(TC_DERIVED_KEY_BUFFER_ALIGNMENT) uint8 derivedKeyProbe[TC_ALIGNMENT_PROBE_SIZE];
8899
static CRYPTOPP_ALIGN_DATA(TC_KEY_INFO_BUFFER_ALIGNMENT) uint8 keyInfoProbe[TC_ALIGNMENT_PROBE_SIZE];
89100

0 commit comments

Comments
 (0)