11#include <botan/types.h>
41 static void initialize();
47 static bool has_simd_32();
57 static std::string to_string();
60#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
62#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
65 return !has_cpuid_bit(CPUID_IS_BIG_ENDIAN_BIT);
70#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
72#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
75 return has_cpuid_bit(CPUID_IS_BIG_ENDIAN_BIT);
80#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
84 CPUID_SSE2_BIT = (1U << 0),
85 CPUID_SSSE3_BIT = (1U << 1),
86 CPUID_AVX2_BIT = (1U << 2),
87 CPUID_AVX512_BIT = (1U << 3),
90 CPUID_RDTSC_BIT = (1U << 10),
91 CPUID_ADX_BIT = (1U << 11),
92 CPUID_BMI_BIT = (1U << 12),
95 CPUID_AESNI_BIT = (1U << 16),
96 CPUID_CLMUL_BIT = (1U << 17),
97 CPUID_RDRAND_BIT = (1U << 18),
98 CPUID_RDSEED_BIT = (1U << 19),
99 CPUID_SHA_BIT = (1U << 20),
100 CPUID_AVX512_AES_BIT = (1U << 21),
101 CPUID_AVX512_CLMUL_BIT = (1U << 22),
104#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
105 CPUID_ALTIVEC_BIT = (1U << 0),
106 CPUID_POWER_CRYPTO_BIT = (1U << 1),
107 CPUID_DARN_BIT = (1U << 2),
110#
if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
111 CPUID_ARM_NEON_BIT = (1U << 0),
112 CPUID_ARM_SVE_BIT = (1U << 1),
113 CPUID_ARM_AES_BIT = (1U << 16),
114 CPUID_ARM_PMULL_BIT = (1U << 17),
115 CPUID_ARM_SHA1_BIT = (1U << 18),
116 CPUID_ARM_SHA2_BIT = (1U << 19),
117 CPUID_ARM_SHA3_BIT = (1U << 20),
118 CPUID_ARM_SHA2_512_BIT = (1U << 21),
119 CPUID_ARM_SM3_BIT = (1U << 22),
120 CPUID_ARM_SM4_BIT = (1U << 23),
123 CPUID_IS_BIG_ENDIAN_BIT = (1U << 30),
124 CPUID_INITIALIZED_BIT = (1U << 31)
127#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
131 static bool has_altivec() {
return has_cpuid_bit(CPUID_ALTIVEC_BIT); }
136 static bool has_power_crypto() {
return has_altivec() && has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
141 static bool has_darn_rng() {
return has_cpuid_bit(CPUID_DARN_BIT); }
145#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
149 static bool has_neon() {
return has_cpuid_bit(CPUID_ARM_NEON_BIT); }
154 static bool has_arm_sve() {
return has_cpuid_bit(CPUID_ARM_SVE_BIT); }
159 static bool has_arm_sha1() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
164 static bool has_arm_sha2() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
169 static bool has_arm_aes() {
return has_neon() && has_cpuid_bit(CPUID_ARM_AES_BIT); }
174 static bool has_arm_pmull() {
return has_neon() && has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
179 static bool has_arm_sha2_512() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
184 static bool has_arm_sha3() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
189 static bool has_arm_sm3() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SM3_BIT); }
194 static bool has_arm_sm4() {
return has_neon() && has_cpuid_bit(CPUID_ARM_SM4_BIT); }
198#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
203 static bool has_rdtsc() {
return has_cpuid_bit(CPUID_RDTSC_BIT); }
208 static bool has_sse2() {
return has_cpuid_bit(CPUID_SSE2_BIT); }
213 static bool has_ssse3() {
return has_sse2() && has_cpuid_bit(CPUID_SSSE3_BIT); }
218 static bool has_avx2() {
return has_cpuid_bit(CPUID_AVX2_BIT); }
225 static bool has_avx512() {
return has_cpuid_bit(CPUID_AVX512_BIT); }
230 static bool has_avx512_aes() {
return has_avx512() && has_cpuid_bit(CPUID_AVX512_AES_BIT); }
235 static bool has_avx512_clmul() {
return has_avx512() && has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
240 static bool has_bmi2() {
return has_cpuid_bit(CPUID_BMI_BIT); }
245 static bool has_aes_ni() {
return has_ssse3() && has_cpuid_bit(CPUID_AESNI_BIT); }
250 static bool has_clmul() {
return has_ssse3() && has_cpuid_bit(CPUID_CLMUL_BIT); }
255 static bool has_intel_sha() {
return has_sse2() && has_cpuid_bit(CPUID_SHA_BIT); }
260 static bool has_adx() {
return has_cpuid_bit(CPUID_ADX_BIT); }
265 static bool has_rdrand() {
return has_cpuid_bit(CPUID_RDRAND_BIT); }
270 static bool has_rdseed() {
return has_cpuid_bit(CPUID_RDSEED_BIT); }
278#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
280#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
282#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
283 return has_altivec();
293#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
295#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
296 return has_arm_aes();
297#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
298 return has_power_crypto();
309#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
311#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
312 return has_arm_pmull();
313#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
314 return has_power_crypto();
334 const uint32_t elem32 =
static_cast<uint32_t
>(elem);
335 return state().has_bit(elem32);
338 static std::vector<CPUID::CPUID_bits> bit_from_string(std::string_view tok);
345 CPUID_Data(
const CPUID_Data& other) =
default;
346 CPUID_Data& operator=(
const CPUID_Data& other) =
default;
348 void clear_cpuid_bit(uint32_t bit) { m_processor_features &= ~bit; }
350 bool has_bit(uint32_t bit)
const {
return (m_processor_features & bit) == bit; }
353#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
354 defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
356 static uint32_t detect_cpu_features();
359 uint32_t m_processor_features;
362 static CPUID_Data& state() {
363 static CPUID::CPUID_Data g_cpuid;
static bool is_little_endian()
static bool is_big_endian()
static bool has_cpuid_bit(CPUID_bits elem)
static bool has_carryless_multiply()
static void clear_cpuid_bit(CPUID_bits bit)
int(* final)(unsigned char *, CTX *)