VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Xts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Xts.c')
-rw-r--r--src/Common/Xts.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/Common/Xts.c b/src/Common/Xts.c
index 390eb31e..4a62aaf3 100644
--- a/src/Common/Xts.c
+++ b/src/Common/Xts.c
@@ -27,64 +27,68 @@ For big-endian platforms define BYTE_ORDER as BIG_ENDIAN. */
# include <memory.h>
#endif
#ifndef TC_NO_COMPILER_INT64
#include "cpu.h"
#include "misc.h"
#endif
#include "Xts.h"
#ifndef TC_NO_COMPILER_INT64
// length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size
// ks: the primary key schedule
// ks2: the secondary key schedule
// startDataUnitNo: The sequential number of the data unit with which the buffer starts.
// startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit startDataUnitNo.
// When encrypting the data unit from its first block, startCipherBlockNo is 0.
// The startCipherBlockNo value applies only to the first data unit in the buffer; each successive
// data unit is encrypted from its first block. The start of the buffer does not have to be
// aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it
// is not aligned, startCipherBlockNo must reflect the misalignment accordingly.
void EncryptBufferXTS (unsigned __int8 *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startCipherBlockNo,
unsigned __int8 *ks,
unsigned __int8 *ks2,
int cipher)
{
- if (CipherSupportsIntraDataUnitParallelization (cipher))
+ #ifndef WOLFCRYPT_BACKEND
+ if (CipherSupportsIntraDataUnitParallelization (cipher))
EncryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
else
EncryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
+ #else
+ xts_encrypt(buffer, buffer, length, startDataUnitNo, ks);
+ #endif
}
#if (CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && CRYPTOPP_BOOL_X64)
#define XorBlocks(result,ptr,len,start,end) \
while (len >= 2) \
{ \
__m128i xmm1 = _mm_loadu_si128((const __m128i*) ptr); \
__m128i xmm2 = _mm_loadu_si128((__m128i*)result); \
__m128i xmm3 = _mm_loadu_si128((const __m128i*) (ptr + 2)); \
__m128i xmm4 = _mm_loadu_si128((__m128i*)(result + 2)); \
\
_mm_storeu_si128((__m128i*)result, _mm_xor_si128(xmm1, xmm2)); \
_mm_storeu_si128((__m128i*)(result + 2), _mm_xor_si128(xmm3, xmm4)); \
ptr+= 4; \
result+= 4; \
len -= 2; \
} \
\
if (len) \
{ \
__m128i xmm1 = _mm_loadu_si128((const __m128i*)ptr); \
__m128i xmm2 = _mm_loadu_si128((__m128i*)result); \
\
_mm_storeu_si128((__m128i*)result, _mm_xor_si128(xmm1, xmm2)); \
ptr+= 2; \
result+= 2; \
} \
len = end - start;
@@ -353,64 +357,68 @@ static void EncryptBufferXTSNonParallel (unsigned __int8 *buffer,
whiteningValuePtr64--;
if (*whiteningValuePtr64 & 0x80)
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
#endif
whiteningValue[0] ^= finalCarry;
}
blockCount -= endBlock - startBlock;
startBlock = 0;
dataUnitNo++;
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
}
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
}
// For descriptions of the input parameters, see EncryptBufferXTS().
void DecryptBufferXTS (unsigned __int8 *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startCipherBlockNo,
unsigned __int8 *ks,
unsigned __int8 *ks2,
int cipher)
{
+ #ifndef WOLFCRYPT_BACKEND
if (CipherSupportsIntraDataUnitParallelization (cipher))
DecryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
else
DecryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
+ #else
+ xts_decrypt(buffer, buffer, length, startDataUnitNo, ks);
+ #endif
}
// Optimized for encryption algorithms supporting intra-data-unit parallelization
static void DecryptBufferXTSParallel (unsigned __int8 *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startCipherBlockNo,
unsigned __int8 *ks,
unsigned __int8 *ks2,
int cipher)
{
unsigned __int8 finalCarry;
unsigned __int8 whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
unsigned __int64 *whiteningValuesPtr64 = (unsigned __int64 *) whiteningValues;
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
unsigned __int64 *dataUnitBufPtr;
unsigned int startBlock = startCipherBlockNo, endBlock, block, countBlock;
TC_LARGEST_COMPILER_UINT remainingBlocks, dataUnitNo;
// Convert the 64-bit data unit number into a little-endian 16-byte array.
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
dataUnitNo = startDataUnitNo->Value;
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
if (length % BYTES_PER_XTS_BLOCK)