Botan 3.3.0
Crypto and TLS for C&
Public Types | Static Public Member Functions | List of all members
Botan::CPUID Class Referencefinal

#include <cpuid.h>

Public Types

enum  CPUID_bits : uint32_t { CPUID_IS_BIG_ENDIAN_BIT = (1U << 30) , CPUID_INITIALIZED_BIT = (1U << 31) }
 

Static Public Member Functions

static std::vector< CPUID::CPUID_bitsbit_from_string (std::string_view tok)
 
static void clear_cpuid_bit (CPUID_bits bit)
 
static bool has_carryless_multiply ()
 
static bool has_cpuid_bit (CPUID_bits elem)
 
static bool has_hw_aes ()
 
static bool has_simd_32 ()
 
static bool has_vperm ()
 
static void initialize ()
 
static bool is_big_endian ()
 
static bool is_little_endian ()
 
static std::string to_string ()
 

Detailed Description

A class handling runtime CPU feature detection. It is limited to just the features necessary to implement CPU specific code in Botan, rather than being a general purpose utility.

This class supports:

Definition at line 36 of file cpuid.h.

Member Enumeration Documentation

◆ CPUID_bits

enum Botan::CPUID::CPUID_bits : uint32_t
Enumerator
CPUID_IS_BIG_ENDIAN_BIT 
CPUID_INITIALIZED_BIT 

Definition at line 79 of file cpuid.h.

79 : uint32_t {
80#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
81 // These values have no relation to cpuid bitfields
82
83 // SIMD instruction sets
84 CPUID_SSE2_BIT = (1U << 0),
85 CPUID_SSSE3_BIT = (1U << 1),
86 CPUID_AVX2_BIT = (1U << 2),
87 CPUID_AVX512_BIT = (1U << 3),
88
89 // Misc useful instructions
90 CPUID_RDTSC_BIT = (1U << 10),
91 CPUID_ADX_BIT = (1U << 11),
92 CPUID_BMI_BIT = (1U << 12),
93
94 // Crypto-specific ISAs
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),
102#endif
103
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),
108#endif
109
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),
121#endif
122
123 CPUID_IS_BIG_ENDIAN_BIT = (1U << 30),
124 CPUID_INITIALIZED_BIT = (1U << 31)
125 };
@ CPUID_INITIALIZED_BIT
Definition cpuid.h:124
@ CPUID_IS_BIG_ENDIAN_BIT
Definition cpuid.h:123

Member Function Documentation

◆ bit_from_string()

std::vector< CPUID::CPUID_bits > Botan::CPUID::bit_from_string ( std::string_view tok)
static

Definition at line 149 of file cpuid.cpp.

