summaryrefslogtreecommitdiff
path: root/node/Utils.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <[email protected]>2020-08-21 09:56:53 -0700
committerAdam Ierymenko <[email protected]>2020-08-21 09:56:53 -0700
commit3fd8efe6423ca6c0e089bc14e090dd7d2eccca32 (patch)
tree4b3ad6538edf89a3b72526119cfac86971d02f74 /node/Utils.cpp
parent06730c7d1d64c43fe41d0a760e92a7cf461f37b0 (diff)
AES builds now
Diffstat (limited to 'node/Utils.cpp')
-rw-r--r--node/Utils.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/node/Utils.cpp b/node/Utils.cpp
index 10da6676..7e3617c9 100644
--- a/node/Utils.cpp
+++ b/node/Utils.cpp
@@ -40,8 +40,87 @@
namespace ZeroTier {
+const uint64_t Utils::ZERO256[4] = {0ULL,0ULL,0ULL,0ULL};
+
const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+#ifdef ZT_ARCH_ARM_HAS_NEON
+Utils::ARMCapabilities::ARMCapabilities() noexcept
+{
+#ifdef HWCAP2_AES
+ 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 {
+#endif
+ 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;
+#ifdef HWCAP2_AES
+ }
+#endif
+}
+
+const Utils::ARMCapabilities Utils::ARMCAP;
+#endif
+
+#ifdef ZT_ARCH_X64
+
+Utils::CPUIDRegisters::CPUIDRegisters() noexcept
+{
+ uint32_t eax, ebx, ecx, edx;
+
+#ifdef __WINDOWS__
+ int regs[4];
+ __cpuid(regs,1);
+ eax = (uint32_t)regs[0];
+ ebx = (uint32_t)regs[1];
+ ecx = (uint32_t)regs[2];
+ edx = (uint32_t)regs[3];
+#else
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "a"(1), "c"(0)
+ );
+#endif
+
+ rdrand = ((ecx & (1U << 30U)) != 0);
+ aes = (((ecx & (1U << 25U)) != 0) && ((ecx & (1U << 19U)) != 0) && ((ecx & (1U << 1U)) != 0));
+ avx = ((ecx & (1U << 25U)) != 0);
+
+#ifdef __WINDOWS__
+ __cpuid(regs,7);
+ eax = (uint32_t)regs[0];
+ ebx = (uint32_t)regs[1];
+ ecx = (uint32_t)regs[2];
+ edx = (uint32_t)regs[3];
+#else
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "a"(7), "c"(0)
+ );
+#endif
+
+ vaes = aes && avx && ((ecx & (1U << 9U)) != 0);
+ vpclmulqdq = aes && avx && ((ecx & (1U << 10U)) != 0);
+ avx2 = avx && ((ebx & (1U << 5U)) != 0);
+ avx512f = avx && ((ebx & (1U << 16U)) != 0);
+ sha = ((ebx & (1U << 29U)) != 0);
+ fsrm = ((edx & (1U << 4U)) != 0);
+}
+
+const Utils::CPUIDRegisters Utils::CPUID;
+#endif
+
// Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers.
static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
{