1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-13 08:17:00 -05:00

Align key schedules and fix Camellia SSSE3 dispatch

Align CRYPTO_INFO primary and secondary key-schedule buffers so cipher implementations can safely use word-sized schedule access on VeraCrypt-managed storage.

Keep generic Camellia direct uint64 schedule indexing. Builds that define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS use direct 64-bit key and block byte loads/stores; memcpy is retained only for strict-alignment builds.

Require SSSE3 before using the x64 AESNI 16-way Camellia path because the assembly uses pshufb in addition to AES and AVX.
This commit is contained in:
Mounir IDRASSI
2026-06-03 15:42:08 +09:00
parent aab9e38894
commit 612bccbd1a
2 changed files with 57 additions and 18 deletions
+2 -2
View File
@@ -254,8 +254,8 @@ typedef struct CRYPTO_INFO_t
int mode; /* Mode of operation (e.g., XTS) */ int mode; /* Mode of operation (e.g., XTS) */
int pkcs5; /* PRF algorithm */ int pkcs5; /* PRF algorithm */
unsigned __int8 ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */ CRYPTOPP_ALIGN_DATA(16) unsigned __int8 ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */
unsigned __int8 ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */ CRYPTOPP_ALIGN_DATA(16) unsigned __int8 ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */
BOOL hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume BOOL hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume
+55 -16
View File
@@ -1096,7 +1096,7 @@ void camellia_decrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock
void camellia_encrypt_blocks(unsigned __int8 *instance, const uint8* in_blk, uint8* out_blk, uint32 blockCount) void camellia_encrypt_blocks(unsigned __int8 *instance, const uint8* in_blk, uint8* out_blk, uint32 blockCount)
{ {
#if !defined (_UEFI) #if !defined (_UEFI)
if ((blockCount >= 16) && IsCpuIntel() && IsAesHwCpuSupported () && HasSAVX()) /* on AMD cpu, AVX is too slow */ if ((blockCount >= 16) && IsCpuIntel() && IsAesHwCpuSupported () && HasSAVX() && HasSSSE3()) /* on AMD cpu, AVX is too slow */
{ {
#if defined (TC_WINDOWS_DRIVER) #if defined (TC_WINDOWS_DRIVER)
XSTATE_SAVE SaveState; XSTATE_SAVE SaveState;
@@ -1132,7 +1132,7 @@ void camellia_encrypt_blocks(unsigned __int8 *instance, const uint8* in_blk, uin
void camellia_decrypt_blocks(unsigned __int8 *instance, const uint8* in_blk, uint8* out_blk, uint32 blockCount) void camellia_decrypt_blocks(unsigned __int8 *instance, const uint8* in_blk, uint8* out_blk, uint32 blockCount)
{ {
#if !defined (_UEFI) #if !defined (_UEFI)
if ((blockCount >= 16) && IsCpuIntel() && IsAesHwCpuSupported () && HasSAVX()) /* on AMD cpu, AVX is too slow */ if ((blockCount >= 16) && IsCpuIntel() && IsAesHwCpuSupported () && HasSAVX() && HasSSSE3()) /* on AMD cpu, AVX is too slow */
{ {
#if defined (TC_WINDOWS_DRIVER) #if defined (TC_WINDOWS_DRIVER)
XSTATE_SAVE SaveState; XSTATE_SAVE SaveState;
@@ -1493,14 +1493,53 @@ static const uint64 S[8][256] = {
return (r << n) | (l >> (64 - n)); return (r << n) | (l >> (64 - n));
} }
#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
# define CAMELLIA_ALLOW_UNALIGNED_DATA_ACCESS
#endif
VC_INLINE uint64 camellia_load64(const void *ptr)
{
#ifdef CAMELLIA_ALLOW_UNALIGNED_DATA_ACCESS
return *(const uint64 *)ptr;
#else
uint64 value;
memcpy(&value, ptr, sizeof(value));
return value;
#endif
}
VC_INLINE void camellia_store64(void *ptr, uint64 value)
{
#ifdef CAMELLIA_ALLOW_UNALIGNED_DATA_ACCESS
*(uint64 *)ptr = value;
#else
memcpy(ptr, &value, sizeof(value));
#endif
}
#ifdef CAMELLIA_ALLOW_UNALIGNED_DATA_ACCESS
# undef CAMELLIA_ALLOW_UNALIGNED_DATA_ACCESS
#endif
VC_INLINE uint64 camellia_load_be64(const unsigned __int8 *ptr)
{
return bswap_64(camellia_load64(ptr));
}
VC_INLINE void camellia_store_be64(unsigned __int8 *ptr, uint64 value)
{
value = bswap_64(value);
camellia_store64(ptr, value);
}
void camellia_set_key(const unsigned __int8 key[], unsigned __int8 *ksPtr) void camellia_set_key(const unsigned __int8 key[], unsigned __int8 *ksPtr)
{ {
uint64 *ks = (uint64 *) ksPtr; uint64 *ks = (uint64 *) ksPtr;
uint64 kll = bswap_64(*((uint64*)key)); uint64 kll = camellia_load_be64(key);
uint64 klr = bswap_64(*((uint64*)(key + 8))); uint64 klr = camellia_load_be64(key + 8);
uint64 krl = bswap_64(*((uint64*)(key + 16))); uint64 krl = camellia_load_be64(key + 16);
uint64 krr = bswap_64(*((uint64*)(key + 24))); uint64 krr = camellia_load_be64(key + 24);
#ifdef CPPCRYPTO_DEBUG #ifdef CPPCRYPTO_DEBUG
printf("kl: %016I64x %016I64x\n", kll, klr); printf("kl: %016I64x %016I64x\n", kll, klr);
@@ -1582,9 +1621,9 @@ void camellia_set_key(const unsigned __int8 key[], unsigned __int8 *ksPtr)
void camellia_encrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned __int8 *ksPtr) void camellia_encrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned __int8 *ksPtr)
{ {
uint64 *ks = (uint64 *) ksPtr; const uint64 *ks = (const uint64 *) ksPtr;
uint64 l = bswap_64(*((uint64*)in)) ^ ks[0]; uint64 l = camellia_load_be64(in) ^ ks[0];
uint64 r = bswap_64(*((uint64*)(in + 8))) ^ ks[1]; uint64 r = camellia_load_be64(in + 8) ^ ks[1];
#ifdef CPPCRYPTO_DEBUG #ifdef CPPCRYPTO_DEBUG
printf("r0: %016I64x %016I64x\n", l, r); printf("r0: %016I64x %016I64x\n", l, r);
@@ -1713,16 +1752,16 @@ void camellia_encrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned
r ^= ks[32]; r ^= ks[32];
l ^= ks[33]; l ^= ks[33];
*(uint64*)out = bswap_64(r); camellia_store_be64(out, r);
*(uint64*)(out + 8) = bswap_64(l); camellia_store_be64(out + 8, l);
} }
void camellia_decrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned __int8 *ksPtr) void camellia_decrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned __int8 *ksPtr)
{ {
uint64 *ks = (uint64 *) ksPtr; const uint64 *ks = (const uint64 *) ksPtr;
uint64 r = bswap_64(*((uint64*)in)) ^ ks[32]; uint64 r = camellia_load_be64(in) ^ ks[32];
uint64 l = bswap_64(*((uint64*)(in + 8))) ^ ks[33]; uint64 l = camellia_load_be64(in + 8) ^ ks[33];
#ifdef CPPCRYPTO_DEBUG #ifdef CPPCRYPTO_DEBUG
printf("DECRYPT: %016I64x %016I64x\n", l, r); printf("DECRYPT: %016I64x %016I64x\n", l, r);
@@ -1880,8 +1919,8 @@ void camellia_decrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned
l ^= ks[0]; l ^= ks[0];
r ^= ks[1]; r ^= ks[1];
*(uint64*)out = bswap_64(l); camellia_store_be64(out, l);
*(uint64*)(out + 8) = bswap_64(r); camellia_store_be64(out + 8, r);
} }
#endif #endif