Fix Solaris 11/Sparc crash in SHA-384 (GH #689, GH #403)

I believe Andrew Marlow first reported it. At the time we could not get our hands on hardware to fully test things. Instead we were using -xmemalign=4i option as a band-aide to avoid running afoul of the Sparc instruction that moves 64-bits of data in one shot.
pull/696/head
Jeffrey Walton 2018-07-20 13:24:04 -04:00
parent 45ffb7e827
commit ca302c952e
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
3 changed files with 88 additions and 65 deletions

View File

@ -566,10 +566,6 @@ CXXFLAGS += -KPIC
endif endif
# Add to all Solaris # Add to all Solaris
CXXFLAGS += -template=no%extdef CXXFLAGS += -template=no%extdef
# http://github.com/weidai11/cryptopp/issues/403
ifneq ($(IS_SPARC32)$(IS_SPARC64),00)
CXXFLAGS += -xmemalign=4i
endif
SUN_CC10_BUGGY := $(shell $(CXX) -V 2>&1 | $(GREP) -c -E "CC: Sun .* 5\.10 .* (2009|2010/0[1-4])") SUN_CC10_BUGGY := $(shell $(CXX) -V 2>&1 | $(GREP) -c -E "CC: Sun .* 5\.10 .* (2009|2010/0[1-4])")
ifneq ($(SUN_CC10_BUGGY),0) ifneq ($(SUN_CC10_BUGGY),0)
# -DCRYPTOPP_INCLUDE_VECTOR_CC is needed for Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 and was fixed in May 2010 # -DCRYPTOPP_INCLUDE_VECTOR_CC is needed for Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 and was fixed in May 2010

147
sha.cpp
View File

@ -161,18 +161,18 @@ ANONYMOUS_NAMESPACE_END
std::string SHA1::AlgorithmProvider() const std::string SHA1::AlgorithmProvider() const
{ {
#if CRYPTOPP_SHANI_AVAILABLE #if CRYPTOPP_SHANI_AVAILABLE
if (HasSHA()) if (HasSHA())
return "SHANI"; return "SHANI";
#endif #endif
#if CRYPTOPP_SSE2_ASM_AVAILABLE #if CRYPTOPP_SSE2_ASM_AVAILABLE
if (HasSSE2()) if (HasSSE2())
return "SSE2"; return "SSE2";
#endif #endif
#if CRYPTOPP_ARM_SHA1_AVAILABLE #if CRYPTOPP_ARM_SHA1_AVAILABLE
if (HasSHA1()) if (HasSHA1())
return "ARMv8"; return "ARMv8";
#endif #endif
return "C++"; return "C++";
} }
void SHA1::InitState(HashWordType *state) void SHA1::InitState(HashWordType *state)
@ -347,27 +347,27 @@ ANONYMOUS_NAMESPACE_END
std::string SHA256_AlgorithmProvider() std::string SHA256_AlgorithmProvider()
{ {
#if CRYPTOPP_SHANI_AVAILABLE #if CRYPTOPP_SHANI_AVAILABLE
if (HasSHA()) if (HasSHA())
return "SHANI"; return "SHANI";
#endif #endif
#if CRYPTOPP_SSE2_ASM_AVAILABLE #if CRYPTOPP_SSE2_ASM_AVAILABLE
if (HasSSE2()) if (HasSSE2())
return "SSE2"; return "SSE2";
#endif #endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE #if CRYPTOPP_ARM_SHA2_AVAILABLE
if (HasSHA2()) if (HasSHA2())
return "ARMv8"; return "ARMv8";
#endif #endif
#if (CRYPTOPP_POWER8_SHA_AVAILABLE) #if (CRYPTOPP_POWER8_SHA_AVAILABLE)
if (HasSHA256()) if (HasSHA256())
return "Power8"; return "Power8";
#endif #endif
return "C++"; return "C++";
} }
std::string SHA224::AlgorithmProvider() const std::string SHA224::AlgorithmProvider() const
{ {
return SHA256_AlgorithmProvider(); return SHA256_AlgorithmProvider();
} }
void SHA224::InitState(HashWordType *state) void SHA224::InitState(HashWordType *state)
@ -718,7 +718,7 @@ void CRYPTOPP_FASTCALL SHA256_HashMultipleBlocks_SSE2(word32 *state, const word3
std::string SHA256::AlgorithmProvider() const std::string SHA256::AlgorithmProvider() const
{ {
return SHA256_AlgorithmProvider(); return SHA256_AlgorithmProvider();
} }
void SHA256::Transform(word32 *state, const word32 *data) void SHA256::Transform(word32 *state, const word32 *data)
@ -868,24 +868,24 @@ size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length)
std::string SHA512_AlgorithmProvider() std::string SHA512_AlgorithmProvider()
{ {
#if CRYPTOPP_SSE2_ASM_AVAILABLE #if CRYPTOPP_SSE2_ASM_AVAILABLE
if (HasSSE2()) if (HasSSE2())
return "SSE2"; return "SSE2";
#endif #endif
#if (CRYPTOPP_POWER8_SHA_AVAILABLE) #if (CRYPTOPP_POWER8_SHA_AVAILABLE)
if (HasSHA512()) if (HasSHA512())
return "Power8"; return "Power8";
#endif #endif
return "C++"; return "C++";
} }
std::string SHA384::AlgorithmProvider() const std::string SHA384::AlgorithmProvider() const
{ {
return SHA512_AlgorithmProvider(); return SHA512_AlgorithmProvider();
} }
std::string SHA512::AlgorithmProvider() const std::string SHA512::AlgorithmProvider() const
{ {
return SHA512_AlgorithmProvider(); return SHA512_AlgorithmProvider();
} }
void SHA384::InitState(HashWordType *state) void SHA384::InitState(HashWordType *state)
@ -1166,7 +1166,7 @@ ANONYMOUS_NAMESPACE_BEGIN
#define g(i) T[(6-i)&7] #define g(i) T[(6-i)&7]
#define h(i) T[(7-i)&7] #define h(i) T[(7-i)&7]
#define blk0(i) (W[i]=data[i]) #define blk0(i) (W[i]=D[i])
#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z))) #define Ch(x,y,z) (z^(x&(y^z)))
@ -1185,9 +1185,14 @@ void SHA512_HashBlock_CXX(word64 *state, const word64 *data)
CRYPTOPP_ASSERT(state); CRYPTOPP_ASSERT(state);
CRYPTOPP_ASSERT(data); CRYPTOPP_ASSERT(data);
word64 W[16]={0}, T[8]; word64 W[16]={0}, D[16], T[8];
/* Copy context->state[] to working vars */ /* Copy context->state[] to working vars */
memcpy(T, state, sizeof(T)); std::memcpy(T, state, sizeof(T));
/* Solaris/Sparc64 crash */
std::memcpy(D, data, sizeof(D));
/* 80 operations, partially loop unrolled */ /* 80 operations, partially loop unrolled */
for (unsigned int j=0; j<80; j+=16) for (unsigned int j=0; j<80; j+=16)
{ {
@ -1196,40 +1201,39 @@ void SHA512_HashBlock_CXX(word64 *state, const word64 *data)
R( 8); R( 9); R(10); R(11); R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15); R(12); R(13); R(14); R(15);
} }
/* Add the working vars back into context.state[] */
state[0] += a(0); /* Solaris 11/Sparc64 crash */
state[1] += b(0); if (IsAligned<word64>(state) == true)
state[2] += c(0); {
state[3] += d(0); /* Add the working vars back into context.state[] */
state[4] += e(0); state[0] += a(0);
state[5] += f(0); state[1] += b(0);
state[6] += g(0); state[2] += c(0);
state[7] += h(0); state[3] += d(0);
state[4] += e(0);
state[5] += f(0);
state[6] += g(0);
state[7] += h(0);
}
else
{
/* Reuse W[] */
std::memcpy(W, state, 8 * sizeof(W[0]));
/* Add the working vars back into context.state[] */
W[0] += a(0);
W[1] += b(0);
W[2] += c(0);
W[3] += d(0);
W[4] += e(0);
W[5] += f(0);
W[6] += g(0);
W[7] += h(0);
std::memcpy(state, W, 8 * sizeof(W[0]));
}
} }
#undef Ch
#undef Maj
#undef s0
#undef s1
#undef S0
#undef S1
#undef blk0
#undef blk1
#undef blk2
#undef R
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g
#undef h
ANONYMOUS_NAMESPACE_END ANONYMOUS_NAMESPACE_END
void SHA512::Transform(word64 *state, const word64 *data) void SHA512::Transform(word64 *state, const word64 *data)
@ -1255,6 +1259,29 @@ void SHA512::Transform(word64 *state, const word64 *data)
SHA512_HashBlock_CXX(state, data); SHA512_HashBlock_CXX(state, data);
} }
#undef Ch
#undef Maj
#undef s0
#undef s1
#undef S0
#undef S1
#undef blk0
#undef blk1
#undef blk2
#undef R
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g
#undef h
NAMESPACE_END NAMESPACE_END
#endif // Not CRYPTOPP_GENERATE_X64_MASM #endif // Not CRYPTOPP_GENERATE_X64_MASM

View File

@ -759,7 +759,7 @@ int crypto_sign_sk2pk(byte *pk, const byte *sk)
{ {
byte d[64]; byte d[64];
gf p[4]; gf p[4];
int i; // int i;
// randombytes(sk, 32); // randombytes(sk, 32);
crypto_hash(d, sk, 32); crypto_hash(d, sk, 32);