diff --git a/iterhash.cpp b/iterhash.cpp index 91e00af8..e9974ced 100644 --- a/iterhash.cpp +++ b/iterhash.cpp @@ -27,13 +27,14 @@ template void IteratedHashBase::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 void IteratedHashBase::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 void IteratedHashBase::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 size_t IteratedHashBase::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(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 void IteratedHashBase::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 void IteratedHashBase::TruncatedFinal(by else { ConditionalByteReverse(order, stateBuf, stateBuf, this->DigestSize()); - memcpy(digest, stateBuf, size); + std::memcpy(digest, stateBuf, size); } this->Restart(); // reinit for next use diff --git a/iterhash.h b/iterhash.h index 45142f85..06b5f0aa 100644 --- a/iterhash.h +++ b/iterhash.h @@ -95,8 +95,10 @@ public: virtual std::string AlgorithmProvider() const { return "C++"; } protected: - inline T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} - inline T GetBitCountLo() const {return m_countLo << 3;} + inline T GetBitCountHi() const + {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} + inline T GetBitCountLo() const + {return m_countLo << 3;} void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); virtual void Init() =0; @@ -104,7 +106,8 @@ protected: virtual ByteOrder GetByteOrder() const =0; virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; virtual size_t HashMultipleBlocks(const T *input, size_t length); - void HashBlock(const HashWordType *input) {HashMultipleBlocks(input, this->BlockSize());} + void HashBlock(const HashWordType *input) + {HashMultipleBlocks(input, this->BlockSize());} virtual T* DataBuf() =0; virtual T* StateBuf() =0; @@ -151,6 +154,11 @@ public: /// \details CorrectEndianess() calls ConditionalByteReverse() using T_Endianness. inline void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount) { + CRYPTOPP_ASSERT(in != NULLPTR); + CRYPTOPP_ASSERT(out != NULLPTR); + CRYPTOPP_ASSERT(IsAligned(in)); + CRYPTOPP_ASSERT(IsAligned(out)); + ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); }