Botan 2.19.5 Crypto and TLS for C&

Classes | Public Types | Static Public Member Functions | List of all members
Botan::CPUID Class Referencefinal

`#include <cpuid.h>`

## Public Types
enum | CPUID_bits : uint64_t { CPUID_INITIALIZED_BIT = (1ULL << 63) }

## Static Public Member Functions
static std::vector< CPUID::CPUID_bits > | bit_from_string (const std::string &tok)
static size_t | cache_line_size ()
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 void | print (std::ostream &o)
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:

- x86 features using CPUID. x86 is also the only processor with accurate cache line detection currently.
- PowerPC AltiVec detection on Linux, NetBSD, OpenBSD, and macOS
- ARM NEON and crypto extensions detection. On Linux and Android systems which support getauxval, that is used to access CPU feature information. Otherwise a relatively portable but thread-unsafe mechanism involving executing probe functions which catching SIGILL signal is used.

Definition at line 38 of file cpuid.h.

## Member Enumeration Documentation

## ◆ CPUID_bits

enum Botan::CPUID::CPUID_bits : uint64_t

Enumerator
CPUID_INITIALIZED_BIT |

Definition at line 95 of file cpuid.h.

95 : uint64_t {
96#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
97 // These values have no relation to cpuid bitfields
98
99 // SIMD instruction sets
100 CPUID_SSE2_BIT = (1ULL << 0),
101 CPUID_SSSE3_BIT = (1ULL << 1),
102 CPUID_SSE41_BIT = (1ULL << 2),
103 CPUID_SSE42_BIT = (1ULL << 3),
104 CPUID_AVX2_BIT = (1ULL << 4),
105 CPUID_AVX512F_BIT = (1ULL << 5),
106
107 CPUID_AVX512DQ_BIT = (1ULL << 6),
108 CPUID_AVX512BW_BIT = (1ULL << 7),
109
110 // Ice Lake profile: AVX-512 F, DQ, BW, IFMA, VBMI, VBMI2, BITALG
111 CPUID_AVX512_ICL_BIT = (1ULL << 11),
112
113 // Crypto-specific ISAs
114 CPUID_AESNI_BIT = (1ULL << 16),
115 CPUID_CLMUL_BIT = (1ULL << 17),
116 CPUID_RDRAND_BIT = (1ULL << 18),
117 CPUID_RDSEED_BIT = (1ULL << 19),
118 CPUID_SHA_BIT = (1ULL << 20),
119 CPUID_AVX512_AES_BIT = (1ULL << 21),
120 CPUID_AVX512_CLMUL_BIT = (1ULL << 22),
121
122 // Misc useful instructions
123 CPUID_RDTSC_BIT = (1ULL << 48),
124 CPUID_ADX_BIT = (1ULL << 49),
125 CPUID_BMI1_BIT = (1ULL << 50),
126 CPUID_BMI2_BIT = (1ULL << 51),
127#endif
128
129#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
130 CPUID_ALTIVEC_BIT = (1ULL << 0),
131 CPUID_POWER_CRYPTO_BIT = (1ULL << 1),
132 CPUID_DARN_BIT = (1ULL << 2),
133#endif
134
135#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
136 CPUID_ARM_NEON_BIT = (1ULL << 0),
137 CPUID_ARM_SVE_BIT = (1ULL << 1),
138 CPUID_ARM_AES_BIT = (1ULL << 16),
139 CPUID_ARM_PMULL_BIT = (1ULL << 17),
140 CPUID_ARM_SHA1_BIT = (1ULL << 18),
141 CPUID_ARM_SHA2_BIT = (1ULL << 19),
142 CPUID_ARM_SHA3_BIT = (1ULL << 20),
143 CPUID_ARM_SHA2_512_BIT = (1ULL << 21),
144 CPUID_ARM_SM3_BIT = (1ULL << 22),
145 CPUID_ARM_SM4_BIT = (1ULL << 23),
146#endif
147
148 CPUID_INITIALIZED_BIT = (1ULL << 63)
149 };
Botan::CPUID::CPUID_INITIALIZED_BIT
@ CPUID_INITIALIZED_BIT
Definition: cpuid.h:148

## Member Function Documentation

## ◆ bit_from_string()

std::vector< Botan::CPUID::CPUID_bits > Botan::CPUID::bit_from_string | ( | const std::string & | tok | ) |
| static

Definition at line 152 of file cpuid.cpp.

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

References BOTAN_UNUSED.

## ◆ cache_line_size()

static size_t Botan::CPUID::cache_line_size | ( |  | ) |
| inline static

Return a best guess of the cache line size

Definition at line 68 of file cpuid.h.

69 {
70 return state().cache_line_size();
71 }

Referenced by Botan::prefetch_readonly(), and Botan::prefetch_readwrite().

## ◆ clear_cpuid_bit()

static void Botan::CPUID::clear_cpuid_bit | ( | CPUID_bits | bit | ) |
| inline static

Definition at line 415 of file cpuid.h.

