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::X2;
using CryptoPP::ARIATab::KRK; 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) { inline byte ARIA_BRF(const word32 x, const int y) {
return GETBYTE(x, y); return GETBYTE(x, y);
} }
// Key XOR Layer // Key XOR Layer
#define ARIA_KXL { \ #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 // 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. // 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; 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[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]; 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) 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) else if (keylen == 24)
{ {
BigEndianBlock::Get(mk+16)(w1[0])(w1[1]); GetBlock<word32, BigEndian, false>block(mk+16);
w1[2] = w1[3] = 0; block(w1[0])(w1[1]); w1[2] = w1[3] = 0;
} }
else else
{ {
@ -261,7 +262,8 @@ void ARIA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, b
u |= *(S1+i); u |= *(S1+i);
t[0] |= u; 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) { if (m_rounds > 12) {
ARIA_KXL; rk+= 16; ARIA_FO; 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; ARIA_FE;
ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; 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()) if (HasSSSE3())
{ {
ARIA_ProcessAndXorBlock_Xor_SSSE3(xorBlock, outBlock, rk, t); ARIA_ProcessAndXorBlock_Xor_SSSE3(xorBlock, outBlock, rk, t);
return; return;
} }
else 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[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 3];
outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 2]; 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]; outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[12];
} }
#else #else
outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ); {
outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8); outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 0];
outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ); outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 1];
outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ); outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ) ^ rk[ 2];
outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ); outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ) ^ rk[ 3];
outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8); outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ) ^ rk[ 4];
outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ); outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8) ^ rk[ 5];
outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ); outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ) ^ rk[ 6];
outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ); outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ) ^ rk[ 7];
outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8); outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ) ^ rk[ 8];
outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ); outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8) ^ rk[ 9];
outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ); outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ) ^ rk[10];
outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ); outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ) ^ rk[11];
outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8); outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ) ^ rk[12];
outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ); outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8) ^ rk[13];
outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ); outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ) ^ rk[14];
outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[15];
t = UINT32_CAST(outBlock); }
BigEndianBlock::Put(rk, t)(t[0])(t[1])(t[2])(t[3]);
#endif // CRYPTOPP_LITTLE_ENDIAN #endif // CRYPTOPP_LITTLE_ENDIAN
#if CRYPTOPP_ARM_NEON_AVAILABLE #if CRYPTOPP_ARM_NEON_AVAILABLE