mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-02-17 03:48:38 +00:00
Add Power8 SHA256 and SHA512 support (GH #513)
This commit is contained in:
parent
375d5e18b3
commit
3bd01f73ba
14
cpu.cpp
14
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
|
||||
|
18
cpu.h
18
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 <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
|
||||
//! <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> 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 <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
|
||||
//! <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> 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
|
||||
|
89
ppc-simd.cpp
89
ppc-simd.cpp
@ -23,22 +23,9 @@
|
||||
# undef CRYPTOPP_POWER8_CRYPTO_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
|
||||
# include <altivec.h>
|
||||
# undef vector
|
||||
# undef pixel
|
||||
# undef bool
|
||||
#endif
|
||||
|
||||
#if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
|
||||
# if defined(CRYPTOPP_XLC_VERSION)
|
||||
// #include <builtins.h>
|
||||
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<byte*>(b1)+3);
|
||||
vec_xst(v1, 0, reinterpret_cast<byte*>(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<byte*>(key));
|
||||
uint8x16_p8 s = vec_xl(0, reinterpret_cast<byte*>(state));
|
||||
s = __vncipher(s, k);
|
||||
s = __vncipherlast(s, k);
|
||||
vec_xst(s, 0, reinterpret_cast<byte*>(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;
|
||||
|
39
sha-simd.cpp
39
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 <signal.h>
|
||||
# include <setjmp.h>
|
||||
@ -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
|
||||
// ***************** 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
|
||||
|
19
sha.cpp
19
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();
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user