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:
+2
-2
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user