Fix SIGBUS on Sparc64 (GH #597)

PutAndGetBlock did not handle an unaligned outblock properly. Ugh...
pull/598/head
Jeffrey Walton 2018-03-08 17:01:00 -05:00
parent 3c01bcc352
commit 730eebe233
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 33 additions and 31 deletions

View File

@ -39,16 +39,14 @@ using CryptoPP::ARIATab::X1;
using CryptoPP::ARIATab::X2;
using CryptoPP::ARIATab::KRK;
typedef BlockGetAndPut<word32, BigEndian, false, false> BigEndianBlock;
typedef BlockGetAndPut<word32, NativeByteOrder, true, true> NativeEndianBlock;
inline byte ARIA_BRF(const word32 x, const int y) {
return GETBYTE(x, y);
}
// Key XOR Layer
#define ARIA_KXL { \
NativeEndianBlock::Put(rk, t)(t[0])(t[1])(t[2])(t[3]); \
typedef BlockGetAndPut<word32, NativeByteOrder, true, true> NativeBlock; \
NativeBlock::Put(rk, t)(t[0])(t[1])(t[2])(t[3]); \
}
// S-Box Layer 1 + M
@ -140,7 +138,9 @@ void ARIA::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const Nam
// w0 has room for 32 bytes. w1-w3 each has room for 16 bytes. t and u are 16 byte temp areas.
word32 *w0 = m_w.data(), *w1 = m_w.data()+8, *w2 = m_w.data()+12, *w3 = m_w.data()+16, *t = m_w.data()+20;
BigEndianBlock::Get(mk)(w0[0])(w0[1])(w0[2])(w0[3]);
GetBlock<word32, BigEndian, false>block(key);
block(w0[0])(w0[1])(w0[2])(w0[3]);
t[0]=w0[0]^KRK[q][0]; t[1]=w0[1]^KRK[q][1];
t[2]=w0[2]^KRK[q][2]; t[3]=w0[3]^KRK[q][3];
@ -148,12 +148,13 @@ void ARIA::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const Nam
if (keylen == 32)
{
BigEndianBlock::Get(mk+16)(w1[0])(w1[1])(w1[2])(w1[3]);
GetBlock<word32, BigEndian, false>block(mk+16);
block(w1[0])(w1[1])(w1[2])(w1[3]);
}
else if (keylen == 24)
{
BigEndianBlock::Get(mk+16)(w1[0])(w1[1]);
w1[2] = w1[3] = 0;
GetBlock<word32, BigEndian, false>block(mk+16);
block(w1[0])(w1[1]); w1[2] = w1[3] = 0;
}
else
{
@ -261,7 +262,8 @@ void ARIA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, b
u |= *(S1+i);
t[0] |= u;
BigEndianBlock::Get(inBlock)(t[0])(t[1])(t[2])(t[3]);
GetBlock<word32, BigEndian>block(inBlock);
block(t[0])(t[1])(t[2])(t[3]);
if (m_rounds > 12) {
ARIA_KXL; rk+= 16; ARIA_FO;
@ -280,15 +282,16 @@ void ARIA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, b
ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE;
ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16;
#ifdef CRYPTOPP_LITTLE_ENDIAN
# if CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS
#if CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS
if (HasSSSE3())
{
ARIA_ProcessAndXorBlock_Xor_SSSE3(xorBlock, outBlock, rk, t);
return;
}
else
# endif // CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS
#endif // CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS
#ifdef CRYPTOPP_LITTLE_ENDIAN
{
outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 3];
outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 2];
@ -308,25 +311,24 @@ void ARIA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, b
outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[12];
}
#else
outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] );
outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8);
outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] );
outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] );
outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] );
outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8);
outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] );
outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] );
outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] );
outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8);
outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] );
outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] );
outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] );
outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8);
outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] );
outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] );
t = UINT32_CAST(outBlock);
BigEndianBlock::Put(rk, t)(t[0])(t[1])(t[2])(t[3]);
{
outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 0];
outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 1];
outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ) ^ rk[ 2];
outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ) ^ rk[ 3];
outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ) ^ rk[ 4];
outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8) ^ rk[ 5];
outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ) ^ rk[ 6];
outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ) ^ rk[ 7];
outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ) ^ rk[ 8];
outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8) ^ rk[ 9];
outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ) ^ rk[10];
outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ) ^ rk[11];
outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ) ^ rk[12];
outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8) ^ rk[13];
outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ) ^ rk[14];
outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[15];
}
#endif // CRYPTOPP_LITTLE_ENDIAN
#if CRYPTOPP_ARM_NEON_AVAILABLE