From d5afba2610fdd1f91dce5023c2c503c26b6c08be Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 29 Jul 2020 21:17:17 +0000 Subject: [PATCH] ARM auto-detection (unfinished) --- core/AES.cpp | 5 +---- core/AES.hpp | 8 +++----- core/Utils.cpp | 30 ++++++++++++++++++++++++++++-- core/Utils.hpp | 14 ++++++++++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/core/AES.cpp b/core/AES.cpp index aadacd07e..d0109d013 100644 --- a/core/AES.cpp +++ b/core/AES.cpp @@ -745,7 +745,7 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept #endif // ZT_AES_AESNI #ifdef ZT_AES_NEON - if (s_hasNeonAes) { + if (Utils::ARMCAP.aes) { uint8x16_t dd = vld1q_u8(reinterpret_cast(_ctr)); const uint32x4_t one = {0,0,0,1}; @@ -1332,9 +1332,6 @@ void AES::_decrypt_aesni(const void *in, void *out) const noexcept #ifdef ZT_AES_NEON -const bool AES::s_hasNeonAes = true; -const bool AES::s_hasNeonGcm = true; - #define ZT_INIT_ARMNEON_CRYPTO_SUBWORD(w) ((uint32_t)s_sbox[w & 0xffU] + ((uint32_t)s_sbox[(w >> 8U) & 0xffU] << 8U) + ((uint32_t)s_sbox[(w >> 16U) & 0xffU] << 16U) + ((uint32_t)s_sbox[(w >> 24U) & 0xffU] << 24U)) #define ZT_INIT_ARMNEON_CRYPTO_ROTWORD(w) (((w) << 8U) | ((w) >> 24U)) #define ZT_INIT_ARMNEON_CRYPTO_NK 8 diff --git a/core/AES.hpp b/core/AES.hpp index 4b4d83c90..765b0dcc2 100644 --- a/core/AES.hpp +++ b/core/AES.hpp @@ -79,7 +79,7 @@ public: } #endif #ifdef ZT_AES_NEON - if (s_hasNeonAes) { + if (Utils::ARMCAP.aes) { _init_armneon_crypto(reinterpret_cast(key)); return; } @@ -102,7 +102,7 @@ public: } #endif #ifdef ZT_AES_NEON - if (s_hasNeonAes) { + if (Utils::ARMCAP.aes) { _encrypt_armneon_crypto(in, out); return; } @@ -125,7 +125,7 @@ public: } #endif #ifdef ZT_AES_NEON - if (s_hasNeonAes) { + if (Utils::ARMCAP.aes) { _decrypt_armneon_crypto(in, out); return; } @@ -548,8 +548,6 @@ private: #endif #ifdef ZT_AES_NEON - static const bool s_hasNeonAes; - static const bool s_hasNeonGcm; void _init_armneon_crypto(const uint8_t key[32]) noexcept; void _encrypt_armneon_crypto(const void *const in, void *const out) const noexcept; void _decrypt_armneon_crypto(const void *const in, void *const out) const noexcept; diff --git a/core/Utils.cpp b/core/Utils.cpp index f11a46a0f..02daf6cd4 100644 --- a/core/Utils.cpp +++ b/core/Utils.cpp @@ -17,11 +17,9 @@ #include "SHA512.hpp" #ifdef __UNIX_LIKE__ - #include #include #include - #endif #include @@ -31,10 +29,38 @@ #include #endif +#if defined(ZT_ARCH_ARM_HAS_NEON) && defined(__LINUX__) +#include +#include +#endif + namespace ZeroTier { namespace Utils { +#ifdef ZT_ARCH_ARM_HAS_NEON +ARMCapabilities::ARMCapabilities() noexcept +{ + if (sizeof(void *) == 4) { + const long hwcaps2 = getauxval(AT_HWCAP2); + this->aes = (hwcaps2 & HWCAP2_AES) != 0; + this->crc32 = (hwcaps2 & HWCAP2_CRC32) != 0; + this->pmull = (hwcaps2 & HWCAP2_PMULL) != 0; + this->sha1 = (hwcaps2 & HWCAP2_SHA1) != 0; + this->sha2 = (hwcaps2 & HWCAP2_SHA2) != 0; + } else { + const long hwcaps = getauxval(AT_HWCAP); + this->aes = (hwcaps & HWCAP_AES) != 0; + this->crc32 = (hwcaps & HWCAP_CRC32) != 0; + this->pmull = (hwcaps & HWCAP_PMULL) != 0; + this->sha1 = (hwcaps & HWCAP_SHA1) != 0; + this->sha2 = (hwcaps & HWCAP_SHA2) != 0; + } +} + +const ARMCapabilities ARMCAP; +#endif + #ifdef ZT_ARCH_X64 CPUIDRegisters::CPUIDRegisters() noexcept diff --git a/core/Utils.hpp b/core/Utils.hpp index 3178dcd7b..b545e773b 100644 --- a/core/Utils.hpp +++ b/core/Utils.hpp @@ -56,6 +56,20 @@ namespace Utils { #define ZT_ROR32(x, r) (((x) >> (r)) | ((x) << (32 - (r)))) #define ZT_ROL32(x, r) (((x) << (r)) | ((x) >> (32 - (r)))) +#ifdef ZT_ARCH_ARM_HAS_NEON +struct ARMCapabilities +{ + ARMCapabilities() noexcept; + + bool aes; + bool crc32; + bool pmull; + bool sha1; + bool sha2; +}; +extern const ARMCapabilities ARMCAP; +#endif + #ifdef ZT_ARCH_X64 struct CPUIDRegisters {