Revert "crypto: added runtime checks for SHA hardware"

This reverts commit e78cfc630dbb712662328eb6c8b401bd3fab8969.

Besides adding runtime checks, this also removes experimental
guards and makes the features leak into release code as we have
no way of disabling them.

Additionally, this breaks on non-gnu systems which currently have
no released binaries, like arm-apple-darwin20 (Apple silicon macs)
This commit is contained in:
Patrick Lodder 2022-10-14 09:22:24 +02:00
parent 763848c56e
commit c5c0c3ecee
No known key found for this signature in database
GPG Key ID: 2D3A345B98D0DC1F
8 changed files with 52 additions and 184 deletions

View File

@ -189,6 +189,18 @@ AC_ARG_WITH([intel-avx2],
[intel_avx2=$withval],
[intel_avx2=no])
AC_ARG_WITH([armv8-crypto],
[AS_HELP_STRING([--with-armv8-crypto],
[Build with armv8 crypto (default is no)])],
[armv8_crypto=$withval],
[armv8_crypto=no])
AC_ARG_WITH([armv82-crypto],
[AS_HELP_STRING([--with-armv82-crypto],
[Build with armv8.2 crypto sha512 (default is no)])],
[armv82_crypto=$withval],
[armv82_crypto=no])
AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], [])
AC_ARG_ENABLE(man,
@ -724,17 +736,18 @@ if test x$use_scrypt_sse2 = xyes; then
AC_DEFINE(USE_SSE2, 1, [Define this symbol if SSE2 works])
fi
AC_MSG_CHECKING([whether to build with armv8 crypto])
case $host in
aarch64-*)
AC_MSG_RESULT(yes)
AC_DEFINE(USE_ARMV8, 1, [Define this symbol if armv8 crypto works])
CXXFLAGS="$CXXFLAGS -march=armv8-a+crypto"
AC_CHECK_DECLS([vsha512su0q_u64],
[AC_DEFINE(USE_ARMV82, 1, [Define this symbol if armv8.2 crypto works])
CXXFLAGS="$CXXFLAGS -march=armv8.2-a+crypto+sha3"],, [#include <arm_neon.h>])
;;
esac
if test x$armv8_crypto = xyes; then
AC_MSG_CHECKING([whether to build with armv8 crypto])
AC_MSG_RESULT(yes)
AC_DEFINE(USE_ARMV8, 1, [Define this symbol if armv8 crypto works])
CXXFLAGS="$CXXFLAGS -march=armv8-a+crypto"
fi
if test x$armv82_crypto = xyes; then
AC_CHECK_DECLS([vsha512su0q_u64],
[AC_DEFINE(USE_ARMV82, 1, [Define this symbol if armv8.2 crypto works])
CXXFLAGS="$CXXFLAGS -march=armv8.2-a+crypto+sha3"], AC_MSG_ERROR(sha512 missing), [#include <arm_neon.h>])
fi
if test x$use_pkgconfig = xyes; then
: dnl

View File

@ -37,6 +37,7 @@ namespace
namespace sha1
{
#ifndef USE_AVX2
/** One round of SHA-1. */
void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w)
{
@ -49,6 +50,7 @@ uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
#endif
/** Initialize SHA-1 state. */
void inline Initialize(uint32_t* s)
@ -65,8 +67,8 @@ const uint32_t k2 = 0x6ED9EBA1ul;
const uint32_t k3 = 0x8F1BBCDCul;
const uint32_t k4 = 0xCA62C1D6ul;
/** Perform a SHA-1 transformation, processing a 64-byte chunk. (ARMv8) */
void Transform_ARMV8(uint32_t* s, const unsigned char* chunk)
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#if defined(USE_ARMV8) || defined(USE_ARMV82)
uint32x4_t ABCD, ABCD_SAVED;
@ -236,22 +238,11 @@ void Transform_ARMV8(uint32_t* s, const unsigned char* chunk)
/** Save state */
vst1q_u32(&s[0], ABCD);
s[4] = E0;
#endif
}
/** Perform a SHA-1 transformation, processing a 64-byte chunk. (AVX2) */
void Transform_AVX2(uint32_t* s, const unsigned char* chunk)
{
#if USE_AVX2
#elif USE_AVX2
// Perform SHA1 one block (Intel AVX2)
sha1_one_block_avx2(chunk, s);
#endif
}
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#else
// Perform SHA one block (legacy)
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
@ -347,41 +338,13 @@ void Transform(uint32_t* s, const unsigned char* chunk)
s[2] += c;
s[3] += d;
s[4] += e;
}
/** Define SHA1 hardware */
#if defined(__linux__)
#define HWCAP_SHA1 (1<<5)
#include <sys/auxv.h>
#elif defined(__WIN64__)
#include <intrin.h>
bool isAVX (void) {
int cpuinfo[4];
__cpuid(cpuinfo, 1);
return ((cpuinfo[2] & (1 << 28)) != 0);
}
#endif
/** Define a function pointer for Transform */
void (*transform_ptr) (uint32_t*, const unsigned char*) = &Transform;
/** Initialize the function pointer */
void inline Initialize_transform_ptr(void)
{
// Override the function pointer for ARMV8/AVX2
#if (defined(USE_ARMV8) || defined(USE_ARMV82))
if (getauxval(AT_HWCAP) && HWCAP_SHA1)
transform_ptr = &Transform_ARMV8;
#elif USE_AVX2 && defined(__linux__)
if (getauxval(AT_HWCAP) && HWCAP_SHA1)
transform_ptr = &Transform_AVX2;
#elif USE_AVX2 && defined(__WIN64__)
if (isAVX)
transform_ptr = &Transform_AVX2;
#endif
}
} // namespace sha1
} // namespace
////// SHA1
@ -400,12 +363,12 @@ CSHA1& CSHA1::Write(const unsigned char* data, size_t len)
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha1::transform_ptr(s, buf);
sha1::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha1::transform_ptr(s, data);
sha1::Transform(s, data);
bytes += 64;
data += 64;
}
@ -437,8 +400,3 @@ CSHA1& CSHA1::Reset()
sha1::Initialize(s);
return *this;
}
void detect_sha1_hardware()
{
sha1::Initialize_transform_ptr();
}