149 {
150#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
151 if(tok == "sse2" || tok == "simd") {
152 return {CPUID::CPUID_SSE2_BIT};
153 }
154 if(tok == "ssse3") {
155 return {CPUID::CPUID_SSSE3_BIT};
156 }
157 // aes_ni is the string printed on the console when running "botan cpuid"
158 if(tok == "aesni" || tok == "aes_ni") {
159 return {CPUID::CPUID_AESNI_BIT};
160 }
161 if(tok == "clmul") {
162 return {CPUID::CPUID_CLMUL_BIT};
163 }
164 if(tok == "avx2") {
165 return {CPUID::CPUID_AVX2_BIT};
166 }
167 if(tok == "avx512") {
168 return {CPUID::CPUID_AVX512_BIT};
169 }
170 // there were two if statements testing "sha" and "intel_sha" separately; combined
171 if(tok == "sha" || tok == "intel_sha") {
172 return {CPUID::CPUID_SHA_BIT};
173 }
174 if(tok == "rdtsc") {
175 return {CPUID::CPUID_RDTSC_BIT};
176 }
177 if(tok == "bmi2") {
178 return {CPUID::CPUID_BMI_BIT};
179 }
180 if(tok == "adx") {
181 return {CPUID::CPUID_ADX_BIT};
182 }
183 if(tok == "rdrand") {
184 return {CPUID::CPUID_RDRAND_BIT};
185 }
186 if(tok == "rdseed") {
187 return {CPUID::CPUID_RDSEED_BIT};
188 }
189 if(tok == "avx512_aes") {
190 return {CPUID::CPUID_AVX512_AES_BIT};
191 }
192 if(tok == "avx512_clmul") {
193 return {CPUID::CPUID_AVX512_CLMUL_BIT};
194 }
195
196#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
197 if(tok == "altivec" || tok == "simd")
198 return {CPUID::CPUID_ALTIVEC_BIT};
199 if(tok == "power_crypto")
200 return {CPUID::CPUID_POWER_CRYPTO_BIT};
201 if(tok == "darn_rng")
202 return {CPUID::CPUID_DARN_BIT};
203
204#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
205 if(tok == "neon" || tok == "simd")
206 return {CPUID::CPUID_ARM_NEON_BIT};
207 if(tok == "arm_sve")
208 return {CPUID::CPUID_ARM_SVE_BIT};
209 if(tok == "armv8sha1" || tok == "arm_sha1")
210 return {CPUID::CPUID_ARM_SHA1_BIT};
211 if(tok == "armv8sha2" || tok == "arm_sha2")
212 return {CPUID::CPUID_ARM_SHA2_BIT};
213 if(tok == "armv8aes" || tok == "arm_aes")
214 return {CPUID::CPUID_ARM_AES_BIT};
215 if(tok == "armv8pmull" || tok == "arm_pmull")
216 return {CPUID::CPUID_ARM_PMULL_BIT};
217 if(tok == "armv8sha3" || tok == "arm_sha3")
218 return {CPUID::CPUID_ARM_SHA3_BIT};
219 if(tok == "armv8sha2_512" || tok == "arm_sha2_512")
220 return {CPUID::CPUID_ARM_SHA2_512_BIT};
221 if(tok == "armv8sm3" || tok == "arm_sm3")
222 return {CPUID::CPUID_ARM_SM3_BIT};
223 if(tok == "armv8sm4" || tok == "arm_sm4")
224 return {CPUID::CPUID_ARM_SM4_BIT};
225
226#else
227 BOTAN_UNUSED(tok);
228#endif
229
230 return {};
231}
#define BOTAN_UNUSED
Definition assert.h:118

References BOTAN_UNUSED.

◆ clear_cpuid_bit()

static void Botan::CPUID::clear_cpuid_bit ( CPUID_bits bit)
inlinestatic

Definition at line 327 of file cpuid.h.

327{ state().clear_cpuid_bit(static_cast<uint32_t>(bit)); }

◆ has_carryless_multiply()

static bool Botan::CPUID::has_carryless_multiply ( )
inlinestatic

Check if the processor supports carryless multiply (CLMUL, PMULL)

Definition at line 308 of file cpuid.h.

308 {
309#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
310 return has_clmul();
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();
315#else
316 return false;
317#endif
318 }

Referenced by Botan::GHASH::provider().

◆ has_cpuid_bit()

static bool Botan::CPUID::has_cpuid_bit ( CPUID_bits elem)
inlinestatic

Definition at line 333 of file cpuid.h.

333 {
334 const uint32_t elem32 = static_cast<uint32_t>(elem);
335 return state().has_bit(elem32);
336 }

◆ has_hw_aes()

static bool Botan::CPUID::has_hw_aes ( )
inlinestatic

Check if the processor supports hardware AES instructions

Definition at line 292 of file cpuid.h.

292 {
293#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
294 return has_aes_ni();
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();
299#else
300 return false;
301#endif
302 }

Referenced by Botan::AES_128::decrypt_n(), Botan::AES_192::decrypt_n(), Botan::AES_256::decrypt_n(), Botan::AES_128::encrypt_n(), Botan::AES_192::encrypt_n(), and Botan::AES_256::encrypt_n().

◆ has_simd_32()

bool Botan::CPUID::has_simd_32 ( )
static

Return true if a 4x32 SIMD instruction set is available (SSE2, NEON, or Altivec/VMX)

Definition at line 18 of file cpuid.cpp.

18 {
19#if defined(BOTAN_TARGET_SUPPORTS_SSE2)
20 return CPUID::has_sse2();
21#elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC)
22 return CPUID::has_altivec();
23#elif defined(BOTAN_TARGET_SUPPORTS_NEON)
24 return CPUID::has_neon();
25#else
26 return true;
27#endif
28}

Referenced by Botan::Noekeon::decrypt_n(), Botan::Serpent::decrypt_n(), Botan::SHACAL2::decrypt_n(), Botan::Noekeon::encrypt_n(), Botan::Serpent::encrypt_n(), Botan::SHACAL2::encrypt_n(), Botan::Noekeon::parallelism(), Botan::SHACAL2::parallelism(), Botan::Noekeon::provider(), Botan::Serpent::provider(), Botan::SHACAL2::provider(), and Botan::ChaCha::provider().

