summaryrefslogtreecommitdiff
path: root/sha.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-07-20 13:24:04 -0400
committerJeffrey Walton <noloader@gmail.com>2018-07-20 13:24:04 -0400
commitca302c952e6393469651e01b7c3ae4686c7e0747 (patch)
treefebb33c08b98f0dd811cfaf775b9e9d352c9e909 /sha.cpp
parent45ffb7e82794a3a023ccbd653f657b5c220135c7 (diff)
downloadcryptopp-git-ca302c952e6393469651e01b7c3ae4686c7e0747.tar.gz
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.
Diffstat (limited to 'sha.cpp')
-rw-r--r--sha.cpp147
1 files changed, 87 insertions, 60 deletions
diff --git a/sha.cpp b/sha.cpp
index ea0b02d3..69577f3d 100644
--- a/sha.cpp
+++ b/sha.cpp
@@ -161,18 +161,18 @@ ANONYMOUS_NAMESPACE_END
std::string SHA1::AlgorithmProvider() const
{
#if CRYPTOPP_SHANI_AVAILABLE
- if (HasSHA())
- return "SHANI";
+ if (HasSHA())
+ return "SHANI";
#endif
#if CRYPTOPP_SSE2_ASM_AVAILABLE
- if (HasSSE2())
- return "SSE2";
+ if (HasSSE2())
+ return "SSE2";
#endif
#if CRYPTOPP_ARM_SHA1_AVAILABLE
- if (HasSHA1())
- return "ARMv8";
+ if (HasSHA1())
+ return "ARMv8";
#endif
- return "C++";
+ return "C++";
}
void SHA1::InitState(HashWordType *state)
@@ -347,27 +347,27 @@ ANONYMOUS_NAMESPACE_END
std::string SHA256_AlgorithmProvider()
{
#if CRYPTOPP_SHANI_AVAILABLE
- if (HasSHA())
- return "SHANI";
+ if (HasSHA())
+ return "SHANI";
#endif
#if CRYPTOPP_SSE2_ASM_AVAILABLE
- if (HasSSE2())
- return "SSE2";
+ if (HasSSE2())
+ return "SSE2";
#endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE
- if (HasSHA2())
- return "ARMv8";
+ if (HasSHA2())
+ return "ARMv8";
#endif
#if (CRYPTOPP_POWER8_SHA_AVAILABLE)
- if (HasSHA256())
- return "Power8";
+ if (HasSHA256())
+ return "Power8";
#endif
- return "C++";
+ return "C++";
}
std::string SHA224::AlgorithmProvider() const
{
- return SHA256_AlgorithmProvider();
+ return SHA256_AlgorithmProvider();
}
void SHA224::InitState(HashWordType *state)
@@ -718,7 +718,7 @@ void CRYPTOPP_FASTCALL SHA256_HashMultipleBlocks_SSE2(word32 *state, const word3
std::string SHA256::AlgorithmProvider() const
{
- return SHA256_AlgorithmProvider();
+ return SHA256_AlgorithmProvider();
}
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()
{
#if CRYPTOPP_SSE2_ASM_AVAILABLE
- if (HasSSE2())
- return "SSE2";
+ if (HasSSE2())
+ return "SSE2";
#endif
#if (CRYPTOPP_POWER8_SHA_AVAILABLE)
- if (HasSHA512())
- return "Power8";
+ if (HasSHA512())
+ return "Power8";
#endif
- return "C++";
+ return "C++";
}
std::string SHA384::AlgorithmProvider() const
{
- return SHA512_AlgorithmProvider();
+ return SHA512_AlgorithmProvider();
}
std::string SHA512::AlgorithmProvider() const
{
- return SHA512_AlgorithmProvider();
+ return SHA512_AlgorithmProvider();
}
void SHA384::InitState(HashWordType *state)
@@ -1166,7 +1166,7 @@ ANONYMOUS_NAMESPACE_BEGIN
#define g(i) T[(6-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 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(data);
- word64 W[16]={0}, T[8];
+ word64 W[16]={0}, D[16], T[8];
+
/* 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 */
for (unsigned int j=0; j<80; j+=16)
{
@@ -1196,39 +1201,38 @@ void SHA512_HashBlock_CXX(word64 *state, const word64 *data)
R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15);
}
- /* Add the working vars back into context.state[] */
- state[0] += a(0);
- state[1] += b(0);
- state[2] += c(0);
- state[3] += d(0);
- state[4] += e(0);
- state[5] += f(0);
- state[6] += g(0);
- state[7] += h(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
+ /* Solaris 11/Sparc64 crash */
+ if (IsAligned<word64>(state) == true)
+ {
+ /* Add the working vars back into context.state[] */
+ state[0] += a(0);
+ state[1] += b(0);
+ state[2] += c(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]));
+ }
+}
ANONYMOUS_NAMESPACE_END
@@ -1255,6 +1259,29 @@ void SHA512::Transform(word64 *state, const word64 *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
#endif // Not CRYPTOPP_GENERATE_X64_MASM