11#include <botan/types.h>
42 static void initialize();
48 static bool has_simd_32();
58 static std::string to_string();
62#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
64#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
67 return !has_cpuid_bit(CPUID_IS_BIG_ENDIAN_BIT);
73#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
75#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
78 return has_cpuid_bit(CPUID_IS_BIG_ENDIAN_BIT);
83#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
87 CPUID_SSE2_BIT = (1U << 0),
88 CPUID_SSSE3_BIT = (1U << 1),
89 CPUID_AVX2_BIT = (1U << 2),
90 CPUID_AVX512_BIT = (1U << 3),
93 CPUID_RDTSC_BIT = (1U << 10),
94 CPUID_ADX_BIT = (1U << 11),
95 CPUID_BMI_BIT = (1U << 12),
98 CPUID_AESNI_BIT = (1U << 16),
99 CPUID_CLMUL_BIT = (1U << 17),
100 CPUID_RDRAND_BIT = (1U << 18),
101 CPUID_RDSEED_BIT = (1U << 19),
102 CPUID_SHA_BIT = (1U << 20),
103 CPUID_AVX512_AES_BIT = (1U << 21),
104 CPUID_AVX512_CLMUL_BIT = (1U << 22),
107#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
108 CPUID_ALTIVEC_BIT = (1U << 0),
109 CPUID_POWER_CRYPTO_BIT = (1U << 1),
110 CPUID_DARN_BIT = (1U << 2),
113#
if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
114 CPUID_ARM_NEON_BIT = (1U << 0),
115 CPUID_ARM_SVE_BIT = (1U << 1),
116 CPUID_ARM_AES_BIT = (1U << 16),
117 CPUID_ARM_PMULL_BIT = (1U << 17),
118 CPUID_ARM_SHA1_BIT = (1U << 18),
119 CPUID_ARM_SHA2_BIT = (1U << 19),
120 CPUID_ARM_SHA3_BIT = (1U << 20),
121 CPUID_ARM_SHA2_512_BIT = (1U << 21),
122 CPUID_ARM_SM3_BIT = (1U << 22),
123 CPUID_ARM_SM4_BIT = (1U << 23),
126 CPUID_IS_BIG_ENDIAN_BIT = (1U << 30),
127 CPUID_INITIALIZED_BIT = (1U << 31)
130#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
134 static bool has_altivec()
135 {
return has_cpuid_bit(CPUID_ALTIVEC_BIT); }
140 static bool has_power_crypto()
141 {
return has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
146 static bool has_darn_rng()
147 {
return has_cpuid_bit(CPUID_DARN_BIT); }
151#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
155 static bool has_neon()
156 {
return has_cpuid_bit(CPUID_ARM_NEON_BIT); }
161 static bool has_arm_sve()
162 {
return has_cpuid_bit(CPUID_ARM_SVE_BIT); }
167 static bool has_arm_sha1()
168 {
return has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
173 static bool has_arm_sha2()
174 {
return has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
179 static bool has_arm_aes()
180 {
return has_cpuid_bit(CPUID_ARM_AES_BIT); }
185 static bool has_arm_pmull()
186 {
return has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
191 static bool has_arm_sha2_512()
192 {
return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
197 static bool has_arm_sha3()
198 {
return has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
203 static bool has_arm_sm3()
204 {
return has_cpuid_bit(CPUID_ARM_SM3_BIT); }
209 static bool has_arm_sm4()
210 {
return has_cpuid_bit(CPUID_ARM_SM4_BIT); }
214#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
219 static bool has_rdtsc()
220 {
return has_cpuid_bit(CPUID_RDTSC_BIT); }
225 static bool has_sse2()
226 {
return has_cpuid_bit(CPUID_SSE2_BIT); }
231 static bool has_ssse3()
232 {
return has_cpuid_bit(CPUID_SSSE3_BIT); }
237 static bool has_avx2()
238 {
return has_cpuid_bit(CPUID_AVX2_BIT); }
245 static bool has_avx512()
246 {
return has_cpuid_bit(CPUID_AVX512_BIT); }
251 static bool has_avx512_aes()
252 {
return has_cpuid_bit(CPUID_AVX512_AES_BIT); }
257 static bool has_avx512_clmul()
258 {
return has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
263 static bool has_bmi2()
264 {
return has_cpuid_bit(CPUID_BMI_BIT); }
269 static bool has_aes_ni()
270 {
return has_cpuid_bit(CPUID_AESNI_BIT); }
275 static bool has_clmul()
276 {
return has_cpuid_bit(CPUID_CLMUL_BIT); }
281 static bool has_intel_sha()
282 {
return has_cpuid_bit(CPUID_SHA_BIT); }
287 static bool has_adx()
288 {
return has_cpuid_bit(CPUID_ADX_BIT); }
293 static bool has_rdrand()
294 {
return has_cpuid_bit(CPUID_RDRAND_BIT); }
299 static bool has_rdseed()
300 {
return has_cpuid_bit(CPUID_RDSEED_BIT); }
309#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
311#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
313#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
314 return has_altivec();
325#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
327#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
328 return has_arm_aes();
329#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
330 return has_power_crypto();
342#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
344#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
345 return has_arm_pmull();
346#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
347 return has_power_crypto();
362 state().clear_cpuid_bit(
static_cast<uint32_t
>(bit));
371 const uint32_t elem32 =
static_cast<uint32_t
>(elem);
372 return state().has_bit(elem32);
375 static std::vector<CPUID::CPUID_bits> bit_from_string(std::string_view tok);
382 CPUID_Data(
const CPUID_Data& other) =
default;
383 CPUID_Data& operator=(
const CPUID_Data& other) =
default;
385 void clear_cpuid_bit(uint32_t bit)
387 m_processor_features &= ~bit;
390 bool has_bit(uint32_t bit)
const
392 return (m_processor_features & bit) == bit;
396#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \
397 defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
398 defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
400 static uint32_t detect_cpu_features();
403 uint32_t m_processor_features;
406 static CPUID_Data& state()
408 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 *)