Fix Tiger crash on Sparc (GH #690)

Man, Sparc does not mess around with unaligned buffers. Without -xmemalign=4i the hardware wants 8-byte aligned word64's so it can use the high performance 64-bit move or add.
Since we do not use -xmemalign we get the default behavior of either -xmemalgin=8i or -xmemalgin=8s. It shoul dnot matter to us since we removed unaligned data access at GH #682.
pull/696/head
Jeffrey Walton 2018-07-20 20:12:54 -04:00
parent 0c0b68a4a2
commit 414c5c5438
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
2 changed files with 23 additions and 7 deletions

View File

@ -33,7 +33,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
if (num+length >= blockSize) if (num+length >= blockSize)
{ {
if (input) if (input)
{memcpy(data+num, input, blockSize-num);} {std::memcpy(data+num, input, blockSize-num);}
HashBlock(dataBuf); HashBlock(dataBuf);
input += (blockSize-num); input += (blockSize-num);
@ -44,7 +44,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
else else
{ {
if (input && length) if (input && length)
{memcpy(data+num, input, length);} {std::memcpy(data+num, input, length);}
return; return;
} }
} }
@ -69,7 +69,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
do do
{ // copy input first if it's not aligned correctly { // copy input first if it's not aligned correctly
if (input) if (input)
{ memcpy(data, input, blockSize); } { std::memcpy(data, input, blockSize); }
HashBlock(dataBuf); HashBlock(dataBuf);
input+=blockSize; input+=blockSize;
@ -79,7 +79,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
} }
if (input && data != input) if (input && data != input)
memcpy(data, input, length); std::memcpy(data, input, length);
} }
template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size) template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size)
@ -92,19 +92,22 @@ template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpa
template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, size_t length) template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, size_t length)
{ {
unsigned int blockSize = this->BlockSize(); const unsigned int blockSize = this->BlockSize();
bool noReverse = NativeByteOrderIs(this->GetByteOrder()); bool noReverse = NativeByteOrderIs(this->GetByteOrder());
T* dataBuf = this->DataBuf(); T* dataBuf = this->DataBuf();
// IteratedHashBase Update calls this with an aligned input, // IteratedHashBase Update calls this with an aligned input,
// but HashBlock may call it with an unaligned buffer. // but HashBlock may call it with an unaligned buffer.
// Alignment checks due to Issues 690/
do do
{ {
if (noReverse) if (noReverse)
{ {
if (IsAligned<word64>(input)) if (IsAligned<word64>(input))
{
this->HashEndianCorrectedBlock(input); this->HashEndianCorrectedBlock(input);
}
else else
{ {
std::memcpy(dataBuf, input, this->BlockSize()); std::memcpy(dataBuf, input, this->BlockSize());
@ -112,10 +115,19 @@ template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlo
} }
} }
else else
{
if (IsAligned<word64>(input))
{ {
ByteReverse(dataBuf, input, this->BlockSize()); ByteReverse(dataBuf, input, this->BlockSize());
this->HashEndianCorrectedBlock(dataBuf); this->HashEndianCorrectedBlock(dataBuf);
} }
else
{
std::memcpy(dataBuf, input, this->BlockSize());
ByteReverse(dataBuf, dataBuf, this->BlockSize());
this->HashEndianCorrectedBlock(dataBuf);
}
}
input += blockSize/sizeof(T); input += blockSize/sizeof(T);
length -= blockSize; length -= blockSize;

4
misc.h
View File

@ -2068,7 +2068,11 @@ inline T ConditionalByteReverse(ByteOrder order, T value)
template <class T> template <class T>
void ByteReverse(T *out, const T *in, size_t byteCount) void ByteReverse(T *out, const T *in, size_t byteCount)
{ {
// Alignment check due to Issues 690
CRYPTOPP_ASSERT(byteCount % sizeof(T) == 0); CRYPTOPP_ASSERT(byteCount % sizeof(T) == 0);
CRYPTOPP_ASSERT(IsAligned<T>(in));
CRYPTOPP_ASSERT(IsAligned<T>(out));
size_t count = byteCount/sizeof(T); size_t count = byteCount/sizeof(T);
for (size_t i=0; i<count; i++) for (size_t i=0; i<count; i++)
out[i] = ByteReverse(in[i]); out[i] = ByteReverse(in[i]);