summaryrefslogtreecommitdiff
path: root/iterhash.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-07-20 18:56:41 -0400
committerJeffrey Walton <noloader@gmail.com>2018-07-20 18:56:41 -0400
commit0c0b68a4a28bdcbcf9239b45242d1c3e06788ccc (patch)
tree22f329a533083061b4d622220d05d2c96ca60182 /iterhash.cpp
parent365e65c2eba53f8d446df293c60eef6debcf3d02 (diff)
downloadcryptopp-git-0c0b68a4a28bdcbcf9239b45242d1c3e06788ccc.tar.gz
Align input buffer in HashMultipleBlocks
IteratedHashBase::Update aligns the buffer, but IteratedHashBase::HashBlock does not. It was causing a fair number of asserts to fire when the code was instrumented with alignment checks. Linux benchmarks shows the code does not run materially slower on i686 or x86_64.
Diffstat (limited to 'iterhash.cpp')
-rw-r--r--iterhash.cpp33
1 files changed, 26 insertions, 7 deletions
diff --git a/iterhash.cpp b/iterhash.cpp
index 91e00af8..e9974ced 100644
--- a/iterhash.cpp
+++ b/iterhash.cpp
@@ -27,13 +27,14 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
T* dataBuf = this->DataBuf();
byte* data = (byte *)dataBuf;
- CRYPTOPP_ASSERT(dataBuf && data);
if (num != 0) // process left over data
{
if (num+length >= blockSize)
{
- if (data && input) {memcpy(data+num, input, blockSize-num);}
+ if (input)
+ {memcpy(data+num, input, blockSize-num);}
+
HashBlock(dataBuf);
input += (blockSize-num);
length -= (blockSize-num);
@@ -42,7 +43,8 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
}
else
{
- if (data && input && length) {memcpy(data+num, input, length);}
+ if (input && length)
+ {memcpy(data+num, input, length);}
return;
}
}
@@ -63,16 +65,20 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
length = leftOver;
}
else
+ {
do
{ // copy input first if it's not aligned correctly
- if (data && input) memcpy(data, input, blockSize);
+ if (input)
+ { memcpy(data, input, blockSize); }
+
HashBlock(dataBuf);
input+=blockSize;
length-=blockSize;
} while (length >= blockSize);
+ }
}
- if (data && input && data != input)
+ if (input && data != input)
memcpy(data, input, length);
}
@@ -89,10 +95,22 @@ template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlo
unsigned int blockSize = this->BlockSize();
bool noReverse = NativeByteOrderIs(this->GetByteOrder());
T* dataBuf = this->DataBuf();
+
+ // IteratedHashBase Update calls this with an aligned input,
+ // but HashBlock may call it with an unaligned buffer.
+
do
{
if (noReverse)
- this->HashEndianCorrectedBlock(input);
+ {
+ if (IsAligned<word64>(input))
+ this->HashEndianCorrectedBlock(input);
+ else
+ {
+ std::memcpy(dataBuf, input, this->BlockSize());
+ this->HashEndianCorrectedBlock(dataBuf);
+ }
+ }
else
{
ByteReverse(dataBuf, input, this->BlockSize());
@@ -112,6 +130,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsi
unsigned int num = ModPowerOf2(m_countLo, blockSize);
T* dataBuf = this->DataBuf();
byte* data = (byte *)dataBuf;
+
data[num++] = padFirst;
if (num <= lastBlockSize)
memset(data+num, 0, lastBlockSize-num);
@@ -150,7 +169,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::TruncatedFinal(by
else
{
ConditionalByteReverse<HashWordType>(order, stateBuf, stateBuf, this->DigestSize());
- memcpy(digest, stateBuf, size);
+ std::memcpy(digest, stateBuf, size);
}
this->Restart(); // reinit for next use