diff --git a/cpu.cpp b/cpu.cpp
index 4a06385b..827aa8c7 100644
--- a/cpu.cpp
+++ b/cpu.cpp
@@ -625,14 +625,14 @@ void DetectArmFeatures()
bool CRYPTOPP_SECTION_INIT g_PowerpcDetectionDone = false;
bool CRYPTOPP_SECTION_INIT g_hasAltivec = false, CRYPTOPP_SECTION_INIT g_hasPower8 = false;
-bool CRYPTOPP_SECTION_INIT g_hasAES = false, CRYPTOPP_SECTION_INIT g_hasSHA1 = false, CRYPTOPP_SECTION_INIT g_hasSHA2 = false;
+bool CRYPTOPP_SECTION_INIT g_hasAES = false, CRYPTOPP_SECTION_INIT g_hasSHA256 = false, CRYPTOPP_SECTION_INIT g_hasSHA512 = false;
word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
extern bool CPU_ProbeAltivec();
extern bool CPU_ProbePower8();
extern bool CPU_ProbeAES();
-extern bool CPU_ProbeSHA1();
-extern bool CPU_ProbeSHA2();
+extern bool CPU_ProbeSHA256();
+extern bool CPU_ProbeSHA512();
#ifndef PPC_FEATURE_HAS_ALTIVEC
# define PPC_FEATURE_HAS_ALTIVEC 0x10000000
@@ -691,7 +691,7 @@ inline bool CPU_QueryAES()
return false;
}
-inline bool CPU_QuerySHA1()
+inline bool CPU_QuerySHA256()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
@@ -703,7 +703,7 @@ inline bool CPU_QuerySHA1()
#endif
return false;
}
-inline bool CPU_QuerySHA2()
+inline bool CPU_QuerySHA512()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
@@ -724,8 +724,8 @@ void DetectPowerpcFeatures()
g_hasPower8 = CPU_QueryPower8() || CPU_ProbePower8();
//g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
- g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1();
- g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2();
+ g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256();
+ g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512();
#if defined(_AIX)
// /usr/include/sys/systemcfg.h
diff --git a/cpu.h b/cpu.h
index 9e2b7572..35710a93 100644
--- a/cpu.h
+++ b/cpu.h
@@ -398,7 +398,7 @@ inline bool HasSHA2()
// Hide from Doxygen
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
extern bool g_PowerpcDetectionDone;
-extern bool g_hasAltivec, g_hasPower7, g_hasPower8, g_hasAES, g_hasSHA1, g_hasSHA2;
+extern bool g_hasAltivec, g_hasPower7, g_hasPower8, g_hasAES, g_hasSHA256, g_hasSHA512;
extern word32 g_cacheLineSize;
void CRYPTOPP_API DetectPowerpcFeatures();
#endif // CRYPTOPP_DOXYGEN_PROCESSING
@@ -445,32 +445,32 @@ inline bool HasAES()
return g_hasAES;
}
-//! \brief Determine if a PowerPC processor has SHA1 available
-//! \returns true if the hardware is capable of SHA1 at runtime, false otherwise.
+//! \brief Determine if a PowerPC processor has SHA256 available
+//! \returns true if the hardware is capable of SHA256 at runtime, false otherwise.
//! \details SHA is part of the in-crypto extensions on Power8 and Power9.
//! \details Runtime support requires compile time support. When compiling with GCC, you may
//! need to compile with -mcpu=power8; while IBM XL C/C++ compilers require
//! -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro.
//! \note This function is only available on PowerPC and PowerPC-64 platforms
-inline bool HasSHA1()
+inline bool HasSHA256()
{
if (!g_PowerpcDetectionDone)
DetectPowerpcFeatures();
- return g_hasSHA1;
+ return g_hasSHA256;
}
-//! \brief Determine if a PowerPC processor has SHA2 available
-//! \returns true if the hardware is capable of SHA2 at runtime, false otherwise.
+//! \brief Determine if a PowerPC processor has SHA512 available
+//! \returns true if the hardware is capable of SHA512 at runtime, false otherwise.
//! \details SHA is part of the in-crypto extensions on Power8 and Power9.
//! \details Runtime support requires compile time support. When compiling with GCC, you may
//! need to compile with -mcpu=power8; while IBM XL C/C++ compilers require
//! -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro.
//! \note This function is only available on PowerPC and PowerPC-64 platforms
-inline bool HasSHA2()
+inline bool HasSHA512()
{
if (!g_PowerpcDetectionDone)
DetectPowerpcFeatures();
- return g_hasSHA2;
+ return g_hasSHA512;
}
//! \brief Provides the cache line size
diff --git a/ppc-simd.cpp b/ppc-simd.cpp
index 7fc18503..cabe8e7c 100644
--- a/ppc-simd.cpp
+++ b/ppc-simd.cpp
@@ -23,22 +23,9 @@
# undef CRYPTOPP_POWER8_CRYPTO_AVAILABLE
#endif
-#if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
-# include
-# undef vector
-# undef pixel
-# undef bool
-#endif
-
-#if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
-# if defined(CRYPTOPP_XLC_VERSION)
- // #include
- typedef __vector unsigned char uint8x16_p8;
- typedef __vector unsigned long long uint64x2_p8;
-#elif defined(CRYPTOPP_GCC_VERSION)
- typedef __vector unsigned char uint8x16_p8;
- typedef __vector unsigned long long uint64x2_p8;
- #endif
+// TODO.. Change to CRYPTOPP_POWER8_CRYPTO_AVAILABLE
+#if (CRYPTOPP_POWER8_AES_AVAILABLE)
+# include "ppc-crypto.h"
#endif
#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
@@ -94,14 +81,14 @@ bool CPU_ProbeAltivec()
const byte b2[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
CRYPTOPP_ALIGN_DATA(16) byte b3[16];
#if defined(CRYPTOPP_XLC_VERSION)
- const uint8x16_p8 v1 = vec_ld(0, (const byte*)b1);
- const uint8x16_p8 v2 = vec_ld(0, (const byte*)b2);
- const uint8x16_p8 v3 = vec_xor(v1, v2);
+ const uint8x16_p8 v1 = VectorLoad(0, b1);
+ const uint8x16_p8 v2 = VectorLoad(0, b2);
+ const uint8x16_p8 v3 = VectorXor(v1, v2);
vec_st(v3, 0, (byte*)b3);
#elif defined(CRYPTOPP_GCC_VERSION)
- const uint64x2_p8 v1 = (uint64x2_p8)vec_ld(0, (const byte*)b1);
- const uint64x2_p8 v2 = (uint64x2_p8)vec_ld(0, (const byte*)b2);
- const uint64x2_p8 v3 = (uint64x2_p8)vec_xor(v1, v2);
+ const uint64x2_p8 v1 = (uint64x2_p8)VectorLoad(0, b1);
+ const uint64x2_p8 v2 = (uint64x2_p8)VectorLoad(0, b2);
+ const uint64x2_p8 v3 = (uint64x2_p8)VectorXor(v1, v2);
vec_st((uint8x16_p8)v3, 0, (byte*)b3);
#endif
result = (0 == std::memcmp(b2, b3, 16));
@@ -121,7 +108,7 @@ bool CPU_ProbePower7()
{
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
-#elif (CRYPTOPP_POWER7_AVAILABLE)
+#elif (CRYPTOPP_POWER7_AVAILABLE) && 0
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@@ -140,17 +127,7 @@ bool CPU_ProbePower7()
result = false;
else
{
- CRYPTOPP_ALIGN_DATA(16) // Non-const due to XL C/C++
- byte b1[19] = {-1, -1, -1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
- CRYPTOPP_ALIGN_DATA(16) byte b2[16];
-#if defined(CRYPTOPP_XLC_VERSION)
- const uint8x16_p8 v1 = vec_xl(0, (const byte*)b1+3);
- vec_xst(v1, 0, (byte*)b2);
-#elif defined(CRYPTOPP_GCC_VERSION)
- const uint8x16_p8 v1 = vec_vsx_ld(0, b1+3);
- vec_vsx_st(v1, 0, (byte*)b2);
-#endif
- result = (0 == std::memcmp(b1+3, b2, 16));
+ // TODO
}
sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
@@ -186,17 +163,11 @@ bool CPU_ProbePower8()
result = false;
else
{
- CRYPTOPP_ALIGN_DATA(16) // Non-const due to XL C/C++
- byte b1[19] = {255, 255, 255, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
- CRYPTOPP_ALIGN_DATA(16) byte b2[16];
-#if defined(CRYPTOPP_XLC_VERSION)
- const uint8x16_p8 v1 = vec_xl(0, reinterpret_cast(b1)+3);
- vec_xst(v1, 0, reinterpret_cast(b2));
-#elif defined(CRYPTOPP_GCC_VERSION)
- const uint8x16_p8 v1 = vec_vsx_ld(0, b1+3);
- vec_vsx_st(v1, 0, b2);
-#endif
- result = (0 == std::memcmp(b1+3, b2, 16));
+ byte b1[19] = {255, 255, 255, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, b2[17];
+ const uint8x16_p8 v1 = (uint8x16_p8)VectorLoad(0, b1+3);
+ VectorStore(v1, b2+1);
+
+ result = (0 == std::memcmp(b1+3, b2+1, 16));
}
sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
@@ -231,24 +202,16 @@ bool CPU_ProbeAES()
result = false;
else
{
- CRYPTOPP_ALIGN_DATA(16) // Non-const due to XL C/C++
byte key[16] = {0xA0, 0xFA, 0xFE, 0x17, 0x88, 0x54, 0x2c, 0xb1, 0x23, 0xa3, 0x39, 0x39, 0x2a, 0x6c, 0x76, 0x05};
- CRYPTOPP_ALIGN_DATA(16) // Non-const due to XL C/C++
byte state[16] = {0x19, 0x3d, 0xe3, 0xb3, 0xa0, 0xf4, 0xe2, 0x2b, 0x9a, 0xc6, 0x8d, 0x2a, 0xe9, 0xf8, 0x48, 0x08};
- CRYPTOPP_ALIGN_DATA(16) byte r[16] = {255}, z[16] = {};
-#if defined(CRYPTOPP_XLC_VERSION)
- uint8x16_p8 k = vec_xl(0, reinterpret_cast(key));
- uint8x16_p8 s = vec_xl(0, reinterpret_cast(state));
- s = __vncipher(s, k);
- s = __vncipherlast(s, k);
- vec_xst(s, 0, reinterpret_cast(r));
-#elif defined(CRYPTOPP_GCC_VERSION)
- uint64x2_p8 k = (uint64x2_p8)vec_xl(0, key);
- uint64x2_p8 s = (uint64x2_p8)vec_xl(0, state);
- s = __builtin_crypto_vncipher(s, k);
- s = __builtin_crypto_vncipherlast(s, k);
- vec_xst((uint8x16_p8)s, 0, r);
-#endif
+ byte r[16] = {255}, z[16] = {};
+
+ uint8x16_p8 k = (uint8x16_p8)VectorLoad(0, key);
+ uint8x16_p8 s = (uint8x16_p8)VectorLoad(0, state);
+ s = VectorEncrypt(s, k);
+ s = VectorEncryptLast(s, k);
+ VectorStore(s, r);
+
result = (0 != std::memcmp(r, z, 16));
}
@@ -261,7 +224,7 @@ bool CPU_ProbeAES()
#endif // CRYPTOPP_ALTIVEC_AVAILABLE
}
-bool CPU_ProbeSHA1()
+bool CPU_ProbeSHA256()
{
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
@@ -296,7 +259,7 @@ bool CPU_ProbeSHA1()
#endif // CRYPTOPP_ALTIVEC_AVAILABLE
}
-bool CPU_ProbeSHA2()
+bool CPU_ProbeSHA512()
{
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
diff --git a/sha-simd.cpp b/sha-simd.cpp
index 0dfd733a..9b16fb1c 100644
--- a/sha-simd.cpp
+++ b/sha-simd.cpp
@@ -29,6 +29,10 @@
# endif
#endif
+#if CRYPTOPP_POWER8_SHA_AVAILABLE
+# include "ppc-crypto.h"
+#endif
+
#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
# include
# include
@@ -960,10 +964,41 @@ void SHA256_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t l
vst1q_u32(&state[0], STATE0);
vst1q_u32(&state[4], STATE1);
}
-#endif
+#endif // CRYPTOPP_ARM_SHA_AVAILABLE
///////////////////////////////////////////////////////
// end of Walton/Schneiders/O'Rourke/Hovsmith's code //
///////////////////////////////////////////////////////
-NAMESPACE_END
\ No newline at end of file
+// ***************** Power8 SHA ********************
+
+////////////////////////////////////////////////
+// Begin Gustavo Serra Scalet and Walton code //
+////////////////////////////////////////////////
+
+#if CRYPTOPP_POWER8_SHA_AVAILABLE
+void SHA256_HashMultipleBlocks_POWER8(word32 *state, const word32 *data, size_t length, ByteOrder order)
+{
+ CRYPTOPP_ASSERT(state);
+ CRYPTOPP_ASSERT(data);
+ CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE);
+
+ CRYPTOPP_ASSERT(0);
+}
+
+void SHA512_HashMultipleBlocks_POWER8(word64 *state, const word64 *data, size_t length, ByteOrder order)
+{
+ CRYPTOPP_ASSERT(state);
+ CRYPTOPP_ASSERT(data);
+ CRYPTOPP_ASSERT(length >= SHA512::BLOCKSIZE);
+
+ CRYPTOPP_ASSERT(0);
+}
+
+#endif // CRYPTOPP_POWER8_SHA_AVAILABLE
+
+//////////////////////////////////////////////
+// End Gustavo Serra Scalet and Walton code //
+//////////////////////////////////////////////
+
+NAMESPACE_END
diff --git a/sha.cpp b/sha.cpp
index 713a1914..04dfb4d9 100644
--- a/sha.cpp
+++ b/sha.cpp
@@ -70,6 +70,11 @@ extern void SHA1_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, siz
extern void SHA256_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order);
#endif
+#if CRYPTOPP_POWER8_SHA_AVAILABLE
+extern void SHA256_HashMultipleBlocks_POWER8(word32 *state, const word32 *data, size_t length, ByteOrder order);
+extern void SHA512_HashMultipleBlocks_POWER8(word64 *state, const word64 *data, size_t length, ByteOrder order);
+#endif
+
////////////////////////////////
// start of Steve Reid's code //
////////////////////////////////
@@ -684,6 +689,13 @@ void SHA256::Transform(word32 *state, const word32 *data)
return;
}
#endif
+#if CRYPTOPP_POWER8_SHA_AVAILABLE
+ if (HasSHA256())
+ {
+ SHA256_HashMultipleBlocks_POWER8(state, data, SHA256::BLOCKSIZE, LITTLE_ENDIAN_ORDER);
+ return;
+ }
+#endif
SHA256_HashBlock_CXX(state, data);
}
@@ -715,6 +727,13 @@ size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length)
return length & (SHA256::BLOCKSIZE - 1);
}
#endif
+#if CRYPTOPP_POWER8_SHA_AVAILABLE
+ if (HasSHA256())
+ {
+ SHA256_HashMultipleBlocks_POWER8(m_state, input, length, BIG_ENDIAN_ORDER);
+ return length & (SHA256::BLOCKSIZE - 1);
+ }
+#endif
const bool noReverse = NativeByteOrderIs(this->GetByteOrder());
word32 *dataBuf = this->DataBuf();
diff --git a/validat1.cpp b/validat1.cpp
index 81fa5582..b5062418 100644
--- a/validat1.cpp
+++ b/validat1.cpp
@@ -379,12 +379,12 @@ bool TestSettings()
bool hasAltivec = HasAltivec();
bool hasPower8 = HasPower8();
bool hasAES = HasAES();
- bool hasSHA1 = HasSHA1();
- bool hasSHA2 = HasSHA2();
+ bool hasSHA256 = HasSHA256();
+ bool hasSHA512 = HasSHA512();
std::cout << "passed: ";
std::cout << "hasAltivec == " << hasAltivec << ", hasPower8 == " << hasPower8;
- std::cout << ", hasAES == " << hasAES << ", hasSHA1 == " << hasSHA1 << ", hasSHA2 == " << hasSHA2 << "\n";
+ std::cout << ", hasAES == " << hasAES << ", hasSHA256 == " << hasSHA256 << ", hasSHA512 == " << hasSHA512 << "\n";
#endif