7#ifndef EXCEPTION_EXECUTE_HANDLER
8# define EXCEPTION_EXECUTE_HANDLER 1
11#ifndef CRYPTOPP_IMPORTS
19#if _MSC_VER >= 1600 && (defined(_M_IX86) || defined(_M_X64))
20# include <immintrin.h>
25#if defined(_WIN32) && defined(_M_ARM64)
27# include <processthreadsapi.h>
31# include <sys/systemcfg.h>
40#if (((__GLIBC__ * 100) + __GLIBC_MINOR__) >= 216)
41# define CRYPTOPP_GETAUXV_AVAILABLE 1
44#if CRYPTOPP_GETAUXV_AVAILABLE
53unsigned long int getauxval(
unsigned long int) {
return 0; }
57# include <sys/utsname.h>
58# include <sys/sysctl.h>
63#if defined(__FreeBSD__)
65# include <sys/elf_common.h>
72#if defined(__ANDROID__)
73# include "cpu-features.h"
76#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
83#if defined(_MSC_VER) && defined(_M_X64)
84extern "C" unsigned long long __fastcall XGETBV64(
unsigned int);
85extern "C" unsigned long long __fastcall CPUID64(
unsigned int,
unsigned int,
unsigned int*);
88#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
90 typedef void (*SigHandler)(int);
95 static jmp_buf s_jmpNoCPUID;
96 static void SigIllHandler(
int)
98 longjmp(s_jmpNoCPUID, 1);
103ANONYMOUS_NAMESPACE_BEGIN
105#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
107using CryptoPP::word32;
109inline bool IsIntel(
const word32 output[4])
112 return (output[1] == 0x756e6547) &&
113 (output[2] == 0x6c65746e) &&
114 (output[3] == 0x49656e69);
117inline bool IsAMD(
const word32 output[4])
120 return ((output[1] == 0x68747541) &&
121 (output[2] == 0x444D4163) &&
122 (output[3] == 0x69746E65)) ||
124 ((output[1] == 0x69444d41) &&
125 (output[2] == 0x74656273) &&
126 (output[3] == 0x21726574));
129inline bool IsHygon(
const word32 output[4])
132 return (output[1] == 0x6f677948) &&
133 (output[2] == 0x656e6975) &&
134 (output[3] == 0x6e65476e);
137inline bool IsVIA(
const word32 output[4])
140 return ((output[1] == 0x746e6543) &&
141 (output[2] == 0x736c7561) &&
142 (output[3] == 0x48727561)) ||
144 ((output[1] == 0x32414956) &&
145 (output[2] == 0x32414956) &&
146 (output[3] == 0x32414956));
151#if defined(__APPLE__)
154class AppleMachineInfo
157 enum { PowerMac=1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch };
158 enum { PowerPC=1, I386, I686, X86_64, ARM32, ARMV8, ARMV82, ARMV83 };
160 AppleMachineInfo() : m_device(0), m_version(0), m_arch(0)
162 struct utsname systemInfo;
163 systemInfo.machine[0] =
'\0';
166 std::string machine(systemInfo.machine);
168 std::string::size_type pos = machine.find_first_of(
"0123456789");
169 if (pos != std::string::npos)
170 m_version = std::atoi(machine.substr(pos).c_str());
172 if (machine.find(
"iPhone") != std::string::npos)
175 if (m_version >= 6) { m_arch = ARMV8; }
176 else { m_arch = ARM32; }
178 else if (machine.find(
"iPod") != std::string::npos)
181 if (m_version >= 6) { m_arch = ARMV8; }
182 else { m_arch = ARM32; }
184 else if (machine.find(
"iPad") != std::string::npos)
187 if (m_version >= 5) { m_arch = ARMV8; }
188 else { m_arch = ARM32; }
190 else if (machine.find(
"PowerMac") != std::string::npos ||
191 machine.find(
"Power Macintosh") != std::string::npos)
196 else if (machine.find(
"Mac") != std::string::npos ||
197 machine.find(
"Macintosh") != std::string::npos)
199#if defined(__x86_64) || defined(__amd64)
214 else if (machine.find(
"AppleTV") != std::string::npos)
217 if (m_version >= 4) { m_arch = ARMV8; }
218 else { m_arch = ARM32; }
220 else if (machine.find(
"AppleWatch") != std::string::npos)
222 m_device = AppleWatch;
223 if (m_version >= 4) { m_arch = ARMV8; }
224 else { m_arch = ARM32; }
226 else if (machine.find(
"arm64") != std::string::npos)
235 if (sysctlbyname(
"machdep.cpu.brand_string", &brand[0], &size, NULL, 0) == 0 && size > 0)
237 if (brand[size-1] ==
'\0')
242 if (brand ==
"Apple M1")
260 unsigned int Device()
const {
264 unsigned int Version()
const {
268 unsigned int Arch()
const {
272 bool IsARM32()
const {
273 return m_arch == ARM32;
276 bool IsARMv8()
const {
277 return m_arch >= ARMV8;
280 bool IsARMv82()
const {
281 return m_arch >= ARMV82;
284 bool IsARMv83()
const {
285 return m_arch >= ARMV83;
289 unsigned int m_device, m_version, m_arch;
292void GetAppleMachineInfo(
unsigned int& device,
unsigned int& version,
unsigned int& arch)
294#if CRYPTOPP_CXX11_STATIC_INIT
295 static const AppleMachineInfo info;
297 using CryptoPP::Singleton;
301 device = info.Device();
302 version = info.Version();
306inline bool IsAppleMachineARM32()
308 static unsigned int arch;
312 GetAppleMachineInfo(unused, unused, arch);
314 return arch == AppleMachineInfo::ARM32;
317inline bool IsAppleMachineARMv8()
319 static unsigned int arch;
323 GetAppleMachineInfo(unused, unused, arch);
325 return arch >= AppleMachineInfo::ARMV8;
328inline bool IsAppleMachineARMv82()
330 static unsigned int arch;
334 GetAppleMachineInfo(unused, unused, arch);
336 return arch >= AppleMachineInfo::ARMV82;
339inline bool IsAppleMachineARMv83()
341 static unsigned int arch;
345 GetAppleMachineInfo(unused, unused, arch);
347 return arch >= AppleMachineInfo::ARMV83;
352ANONYMOUS_NAMESPACE_END
354NAMESPACE_BEGIN(CryptoPP)
358#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
360bool CRYPTOPP_SECTION_INIT g_x86DetectionDone =
false;
361bool CRYPTOPP_SECTION_INIT g_hasSSE2 =
false;
362bool CRYPTOPP_SECTION_INIT g_hasSSSE3 =
false;
363bool CRYPTOPP_SECTION_INIT g_hasSSE41 =
false;
364bool CRYPTOPP_SECTION_INIT g_hasSSE42 =
false;
365bool CRYPTOPP_SECTION_INIT g_hasAESNI =
false;
366bool CRYPTOPP_SECTION_INIT g_hasCLMUL =
false;
367bool CRYPTOPP_SECTION_INIT g_hasMOVBE =
false;
368bool CRYPTOPP_SECTION_INIT g_hasAVX =
false;
369bool CRYPTOPP_SECTION_INIT g_hasAVX2 =
false;
370bool CRYPTOPP_SECTION_INIT g_hasADX =
false;
371bool CRYPTOPP_SECTION_INIT g_hasSHA =
false;
372bool CRYPTOPP_SECTION_INIT g_hasRDRAND =
false;
373bool CRYPTOPP_SECTION_INIT g_hasRDSEED =
false;
374bool CRYPTOPP_SECTION_INIT g_isP4 =
false;
375bool CRYPTOPP_SECTION_INIT g_hasPadlockRNG =
false;
376bool CRYPTOPP_SECTION_INIT g_hasPadlockACE =
false;
377bool CRYPTOPP_SECTION_INIT g_hasPadlockACE2 =
false;
378bool CRYPTOPP_SECTION_INIT g_hasPadlockPHE =
false;
379bool CRYPTOPP_SECTION_INIT g_hasPadlockPMM =
false;
380word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
383extern bool CPU_ProbeSSE2();
392#if defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219)
397#elif defined(_MSC_VER) && defined(_M_X64)
399 return XGETBV64(num);
402#elif defined(_MSC_VER) && defined(_M_IX86)
419 return (
static_cast<word64
>(d) << 32) | a;
422#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
427 "xgetbv" :
"=a"(a),
"=d"(d) :
"c"(num) :
"cc"
429 return (
static_cast<word64
>(d) << 32) | a;
432#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC)
439 ".byte 0x0f, 0x01, 0xd0" "\n\t"
440 :
"=a"(a),
"=d"(d) :
"c"(num) :
"cc"
442 return (
static_cast<word64
>(d) << 32) | a;
444 # error "Need an xgetbv function"
453#if defined(_MSC_VER) && (_MSC_VER >= 1600)
455 __cpuidex((
int *)output, func, subfunc);
459#elif defined(_MSC_VER) && defined(_M_X64)
461 CPUID64(func, subfunc, output);
465#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__BORLANDC__)
489 __except (EXCEPTION_EXECUTE_HANDLER)
501 volatile bool result =
true;
503 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler);
504 if (oldHandler == SIG_ERR)
508 volatile sigset_t oldMask;
509 if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask) != 0)
511 signal(SIGILL, oldHandler);
516 if (setjmp(s_jmpNoCPUID))
523# if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
524 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
526 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
528 :
"=a" (output[0]),
"=D" (output[1]),
"=c" (output[2]),
"=d" (output[3])
529 :
"a" (func),
"c" (subfunc)
535 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
538 signal(SIGILL, oldHandler);
543void DetectX86Features()
547 word32 cpuid0[4]={0}, cpuid1[4]={0}, cpuid2[4]={0};
549#if defined(CRYPTOPP_DISABLE_ASM)
553 if (!CpuId(0, 0, cpuid0))
555 if (!CpuId(1, 0, cpuid1))
559 CRYPTOPP_CONSTANT(EAX_REG = 0);
560 CRYPTOPP_CONSTANT(EBX_REG = 1);
561 CRYPTOPP_CONSTANT(ECX_REG = 2);
562 CRYPTOPP_CONSTANT(EDX_REG = 3);
564 CRYPTOPP_CONSTANT(MMX_FLAG = (1 << 24));
565 CRYPTOPP_CONSTANT(SSE_FLAG = (1 << 25));
566 CRYPTOPP_CONSTANT(SSE2_FLAG = (1 << 26));
568 CRYPTOPP_CONSTANT(SSE3_FLAG = (1 << 0));
569 CRYPTOPP_CONSTANT(SSSE3_FLAG = (1 << 9));
570 CRYPTOPP_CONSTANT(SSE41_FLAG = (1 << 19));
571 CRYPTOPP_CONSTANT(SSE42_FLAG = (1 << 20));
572 CRYPTOPP_CONSTANT(MOVBE_FLAG = (1 << 22));
573 CRYPTOPP_CONSTANT(AESNI_FLAG = (1 << 25));
574 CRYPTOPP_CONSTANT(CLMUL_FLAG = (1 << 1));
576 CRYPTOPP_CONSTANT(XSAVE_FLAG = (1 << 26));
577 CRYPTOPP_CONSTANT(OSXSAVE_FLAG = (1 << 27));
579 CRYPTOPP_CONSTANT(AVX_FLAG = (3 << 27));
580 CRYPTOPP_CONSTANT(YMM_FLAG = (3 << 1));
584 CRYPTOPP_UNUSED(MMX_FLAG); CRYPTOPP_UNUSED(SSE_FLAG);
585 CRYPTOPP_UNUSED(SSE2_FLAG); CRYPTOPP_UNUSED(SSE3_FLAG);
586 CRYPTOPP_UNUSED(XSAVE_FLAG);
588#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
591 g_hasSSE2 = (cpuid1[ECX_REG] & OSXSAVE_FLAG) != 0;
597 if ((cpuid1[EDX_REG] & SSE2_FLAG) == SSE2_FLAG)
598 g_hasSSE2 = (cpuid1[ECX_REG] & XSAVE_FLAG) != 0 &&
599 (cpuid1[ECX_REG] & OSXSAVE_FLAG) != 0;
604 if (g_hasSSE2 ==
false)
605 g_hasSSE2 = CPU_ProbeSSE2();
607 if (g_hasSSE2 ==
false)
610 g_hasSSSE3 = (cpuid1[ECX_REG] & SSSE3_FLAG) != 0;
611 g_hasSSE41 = (cpuid1[ECX_REG] & SSE41_FLAG) != 0;
612 g_hasSSE42 = (cpuid1[ECX_REG] & SSE42_FLAG) != 0;
613 g_hasMOVBE = (cpuid1[ECX_REG] & MOVBE_FLAG) != 0;
614 g_hasAESNI = (cpuid1[ECX_REG] & AESNI_FLAG) != 0;
615 g_hasCLMUL = (cpuid1[ECX_REG] & CLMUL_FLAG) != 0;
620 if ((cpuid1[ECX_REG] & AVX_FLAG) == AVX_FLAG)
622 word64 xcr0 = XGetBV(0);
623 g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
628 CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30));
629 CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18));
630 CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19));
631 CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29));
632 CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5));
634 g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
635 g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
636 g_hasRDRAND = (cpuid1[ECX_REG] & RDRAND_FLAG) != 0;
638 if (cpuid0[EAX_REG] >= 7)
640 if (CpuId(7, 0, cpuid2))
642 g_hasRDSEED = (cpuid2[EBX_REG] & RDSEED_FLAG) != 0;
643 g_hasADX = (cpuid2[EBX_REG] & ADX_FLAG) != 0;
644 g_hasSHA = (cpuid2[EBX_REG] & SHA_FLAG) != 0;
645 g_hasAVX2 = (cpuid2[EBX_REG] & AVX2_FLAG) != 0;
649 else if (IsAMD(cpuid0) || IsHygon(cpuid0))
651 CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30));
652 CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18));
653 CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19));
654 CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29));
655 CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5));
657 CpuId(0x80000005, 0, cpuid2);
658 g_cacheLineSize = GETBYTE(cpuid2[ECX_REG], 0);
659 g_hasRDRAND = (cpuid1[ECX_REG] & RDRAND_FLAG) != 0;
661 if (cpuid0[EAX_REG] >= 7)
663 if (CpuId(7, 0, cpuid2))
665 g_hasRDSEED = (cpuid2[EBX_REG] & RDSEED_FLAG) != 0;
666 g_hasADX = (cpuid2[EBX_REG] & ADX_FLAG) != 0;
667 g_hasSHA = (cpuid2[EBX_REG] & SHA_FLAG) != 0;
668 g_hasAVX2 = (cpuid2[EBX_REG] & AVX2_FLAG) != 0;
677 CRYPTOPP_CONSTANT(FAMILY_BASE_FLAG = (0x0f << 8));
678 CRYPTOPP_CONSTANT(FAMILY_EXT_FLAG = (0xff << 20));
680 word32 family = (cpuid1[0] & FAMILY_BASE_FLAG) >> 8;
682 family += (cpuid1[0] & FAMILY_EXT_FLAG) >> 20;
683 if (family == 0x15 || family == 0x16)
690 else if (IsVIA(cpuid0))
693 CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2));
694 CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6));
695 CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8));
696 CRYPTOPP_CONSTANT( PHE_FLAGS = (0x3 << 10));
697 CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12));
699 CpuId(0xC0000000, 0, cpuid2);
700 word32 extendedFeatures = cpuid2[0];
702 if (extendedFeatures >= 0xC0000001)
704 CpuId(0xC0000001, 0, cpuid2);
705 g_hasPadlockRNG = (cpuid2[EDX_REG] & RNG_FLAGS) != 0;
706 g_hasPadlockACE = (cpuid2[EDX_REG] & ACE_FLAGS) != 0;
707 g_hasPadlockACE2 = (cpuid2[EDX_REG] & ACE2_FLAGS) != 0;
708 g_hasPadlockPHE = (cpuid2[EDX_REG] & PHE_FLAGS) != 0;
709 g_hasPadlockPMM = (cpuid2[EDX_REG] & PMM_FLAGS) != 0;
712 if (extendedFeatures >= 0xC0000005)
714 CpuId(0xC0000005, 0, cpuid2);
715 g_cacheLineSize = GETBYTE(cpuid2[ECX_REG], 0);
721 g_hasAVX2 &= g_hasAVX;
725#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
728 int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
729 if (g_cacheLineSize == 0 && cacheLineSize > 0)
730 g_cacheLineSize = cacheLineSize;
733 if (g_cacheLineSize == 0)
734 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
736 *
const_cast<volatile bool*
>(&g_x86DetectionDone) =
true;
741#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8)
743bool CRYPTOPP_SECTION_INIT g_ArmDetectionDone =
false;
744bool CRYPTOPP_SECTION_INIT g_hasARMv7 =
false;
745bool CRYPTOPP_SECTION_INIT g_hasNEON =
false;
746bool CRYPTOPP_SECTION_INIT g_hasPMULL =
false;
747bool CRYPTOPP_SECTION_INIT g_hasCRC32 =
false;
748bool CRYPTOPP_SECTION_INIT g_hasAES =
false;
749bool CRYPTOPP_SECTION_INIT g_hasSHA1 =
false;
750bool CRYPTOPP_SECTION_INIT g_hasSHA2 =
false;
751bool CRYPTOPP_SECTION_INIT g_hasSHA512 =
false;
752bool CRYPTOPP_SECTION_INIT g_hasSHA3 =
false;
753bool CRYPTOPP_SECTION_INIT g_hasSM3 =
false;
754bool CRYPTOPP_SECTION_INIT g_hasSM4 =
false;
755word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
771extern bool CPU_ProbeARMv7();
772extern bool CPU_ProbeNEON();
773extern bool CPU_ProbeCRC32();
774extern bool CPU_ProbeAES();
775extern bool CPU_ProbeSHA1();
776extern bool CPU_ProbeSHA256();
777extern bool CPU_ProbeSHA512();
778extern bool CPU_ProbeSHA3();
779extern bool CPU_ProbeSM3();
780extern bool CPU_ProbeSM4();
781extern bool CPU_ProbePMULL();
786# define HWCAP_ARMv7 (1 << 29)
789# define HWCAP_ASIMD (1 << 1)
792# define HWCAP_NEON (1 << 12)
795# define HWCAP_CRC32 (1 << 7)
798# define HWCAP2_CRC32 (1 << 4)
801# define HWCAP_PMULL (1 << 4)
804# define HWCAP2_PMULL (1 << 1)
807# define HWCAP_AES (1 << 3)
810# define HWCAP2_AES (1 << 0)
813# define HWCAP_SHA1 (1 << 5)
816# define HWCAP_SHA2 (1 << 6)
819# define HWCAP2_SHA1 (1 << 2)
822# define HWCAP2_SHA2 (1 << 3)
825# define HWCAP_SHA3 (1 << 17)
828# define HWCAP_SM3 (1 << 18)
831# define HWCAP_SM4 (1 << 19)
834# define HWCAP_SHA512 (1 << 21)
837inline bool CPU_QueryARMv7()
839#if defined(__ANDROID__) && defined(__arm__)
840 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
841 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0))
843#elif defined(__linux__) && defined(__arm__)
844 if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0 ||
845 (getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
847#elif defined(__APPLE__) && defined(__arm__)
850#elif defined(_WIN32) && defined(_M_ARM64)
857inline bool CPU_QueryNEON()
859#if defined(__ANDROID__) && defined(__aarch64__)
860 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
861 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0))
863#elif defined(__ANDROID__) && defined(__arm__)
864 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
865 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0))
867#elif defined(__linux__) && defined(__aarch64__)
868 if ((getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0)
870#elif defined(__linux__) && defined(__aarch32__)
871 if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0)
873#elif defined(__linux__) && defined(__arm__)
874 if ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
876#elif defined(__APPLE__) && defined(__aarch64__)
878 if (IsAppleMachineARMv8())
880#elif defined(_WIN32) && defined(_M_ARM64)
882 if (IsProcessorFeaturePresent(PF_ARM_V8_INSTRUCTIONS_AVAILABLE) != 0)
888inline bool CPU_QueryCRC32()
890#if defined(__ANDROID__) && defined(__aarch64__)
891 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
892 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32) != 0))
894#elif defined(__ANDROID__) && defined(__aarch32__)
895 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
896 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32) != 0))
898#elif defined(__linux__) && defined(__aarch64__)
899 if ((getauxval(AT_HWCAP) & HWCAP_CRC32) != 0)
901#elif defined(__linux__) && defined(__aarch32__)
902 if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0)
904#elif defined(__APPLE__) && defined(__aarch64__)
906 if (IsAppleMachineARMv82())
908#elif defined(_WIN32) && defined(_M_ARM64)
909 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0)
915inline bool CPU_QueryPMULL()
917#if defined(__ANDROID__) && defined(__aarch64__)
918 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
919 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL) != 0))
921#elif defined(__ANDROID__) && defined(__aarch32__)
922 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
923 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL) != 0))
925#elif defined(__linux__) && defined(__aarch64__)
926 if ((getauxval(AT_HWCAP) & HWCAP_PMULL) != 0)
928#elif defined(__linux__) && defined(__aarch32__)
929 if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0)
931#elif defined(__APPLE__) && defined(__aarch64__)
933 if (IsAppleMachineARMv82())
935#elif defined(_WIN32) && defined(_M_ARM64)
936 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
942inline bool CPU_QueryAES()
944#if defined(__ANDROID__) && defined(__aarch64__)
945 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
946 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0))
948#elif defined(__ANDROID__) && defined(__aarch32__)
949 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
950 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0))
952#elif defined(__linux__) && defined(__aarch64__)
953 if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0)
955#elif defined(__linux__) && defined(__aarch32__)
956 if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0)
958#elif defined(__APPLE__) && defined(__aarch64__)
960 if (IsAppleMachineARMv82())
962#elif defined(_WIN32) && defined(_M_ARM64)
963 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
969inline bool CPU_QuerySHA1()
971#if defined(__ANDROID__) && defined(__aarch64__)
972 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
973 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1) != 0))
975#elif defined(__ANDROID__) && defined(__aarch32__)
976 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
977 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1) != 0))
979#elif defined(__linux__) && defined(__aarch64__)
980 if ((getauxval(AT_HWCAP) & HWCAP_SHA1) != 0)
982#elif defined(__linux__) && defined(__aarch32__)
983 if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0)
985#elif defined(__APPLE__) && defined(__aarch64__)
987 if (IsAppleMachineARMv82())
989#elif defined(_WIN32) && defined(_M_ARM64)
990 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
996inline bool CPU_QuerySHA256()
998#if defined(__ANDROID__) && defined(__aarch64__)
999 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
1000 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2) != 0))
1002#elif defined(__ANDROID__) && defined(__aarch32__)
1003 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
1004 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2) != 0))
1006#elif defined(__linux__) && defined(__aarch64__)
1007 if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0)
1009#elif defined(__linux__) && defined(__aarch32__)
1010 if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0)
1012#elif defined(__APPLE__) && defined(__aarch64__)
1014 if (IsAppleMachineARMv82())
1016#elif defined(_WIN32) && defined(_M_ARM64)
1017 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
1024inline bool CPU_QuerySHA3()
1030 if (!g_hasSHA1 || !g_hasSHA2) {
return false; }
1032#if defined(__ANDROID__) && defined(__aarch64__) && 0
1033 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
1034 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA3) != 0))
1036#elif defined(__ANDROID__) && defined(__aarch32__) && 0
1037 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
1038 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA3) != 0))
1040#elif defined(__linux__) && defined(__aarch64__)
1041 if ((getauxval(AT_HWCAP) & HWCAP_SHA3) != 0)
1043#elif defined(__linux__) && defined(__aarch32__)
1044 if ((getauxval(AT_HWCAP2) & HWCAP2_SHA3) != 0)
1046#elif defined(__APPLE__) && defined(__aarch64__)
1048 if (IsAppleMachineARMv82())
1055inline bool CPU_QuerySHA512()
1061 if (!g_hasSHA1 || !g_hasSHA2) {
return false; }
1063#if defined(__ANDROID__) && defined(__aarch64__) && 0
1064 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
1065 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA512) != 0))
1067#elif defined(__ANDROID__) && defined(__aarch32__) && 0
1068 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
1069 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA512) != 0))
1071#elif defined(__linux__) && defined(__aarch64__)
1072 if ((getauxval(AT_HWCAP) & HWCAP_SHA512) != 0)
1074#elif defined(__linux__) && defined(__aarch32__)
1075 if ((getauxval(AT_HWCAP2) & HWCAP2_SHA512) != 0)
1077#elif defined(__APPLE__) && defined(__aarch64__)
1079 if (IsAppleMachineARMv82())
1086inline bool CPU_QuerySM3()
1088#if defined(__ANDROID__) && defined(__aarch64__) && 0
1089 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
1090 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM3) != 0))
1092#elif defined(__ANDROID__) && defined(__aarch32__) && 0
1093 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
1094 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM3) != 0))
1096#elif defined(__linux__) && defined(__aarch64__)
1097 if ((getauxval(AT_HWCAP) & HWCAP_SM3) != 0)
1099#elif defined(__linux__) && defined(__aarch32__)
1100 if ((getauxval(AT_HWCAP2) & HWCAP2_SM3) != 0)
1102#elif defined(__APPLE__) && defined(__aarch64__) && 0
1109inline bool CPU_QuerySM4()
1111#if defined(__ANDROID__) && defined(__aarch64__) && 0
1112 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
1113 ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM4) != 0))
1115#elif defined(__ANDROID__) && defined(__aarch32__) && 0
1116 if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
1117 ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM4) != 0))
1119#elif defined(__linux__) && defined(__aarch64__)
1120 if ((getauxval(AT_HWCAP) & HWCAP_SM4) != 0)
1122#elif defined(__linux__) && defined(__aarch32__)
1123 if ((getauxval(AT_HWCAP2) & HWCAP2_SM4) != 0)
1125#elif defined(__APPLE__) && defined(__aarch64__) && 0
1131void DetectArmFeatures()
1133#ifndef CRYPTOPP_DISABLE_ASM
1137 g_hasARMv7 = CPU_QueryARMv7() || CPU_ProbeARMv7();
1138 g_hasNEON = CPU_QueryNEON() || CPU_ProbeNEON();
1139 g_hasCRC32 = CPU_QueryCRC32() || CPU_ProbeCRC32();
1140 g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
1141 g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
1142 g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1();
1143 g_hasSHA2 = CPU_QuerySHA256() || CPU_ProbeSHA256();
1144 g_hasSHA512 = CPU_QuerySHA512();
1145 g_hasSHA3 = CPU_QuerySHA3();
1146 g_hasSM3 = CPU_QuerySM3();
1147 g_hasSM4 = CPU_QuerySM4();
1149#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
1152 int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
1153 if (cacheLineSize > 0)
1154 g_cacheLineSize = cacheLineSize;
1157 if (g_cacheLineSize == 0)
1158 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
1162 *
const_cast<volatile bool*
>(&g_ArmDetectionDone) =
true;
1167#elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
1169bool CRYPTOPP_SECTION_INIT g_PowerPcDetectionDone =
false;
1170bool CRYPTOPP_SECTION_INIT g_hasAltivec =
false;
1171bool CRYPTOPP_SECTION_INIT g_hasPower7 =
false;
1172bool CRYPTOPP_SECTION_INIT g_hasPower8 =
false;
1173bool CRYPTOPP_SECTION_INIT g_hasPower9 =
false;
1174bool CRYPTOPP_SECTION_INIT g_hasAES =
false;
1175bool CRYPTOPP_SECTION_INIT g_hasPMULL =
false;
1176bool CRYPTOPP_SECTION_INIT g_hasSHA256 =
false;
1177bool CRYPTOPP_SECTION_INIT g_hasSHA512 =
false;
1178bool CRYPTOPP_SECTION_INIT g_hasDARN =
false;
1179word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
1181extern bool CPU_ProbeAltivec();
1182extern bool CPU_ProbePower7();
1183extern bool CPU_ProbePower8();
1184extern bool CPU_ProbePower9();
1185extern bool CPU_ProbeAES();
1186extern bool CPU_ProbePMULL();
1187extern bool CPU_ProbeSHA256();
1188extern bool CPU_ProbeSHA512();
1189extern bool CPU_ProbeDARN();
1195#ifndef __power_6_andup
1196# define __power_6_andup() __power_set(0xffffffffU<<14)
1198#ifndef __power_7_andup
1199# define __power_7_andup() __power_set(0xffffffffU<<15)
1201#ifndef __power_8_andup
1202# define __power_8_andup() __power_set(0xffffffffU<<16)
1204#ifndef __power_9_andup
1205# define __power_9_andup() __power_set(0xffffffffU<<17)
1210inline bool CPU_QueryAltivec()
1212#if defined(__linux__) && defined(PPC_FEATURE_HAS_ALTIVEC)
1213 if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0)
1216 if (__power_6_andup() != 0)
1218#elif defined(__APPLE__) && defined(__POWERPC__)
1219 unsigned int unused, arch;
1220 GetAppleMachineInfo(unused, unused, arch);
1221 return arch == AppleMachineInfo::PowerMac;
1222#elif defined(__FreeBSD__) && defined(PPC_FEATURE_HAS_ALTIVEC)
1223 unsigned long cpufeatures;
1224 if (elf_aux_info(AT_HWCAP, &cpufeatures,
sizeof(cpufeatures)) == 0)
1225 if ((cpufeatures & PPC_FEATURE_HAS_ALTIVEC) != 0)
1231inline bool CPU_QueryPower7()
1234#if defined(__linux__) && defined(PPC_FEATURE_ARCH_2_06)
1235 if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0)
1238 if (__power_7_andup() != 0)
1240#elif defined(__FreeBSD__) && defined(PPC_FEATURE_ARCH_2_06)
1241 unsigned long cpufeatures;
1242 if (elf_aux_info(AT_HWCAP, &cpufeatures,
sizeof(cpufeatures)) == 0)
1243 if ((cpufeatures & PPC_FEATURE_ARCH_2_06) != 0)
1249inline bool CPU_QueryPower8()
1252#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_2_07)
1253 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0)
1256 if (__power_8_andup() != 0)
1258#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_2_07)
1259 unsigned long cpufeatures;
1260 if (elf_aux_info(AT_HWCAP, &cpufeatures,
sizeof(cpufeatures)) == 0)
1261 if ((cpufeatures & PPC_FEATURE_ARCH_2_07) != 0)
1267inline bool CPU_QueryPower9()
1270#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
1271 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
1274 if (__power_9_andup() != 0)
1276#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_3_00)
1277 unsigned long cpufeatures;
1278 if (elf_aux_info(AT_HWCAP, &cpufeatures,
sizeof(cpufeatures)) == 0)
1279 if ((cpufeatures & PPC_FEATURE_ARCH2_3_00) != 0)
1285inline bool CPU_QueryAES()
1289#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
1290 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
1293 if (__power_8_andup() != 0)
1295#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO)
1296 unsigned long cpufeatures;
1297 if (elf_aux_info(AT_HWCAP2, &cpufeatures,
sizeof(cpufeatures)) == 0)
1298 if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0)
1304inline bool CPU_QueryPMULL()
1308#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
1309 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
1312 if (__power_8_andup() != 0)
1314#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO)
1315 unsigned long cpufeatures;
1316 if (elf_aux_info(AT_HWCAP2, &cpufeatures,
sizeof(cpufeatures)) == 0)
1317 if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0)
1323inline bool CPU_QuerySHA256()
1327#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
1328 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
1331 if (__power_8_andup() != 0)
1333#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO)
1334 unsigned long cpufeatures;
1335 if (elf_aux_info(AT_HWCAP2, &cpufeatures,
sizeof(cpufeatures)) == 0)
1336 if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0)
1341inline bool CPU_QuerySHA512()
1345#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
1346 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
1349 if (__power_8_andup() != 0)
1351#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO)
1352 unsigned long cpufeatures;
1353 if (elf_aux_info(AT_HWCAP2, &cpufeatures,
sizeof(cpufeatures)) == 0)
1354 if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0)
1361inline bool CPU_QueryDARN()
1365#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
1366 if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
1369 if (__power_9_andup() != 0)
1371#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_3_00)
1372 unsigned long cpufeatures;
1373 if (elf_aux_info(AT_HWCAP2, &cpufeatures,
sizeof(cpufeatures)) == 0)
1374 if ((cpufeatures & PPC_FEATURE2_ARCH_3_00) != 0)
1380void DetectPowerPcFeatures()
1388#ifndef CRYPTOPP_DISABLE_ASM
1392 g_hasAltivec = CPU_QueryAltivec() || CPU_ProbeAltivec();
1393 g_hasPower7 = CPU_QueryPower7() || CPU_ProbePower7();
1394 g_hasPower8 = CPU_QueryPower8() || CPU_ProbePower8();
1395 g_hasPower9 = CPU_QueryPower9() || CPU_ProbePower9();
1396 g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
1397 g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
1398 g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256();
1399 g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512();
1400 g_hasDARN = CPU_QueryDARN() || CPU_ProbeDARN();
1402#if defined(_AIX) && defined(SC_L1C_DLS)
1404 int cacheLineSize = getsystemcfg(SC_L1C_DLS);
1405 if (cacheLineSize > 0)
1406 g_cacheLineSize = cacheLineSize;
1407#elif defined(_SC_LEVEL1_DCACHE_LINESIZE)
1410 int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
1411 if (cacheLineSize > 0)
1412 g_cacheLineSize = cacheLineSize;
1415 if (g_cacheLineSize == 0)
1416 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
1420 *
const_cast<volatile bool*
>(&g_PowerPcDetectionDone) =
true;
1428ANONYMOUS_NAMESPACE_BEGIN
1435#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
1436 CryptoPP::DetectX86Features();
1437#elif CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8
1438 CryptoPP::DetectArmFeatures();
1439#elif CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
1440 CryptoPP::DetectPowerPcFeatures();
1449#if HAVE_GCC_INIT_PRIORITY
1450 const InitCpu s_init __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) =
InitCpu();
1451#elif HAVE_MSC_INIT_PRIORITY
1452 #pragma warning(disable: 4075)
1453 #pragma init_seg(".CRT$XCU")
1455 #pragma warning(default: 4075)
1456#elif HAVE_XLC_INIT_PRIORITY
1458 #pragma priority(270)
1464ANONYMOUS_NAMESPACE_END
Restricts the instantiation of a class to one static object without locks.
CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
Return a reference to the inner Singleton object.
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Functions for CPU features and intrinsics.
Utility functions for the Crypto++ library.