416 {
417 state().clear_cpuid_bit(static_cast<uint64_t>(bit));
418 }

## ◆ has_carryless_multiply()

static bool Botan::CPUID::has_carryless_multiply | ( |  | ) |
| inline static

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

Definition at line 395 of file cpuid.h.

396 {
397#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
398 return has_clmul();
399#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
400 return has_arm_pmull();
401#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
402 return has_power_crypto();
403#else
404 return false;
405#endif
406 }

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

## ◆ has_cpuid_bit()

static bool Botan::CPUID::has_cpuid_bit | ( | CPUID_bits | elem | ) |
| inline static

Definition at line 424 of file cpuid.h.

425 {
426 const uint64_t elem64 = static_cast<uint64_t>(elem);
427 return state().has_bit(elem64);
428 }

## ◆ has_hw_aes()

static bool Botan::CPUID::has_hw_aes | ( |  | ) |
| inline static

Check if the processor supports hardware AES instructions

Definition at line 378 of file cpuid.h.

379 {
380#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
381 return has_aes_ni();
382#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
383 return has_arm_aes();
384#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
385 return has_power_crypto();
386#else
387 return false;
388#endif
389 }

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

Definition at line 16 of file cpuid.cpp.

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

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 | ( |  | ) |
| inline static

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

Definition at line 362 of file cpuid.h.

363 {
364#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
365 return has_ssse3();
366#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
367 return has_neon();
368#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
369 return has_altivec();
370#else
371 return false;
372#endif
373 }

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 93 of file cpuid.cpp.

94 {
95 state() = CPUID_Data();
96 }

## ◆ is_big_endian()

static bool Botan::CPUID::is_big_endian | ( |  | ) |
| inline static

Definition at line 84 of file cpuid.h.

85 {
86#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
87 return true;
88#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
89 return false;
90#else
91 return state().endian_status() == Endian_Status::Big;
92#endif
93 }

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

## ◆ is_little_endian()

static bool Botan::CPUID::is_little_endian | ( |  | ) |
| inline static

Definition at line 73 of file cpuid.h.

74 {
75#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
76 return true;
77#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
78 return false;
79#else
80 return state().endian_status() == Endian_Status::Little;
81#endif
82 }

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

## ◆ print()

void Botan::CPUID::print | ( | std::ostream & | o | ) |
| static

Deprecated equivalent to o << "CPUID flags: " << CPUID::to_string() << "\n";

Definition at line 87 of file cpuid.cpp.

88 {
89 o << "CPUID flags: " << CPUID::to_string() << "\n";
90 }
Botan::CPUID::to_string
static std::string to_string()
Definition: cpuid.cpp:30

References to_string().

## ◆ 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 30 of file cpuid.cpp.

31 {
32 std::vector<std::string> flags;
33
34#define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0)
35
36#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
37 CPUID_PRINT(sse2);
38 CPUID_PRINT(ssse3);
39 CPUID_PRINT(sse41);
40 CPUID_PRINT(sse42);
41 CPUID_PRINT(avx2);
42 CPUID_PRINT(avx512f);
43 CPUID_PRINT(avx512dq);
44 CPUID_PRINT(avx512bw);
45 CPUID_PRINT(avx512_icelake);
46
47 CPUID_PRINT(rdtsc);
48 CPUID_PRINT(bmi1);
49 CPUID_PRINT(bmi2);
50 CPUID_PRINT(adx);
51
52 CPUID_PRINT(aes_ni);
53 CPUID_PRINT(clmul);
54 CPUID_PRINT(rdrand);
55 CPUID_PRINT(rdseed);
56 CPUID_PRINT(intel_sha);
57 CPUID_PRINT(avx512_aes);
58 CPUID_PRINT(avx512_clmul);
59#endif
60
61#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
62 CPUID_PRINT(altivec);
63 CPUID_PRINT(power_crypto);
64 CPUID_PRINT(darn_rng);
65#endif
66
67#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
68 CPUID_PRINT(neon);
69 CPUID_PRINT(arm_sve);
70
71 CPUID_PRINT(arm_sha1);
72 CPUID_PRINT(arm_sha2);
73 CPUID_PRINT(arm_aes);
74 CPUID_PRINT(arm_pmull);
75 CPUID_PRINT(arm_sha2_512);
76 CPUID_PRINT(arm_sha3);
77 CPUID_PRINT(arm_sm3);
78 CPUID_PRINT(arm_sm4);
79#endif
80
81#undef CPUID_PRINT
82
83 return string_join(flags, ' ');
84 }
CPUID_PRINT
#define CPUID_PRINT(flag)
Botan::PKCS11::flags
Flags flags(Flag flags)
Definition: p11.h:860
Botan::string_join
std::string string_join(const std::vector< std::string > &strs, char delim)
Definition: parsing.cpp:182

References CPUID_PRINT, Botan::PKCS11::flags(), and Botan::string_join().

Referenced by print().

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

- src/lib/utils/cpuid/cpuid.h
- src/lib/utils/cpuid/cpuid.cpp