diff options
author | Jeffrey Walton <noloader@gmail.com> | 2018-07-20 18:56:41 -0400 |
---|---|---|
committer | Jeffrey Walton <noloader@gmail.com> | 2018-07-20 18:56:41 -0400 |
commit | 0c0b68a4a28bdcbcf9239b45242d1c3e06788ccc (patch) | |
tree | 22f329a533083061b4d622220d05d2c96ca60182 /iterhash.cpp | |
parent | 365e65c2eba53f8d446df293c60eef6debcf3d02 (diff) | |
download | cryptopp-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.cpp | 33 |
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
|