VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Crypto/Whirlpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Crypto/Whirlpool.c')
-rw-r--r--src/Crypto/Whirlpool.c78
1 files changed, 49 insertions, 29 deletions
diff --git a/src/Crypto/Whirlpool.c b/src/Crypto/Whirlpool.c
index 308f4812..140c7c6f 100644
--- a/src/Crypto/Whirlpool.c
+++ b/src/Crypto/Whirlpool.c
@@ -642,13 +642,27 @@ static const uint64 Whirlpool_C[8*256+R] = {
// Whirlpool basic transformation. Transforms state based on block.
void WhirlpoolTransform(uint64 *digest, const uint64 *block)
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+#if defined(__GNUC__) && (CRYPTOPP_GCC_VERSION <= 40407)
+ /* workaround for gcc 4.4.7 bug under CentOS which causes crash
+ * in inline assembly.
+ * This dummy check that is always false since "block" is aligned.
+ */
+ uint64 lb = (uint64) block;
+ if (lb % 16)
+ {
+ TC_THROW_FATAL_EXCEPTION;
+ }
+#endif
+#endif
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
if (HasISSE())
{
#ifdef __GNUC__
#if CRYPTOPP_BOOL_X64
- uint64 workspace[16];
+ CRYPTOPP_ALIGN_DATA(16) uint64 workspace[16];
#endif
__asm__ __volatile__
(
INTEL_NOPREFIX
@@ -879,9 +893,9 @@ static uint64 HashMultipleBlocks(WHIRLPOOL_CTX * const ctx, const uint64 *input,
{
#if BYTE_ORDER == BIG_ENDIAN
WhirlpoolTransform(ctx->state, input);
#else
- CorrectEndianess(dataBuf, input, 64);
+ CorrectEndianness(dataBuf, input, 64);
WhirlpoolTransform(ctx->state, dataBuf);
#endif
input += 8;
length -= 64;
@@ -921,9 +935,9 @@ void WHIRLPOOL_add(const unsigned char * input,
return;
else
{
uint64* dataBuf = ctx->data;
- byte* data = (byte *)dataBuf;
+ uint8* data = (uint8 *)dataBuf;
num = oldCountLo & 63;
if (num != 0) // process left over data
{
@@ -932,9 +946,8 @@ void WHIRLPOOL_add(const unsigned char * input,
memcpy(data+num, input, (size_t) (64-num));
HashMultipleBlocks(ctx, dataBuf, 64);
input += (64-num);
len -= (64-num);
- num = 0;
// drop through and do the rest
}
else
{
@@ -943,30 +956,37 @@ void WHIRLPOOL_add(const unsigned char * input,
}
}
// now process the input data in blocks of 64 bytes and save the leftovers to ctx->data
- if (len >= 64)
- {
- if (input == data)
- {
- HashMultipleBlocks(ctx, dataBuf, 64);
- return;
- }
- else if (IsAligned16(input))
- {
- uint64 leftOver = HashMultipleBlocks(ctx, (uint64 *)input, len);
- input += (len - leftOver);
- len = leftOver;
- }
- else
- do
- { // copy input first if it's not aligned correctly
- memcpy(data, input, 64);
- HashMultipleBlocks(ctx, dataBuf, 64);
- input+=64;
- len-=64;
- } while (len >= 64);
- }
+ if (len >= 64)
+ {
+ if (input == data)
+ {
+ HashMultipleBlocks(ctx, dataBuf, 64);
+ return;
+ }
+ else
+ {
+#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+ if (IsAligned16(input))
+#endif
+ {
+ uint64 leftOver = HashMultipleBlocks(ctx, (uint64*)input, len);
+ input += (len - leftOver);
+ len = leftOver;
+ }
+#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+ else
+ do
+ { // copy input first if it's not aligned correctly
+ memcpy(data, input, 64);
+ HashMultipleBlocks(ctx, dataBuf, 64);
+ input += 64;
+ len -= 64;
+ } while (len >= 64);
+#endif
+ }
+ }
if (len && data != input)
memcpy(data, input, (size_t) len);
}
@@ -982,9 +1002,9 @@ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx,
{
unsigned int num = ctx->countLo & 63;
uint64* dataBuf = ctx->data;
uint64* stateBuf = ctx->state;
- byte* data = (byte *)dataBuf;
+ uint8* data = (uint8 *)dataBuf;
data[num++] = 0x80;
if (num <= 32)
memset(data+num, 0, 32-num);
@@ -994,9 +1014,9 @@ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx,
HashMultipleBlocks(ctx, dataBuf, 64);
memset(data, 0, 32);
}
#if BYTE_ORDER == LITTLE_ENDIAN
- CorrectEndianess(dataBuf, dataBuf, 32);
+ CorrectEndianness(dataBuf, dataBuf, 32);
#endif
dataBuf[4] = 0;
dataBuf[5] = 0;
@@ -1004,8 +1024,8 @@ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx,
dataBuf[7] = ctx->countLo << 3;
WhirlpoolTransform(stateBuf, dataBuf);
#if BYTE_ORDER == LITTLE_ENDIAN
- CorrectEndianess(stateBuf, stateBuf, 64);
+ CorrectEndianness(stateBuf, stateBuf, 64);
#endif
memcpy(result, stateBuf, 64);
}