View File

@ -25,6 +25,4 @@ public:
CSHA1& Reset();
};
void detect_sha1_hardware(void);
#endif // BITCOIN_CRYPTO_SHA1_H

View File

@ -28,6 +28,7 @@
# include "compat/arm_acle_selector.h"
# endif
# endif
#endif /** ARM Headers */
static const uint32_t K[] =
{
@ -48,7 +49,6 @@ static const uint32_t K[] =
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};
#endif /** ARM Headers */
// Internal implementation code.
namespace
@ -56,6 +56,7 @@ namespace
/// Internal SHA-256 implementation.
namespace sha256
{
#ifndef USE_AVX2
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
@ -71,6 +72,7 @@ void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, u
d += t1;
h = t1 + t2;
}
#endif
/** Initialize SHA-256 state. */
void inline Initialize(uint32_t* s)
@ -85,8 +87,8 @@ void inline Initialize(uint32_t* s)
s[7] = 0x5be0cd19ul;
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. (ARMv8) */
void Transform_ARMV8(uint32_t* s, const unsigned char* chunk)
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#if defined(USE_ARMV8) || defined(USE_ARMV82)
uint32x4_t STATE0, STATE1, ABEF_SAVE, CDGH_SAVE;
@ -242,21 +244,11 @@ void Transform_ARMV8(uint32_t* s, const unsigned char* chunk)
/** Save state */
vst1q_u32(&s[0], STATE0);
vst1q_u32(&s[4], STATE1);
#endif
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. (AVX2) */
void Transform_AVX2(uint32_t* s, const unsigned char* chunk)
{
#if USE_AVX2
#elif USE_AVX2
// Perform SHA256 one block (Intel AVX2)
sha256_one_block_avx2(chunk, s);
#endif
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#else
// Perform SHA256 one block (legacy)
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@ -337,37 +329,6 @@ void Transform(uint32_t* s, const unsigned char* chunk)
s[5] += f;
s[6] += g;
s[7] += h;
}
/** Define SHA256 hardware */
#if defined(__linux__)
#define HWCAP_SHA2 (1<<6)
#include <sys/auxv.h>
#elif defined(__WIN64__)
#include <intrin.h>
bool isAVX (void) {
int cpuinfo[4];
__cpuid(cpuinfo, 1);
return ((cpuinfo[2] & (1 << 28)) != 0);
}
#endif
/** Define a function pointer for Transform */
void (*transform_ptr) (uint32_t*, const unsigned char*) = &Transform;
/** Initialize the function pointer */
void inline Initialize_transform_ptr(void)
{
// Override the function pointer for ARMV8/AVX2
#if (defined(USE_ARMV8) || defined(USE_ARMV82))
if (getauxval(AT_HWCAP) && HWCAP_SHA2)
transform_ptr = &Transform_ARMV8;
#elif USE_AVX2 && defined(__linux__)
if (getauxval(AT_HWCAP) && HWCAP_SHA2)
transform_ptr = &Transform_AVX2;
#elif USE_AVX2 && defined(__WIN64__)
if (isAVX)
transform_ptr = &Transform_AVX2;
#endif
}
@ -391,12 +352,12 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha256::transform_ptr(s, buf);
sha256::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha256::transform_ptr(s, data);
sha256::Transform(s, data);
bytes += 64;
data += 64;
}
@ -431,8 +392,3 @@ CSHA256& CSHA256::Reset()
sha256::Initialize(s);
return *this;
}
void detect_sha256_hardware()
{
sha256::Initialize_transform_ptr();
}

View File