◆ has_vperm()

static bool Botan::CPUID::has_vperm ( )
inlinestatic

Check if the processor supports byte-level vector permutes (SSSE3, NEON, Altivec)

Definition at line 277 of file cpuid.h.

277 {
278#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
279 return has_ssse3();
280#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
281 return has_neon();
282#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
283 return has_altivec();
284#else
285 return false;
286#endif
287 }

Referenced by Botan::AES_128::decrypt_n(), Botan::AES_192::decrypt_n(), Botan::AES_256::decrypt_n(), Botan::AES_128::encrypt_n(), Botan::AES_192::encrypt_n(), Botan::AES_256::encrypt_n(), Botan::ZFEC::provider(), and Botan::GHASH::provider().

◆ initialize()

void Botan::CPUID::initialize ( )
static

Probe the CPU and see what extensions are supported

Definition at line 88 of file cpuid.cpp.

88 {
89 state() = CPUID_Data();
90}

◆ is_big_endian()

static bool Botan::CPUID::is_big_endian ( )
inlinestatic

Definition at line 69 of file cpuid.h.

69 {
70#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
71 return true;
72#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
73 return false;
74#else
76#endif
77 }
static bool has_cpuid_bit(CPUID_bits elem)
Definition cpuid.h:333

Referenced by Botan::SIMD_4x32::load_le().

◆ is_little_endian()

static bool Botan::CPUID::is_little_endian ( )
inlinestatic

Definition at line 59 of file cpuid.h.

59 {
60#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
61 return true;
62#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
63 return false;
64#else
66#endif
67 }

Referenced by Botan::XMSS_Tools::concat(), Botan::XMSS_Tools::concat(), Botan::SIMD_4x32::load_be(), Botan::SIMD_4x32::store_be(), and Botan::SIMD_4x32::store_le().

◆ to_string()

std::string Botan::CPUID::to_string ( )
static

Return a possibly empty string containing list of known CPU extensions. Each name will be seperated by a space, and the ordering will be arbitrary. This list only contains values that are useful to Botan (for example FMA instructions are not checked).

Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec"

Definition at line 31 of file cpuid.cpp.

31 {
32 std::vector<std::string> flags;
33
34 auto append_fn = [&](bool flag, const char* flag_name) {
35 if(flag) {
36 flags.push_back(flag_name);
37 }
38 };
39
40 // NOLINTNEXTLINE(*-macro-usage)
41#define CPUID_PRINT(flag) append_fn(has_##flag(), #flag)
42
43#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
44 CPUID_PRINT(rdtsc);
45
46 CPUID_PRINT(sse2);
47 CPUID_PRINT(ssse3);
48 CPUID_PRINT(avx2);
49
50 CPUID_PRINT(bmi2);
51 CPUID_PRINT(adx);
52
53 CPUID_PRINT(aes_ni);
54 CPUID_PRINT(clmul);
55 CPUID_PRINT(rdrand);
56 CPUID_PRINT(rdseed);
57 CPUID_PRINT(intel_sha);
58
59 CPUID_PRINT(avx512);
60 CPUID_PRINT(avx512_aes);
61 CPUID_PRINT(avx512_clmul);
62#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
63 CPUID_PRINT(altivec);
64 CPUID_PRINT(power_crypto);
65 CPUID_PRINT(darn_rng);
66#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
67 CPUID_PRINT(neon);
68 CPUID_PRINT(arm_sve);
69
70 CPUID_PRINT(arm_sha1);
71 CPUID_PRINT(arm_sha2);
72 CPUID_PRINT(arm_aes);
73 CPUID_PRINT(arm_pmull);
74 CPUID_PRINT(arm_sha2_512);
75 CPUID_PRINT(arm_sha3);
76 CPUID_PRINT(arm_sm3);
77 CPUID_PRINT(arm_sm4);
78#else
79 BOTAN_UNUSED(append_fn);
80#endif
81
82#undef CPUID_PRINT
83
84 return string_join(flags, ' ');
85}
#define CPUID_PRINT(flag)
Flags flags(Flag flags)
Definition p11.h:836
std::string string_join(const std::vector< std::string > &strs, char delim)
Definition parsing.cpp:140

References BOTAN_UNUSED, CPUID_PRINT, and Botan::string_join().


The documentation for this class was generated from the following files: