Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

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

`#include <cpuid.h>`

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

## Static Public Member Functions
static size_t | cache_line_size ()
static void | clear_cpuid_bit (CPUID_bits bit)
static bool | has_cpuid_bit (CPUID_bits elem)
static bool | has_simd_32 ()
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 Darwin
- 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 35 of file cpuid.h.

## Member Enumeration Documentation

enum Botan::CPUID::CPUID_bits : uint64_t

Enumerator
CPUID_INITIALIZED_BIT |

Definition at line 92 of file cpuid.h.

92 : uint64_t {
93 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
94 // These values have no relation to cpuid bitfields
95
96 // SIMD instruction sets
97 CPUID_SSE2_BIT = (1ULL << 0),
98 CPUID_SSSE3_BIT = (1ULL << 1),
99 CPUID_SSE41_BIT = (1ULL << 2),
100 CPUID_SSE42_BIT = (1ULL << 3),
101 CPUID_AVX2_BIT = (1ULL << 4),
102 CPUID_AVX512F_BIT = (1ULL << 5),
103
104 // Misc useful instructions
105 CPUID_RDTSC_BIT = (1ULL << 10),
106 CPUID_BMI2_BIT = (1ULL << 11),
107 CPUID_ADX_BIT = (1ULL << 12),
108
109 // Crypto-specific ISAs
110 CPUID_AESNI_BIT = (1ULL << 16),
111 CPUID_CLMUL_BIT = (1ULL << 17),
112 CPUID_RDRAND_BIT = (1ULL << 18),
113 CPUID_RDSEED_BIT = (1ULL << 19),
114 CPUID_SHA_BIT = (1ULL << 20),
115 #endif
116
117 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
118 CPUID_ALTIVEC_BIT = (1ULL << 0),
119 #endif
120
121 #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
122 CPUID_ARM_NEON_BIT = (1ULL << 0),
123 CPUID_ARM_AES_BIT = (1ULL << 16),
124 CPUID_ARM_PMULL_BIT = (1ULL << 17),
125 CPUID_ARM_SHA1_BIT = (1ULL << 18),
126 CPUID_ARM_SHA2_BIT = (1ULL << 19),
127 #endif
128
129 CPUID_INITIALIZED_BIT = (1ULL << 63)
130 };
Botan::CPUID::CPUID_INITIALIZED_BIT
Definition: cpuid.h:129

## Member Function Documentation

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

Return a best guess of the cache line size

Definition at line 65 of file cpuid.h.

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

66 {
67 if(g_processor_features == 0)
68 {
69 initialize();
70 }
71 return g_cache_line_size;
72 }
Botan::CPUID::initialize
static void initialize()
Definition: cpuid.cpp:413

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

Definition at line 266 of file cpuid.h.

267 {
268 const uint64_t mask = ~(static_cast<uint64_t>(bit));
269 g_processor_features &= mask;
270 }

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

Definition at line 276 of file cpuid.h.

277 {
278 if(g_processor_features == 0)
279 initialize();
280 return ((g_processor_features & static_cast<uint64_t>(elem)) != 0);
281 }
Botan::CPUID::initialize
static void initialize()
Definition: cpuid.cpp:413

bool Botan::CPUID::has_simd_32 | ( |  | ) |
| static

Definition at line 351 of file cpuid.cpp.

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

352 {
353 #if defined(BOTAN_TARGET_SUPPORTS_SSE2)
354 return CPUID::has_sse2();
355 #elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC)
356 return CPUID::has_altivec();
357 #elif defined(BOTAN_TARGET_SUPPORTS_NEON)
358 return CPUID::has_neon();
359 #else
360 return true;
361 #endif
362 }

void Botan::CPUID::initialize | ( |  | ) |
| static

Probe the CPU and see what extensions are supported

Definition at line 413 of file cpuid.cpp.

References BOTAN_ASSERT, and CPUID_INITIALIZED_BIT.

414 {
415 g_processor_features = 0;
416
417 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
418 g_processor_features = powerpc_detect_cpu_featutures();
419 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
420 g_processor_features = arm_detect_cpu_features(&g_cache_line_size);
421 #elif defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
422 g_processor_features = x86_detect_cpu_features(&g_cache_line_size);
423 #endif
424
425 g_processor_features |= CPUID::CPUID_INITIALIZED_BIT;
426
427 // Check runtime endian
428 const uint32_t endian32 = 0x01234567;
429 const uint8_t* e8 = reinterpret_cast<const uint8_t*>(&endian32);
430
431 if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67)
432 {
433 g_little_endian = false;
434 }
435 else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01)
436 {
437 g_little_endian = true;
438 }
439 else
440 {
441 throw Internal_Error("Unexpected endian at runtime, neither big nor little");
442 }
443
444 // If we were compiled with a known endian, verify it matches at runtime
445 #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
446 BOTAN_ASSERT(g_little_endian == true, "Build and runtime endian match");
447 #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
448 BOTAN_ASSERT(g_little_endian == false, "Build and runtime endian match");
449 #endif
450
451 }
Botan::CPUID::CPUID_INITIALIZED_BIT
Definition: cpuid.h:129
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27

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

Definition at line 83 of file cpuid.h.

Referenced by Botan::SIMD_4x32::load_le(), and Botan::SIMD_4x32::store_le().

84 {
85 /*
86 * We do not support PDP endian, so the endian is
87 * always either big or little.
88 */
89 return is_little_endian() == false;
90 }
Botan::CPUID::is_little_endian
static bool is_little_endian()
Definition: cpuid.h:74

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

Definition at line 74 of file cpuid.h.

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

75 {
76 if(g_processor_features == 0)
77 {
78 initialize();
79 }
80 return g_little_endian;
81 }
Botan::CPUID::initialize
static void initialize()
Definition: cpuid.cpp:413

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

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

Definition at line 408 of file cpuid.cpp.

References to_string().

409 {
410 o << "CPUID flags: " << CPUID::to_string() << "\n";
411 }
Botan::CPUID::to_string
static std::string to_string()
Definition: cpuid.cpp:365

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

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

Referenced by print().

366 {
367 std::vector<std::string> flags;
368
369 #define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0)
370
371 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
372 CPUID_PRINT(sse2);
373 CPUID_PRINT(ssse3);
374 CPUID_PRINT(sse41);
375 CPUID_PRINT(sse42);
376 CPUID_PRINT(avx2);
377 CPUID_PRINT(avx512f);
378
379 CPUID_PRINT(rdtsc);
380 CPUID_PRINT(bmi2);
381 CPUID_PRINT(adx);
382
383 CPUID_PRINT(aes_ni);
384 CPUID_PRINT(clmul);
385 CPUID_PRINT(rdrand);
386 CPUID_PRINT(rdseed);
387 CPUID_PRINT(intel_sha);
388 #endif
389
390 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
391 CPUID_PRINT(altivec);
392 #endif
393
394 #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
395 CPUID_PRINT(neon);
396 CPUID_PRINT(arm_sha1);
397 CPUID_PRINT(arm_sha2);
398 CPUID_PRINT(arm_aes);
399 CPUID_PRINT(arm_pmull);
400 #endif
401
402 #undef CPUID_PRINT
403
404 return string_join(flags, ' ');
405 }
Botan::string_join
std::string string_join(const std::vector< std::string > &strs, char delim)
Definition: parsing.cpp:172
Botan::PKCS11::flags
Flags flags(Flag flags)
Definition: p11.h:858
CPUID_PRINT
#define CPUID_PRINT(flag)

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

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