@ -25,6 +25,4 @@ public:
CSHA256& Reset();
};
void detect_sha256_hardware();
#endif // BITCOIN_CRYPTO_SHA256_H

View File

@ -28,6 +28,7 @@
# include "compat/arm_acle_selector.h"
# endif
# endif
#endif /** ARM Headers */
static const uint64_t sha512_round_constants[] =
{
@ -72,7 +73,6 @@ static const uint64_t sha512_round_constants[] =
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
#endif /** ARM Headers */
// Internal implementation code.
namespace
@ -80,6 +80,7 @@ namespace
/// Internal SHA-512 implementation.
namespace sha512
{
#ifndef USE_AVX2
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
@ -95,6 +96,7 @@ void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, u
d += t1;
h = t1 + t2;
}
#endif
#ifdef USE_ARMV82
@ -304,19 +306,13 @@ void inline Initialize(uint64_t* s)
s[7] = 0x5be0cd19137e2179ull;
}
/** Perform one SHA-512 transformation, processing a 128-byte chunk. (AVX2) */
void Transform_AVX2(uint64_t* s, const unsigned char* chunk)
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
void Transform(uint64_t* s, const unsigned char* chunk)
{
#ifdef USE_AVX2
// Perform SHA512 one block (Intel AVX2)
sha512_one_block_avx2(chunk, s);
#endif
}
/** Perform one SHA-512 transformation, processing a 128-byte chunk. (ARMv8.2) */
void Transform_ARMV82(uint64_t* s, const unsigned char* chunk)
{
#ifdef USE_ARMV82
#elif USE_ARMV82
sha512_neon_core core;
core.ab = vld1q_u64(s);
@ -335,12 +331,7 @@ void Transform_ARMV82(uint64_t* s, const unsigned char* chunk)
s[5] = vgetq_lane_u64 (core.ef, 1);
s[6] = vgetq_lane_u64 (core.gh, 0);
s[7] = vgetq_lane_u64 (core.gh, 1);
#endif
}
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
void Transform(uint64_t* s, const unsigned char* chunk)
{
#else
// Perform SHA512 one block (legacy)
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@ -438,41 +429,11 @@ void Transform(uint64_t* s, const unsigned char* chunk)
s[5] += f;
s[6] += g;
s[7] += h;
}
/** Define SHA512 hardware */
#if defined(__linux__)
#define HWCAP_SHA512 (1<<21)
#include <sys/auxv.h>
#elif defined(__WIN64__)
#include <intrin.h>
bool isAVX (void) {
int cpuinfo[4];
__cpuid(cpuinfo, 1);
return ((cpuinfo[2] & (1 << 28)) != 0);
}
#endif
/** Define a function pointer for Transform */
void (*transform_ptr) (uint64_t*, const unsigned char*) = &Transform;
/** Initialize the function pointer */
void inline Initialize_transform_ptr(void)
{
// Override the function pointer for ARMV82/AVX2
#if defined(USE_ARMV82)
if (getauxval(AT_HWCAP) && HWCAP_SHA512)
transform_ptr = &Transform_ARMV82;
#elif USE_AVX2 && defined(__linux__)
if (getauxval(AT_HWCAP) && HWCAP_SHA512)
transform_ptr = &Transform_AVX2;
#elif USE_AVX2 && defined(__WIN64__)
if (isAVX)
transform_ptr = &Transform_AVX2;
#endif
}
} // namespace sha512
} // namespace
@ -492,12 +453,12 @@ CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
memcpy(buf + bufsize, data, 128 - bufsize);
bytes += 128 - bufsize;
data += 128 - bufsize;
sha512::transform_ptr(s, buf);
sha512::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 128) {
// Process full chunks directly from the source.
sha512::transform_ptr(s, data);
sha512::Transform(s, data);
data += 128;
bytes += 128;
}
@ -532,8 +493,3 @@ CSHA512& CSHA512::Reset()
sha512::Initialize(s);
return *this;
}
void detect_sha512_hardware()
{
sha512::Initialize_transform_ptr();
}

View File

@ -25,6 +25,4 @@ public:
CSHA512& Reset();
};
void detect_sha512_hardware(void);
#endif // BITCOIN_CRYPTO_SHA512_H

View File

@ -90,10 +90,6 @@
#include <openssl/rand.h>
#include <openssl/conf.h>
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "crypto/sha512.h"
// Work around clang compilation problem in Boost 1.46:
// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
@ -864,11 +860,6 @@ void SetupEnvironment()
// boost::filesystem::path, which is then used to explicitly imbue the path.
std::locale loc = boost::filesystem::path::imbue(std::locale::classic());
boost::filesystem::path::imbue(loc);
// Auto detect SHA1, SHA256 and SHA512 features of ARMv8/ARMv8.2/AVX2
detect_sha1_hardware();
detect_sha256_hardware();
detect_sha512_hardware();
}
bool SetupNetworking()