• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 6641526834

25 Oct 2023 02:01PM UTC coverage: 91.677% (-0.04%) from 91.712%
6641526834

push

github

web-flow
Merge pull request #3773 from FAlbertDev/fix/tlsanvil-nightly-fail

TLS-Anvil nightly CI fix

80099 of 87371 relevant lines covered (91.68%)

8564496.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.94
/src/lib/utils/cpuid/cpuid.cpp
1
/*
2
* Runtime CPU detection
3
* (C) 2009,2010,2013,2017,2023 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/internal/cpuid.h>
9

10
#include <botan/exceptn.h>
11
#include <botan/types.h>
12
#include <botan/internal/os_utils.h>
13
#include <botan/internal/parsing.h>
14
#include <ostream>
15

16
namespace Botan {
17

18
bool CPUID::has_simd_32() {
299,401✔
19
#if defined(BOTAN_TARGET_SUPPORTS_SSE2)
20
   return CPUID::has_sse2();
299,401✔
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
}
29

30
//static
31
std::string CPUID::to_string() {
14✔
32
   std::vector<std::string> flags;
14✔
33

34
   auto append_fn = [&](bool flag, const char* flag_name) {
210✔
35
      if(flag) {
196✔
36
         flags.push_back(flag_name);
196✔
37
      }
38
   };
196✔
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);
14✔
45

46
   CPUID_PRINT(sse2);
14✔
47
   CPUID_PRINT(ssse3);
14✔
48
   CPUID_PRINT(avx2);
14✔
49

50
   CPUID_PRINT(bmi2);
14✔
51
   CPUID_PRINT(adx);
14✔
52

53
   CPUID_PRINT(aes_ni);
14✔
54
   CPUID_PRINT(clmul);
14✔
55
   CPUID_PRINT(rdrand);
14✔
56
   CPUID_PRINT(rdseed);
14✔
57
   CPUID_PRINT(intel_sha);
14✔
58

59
   CPUID_PRINT(avx512);
14✔
60
   CPUID_PRINT(avx512_aes);
14✔
61
   CPUID_PRINT(avx512_clmul);
14✔
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, ' ');
28✔
85
}
14✔
86

87
//static
88
void CPUID::initialize() {
5,604✔
89
   state() = CPUID_Data();
5,604✔
90
}
5,604✔
91

92
namespace {
93

94
// Returns true if big-endian
95
bool runtime_check_if_big_endian() {
12,867✔
96
   // Check runtime endian
97
   const uint32_t endian32 = 0x01234567;
12,867✔
98
   const uint8_t* e8 = reinterpret_cast<const uint8_t*>(&endian32);
12,867✔
99

100
   bool is_big_endian = false;
12,867✔
101

102
   if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) {
12,867✔
103
      is_big_endian = true;
104
   } else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) {
12,867✔
105
      is_big_endian = false;
106
   } else {
107
      throw Internal_Error("Unexpected endian at runtime, neither big nor little");
108
   }
109

110
   // If we were compiled with a known endian, verify it matches at runtime
111
#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
112
   BOTAN_ASSERT(!is_big_endian, "Build and runtime endian match");
12,867✔
113
#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
114
   BOTAN_ASSERT(is_big_endian, "Build and runtime endian match");
115
#endif
116

117
   return is_big_endian;
12,867✔
118
}
119

120
}  // namespace
121

122
CPUID::CPUID_Data::CPUID_Data() {
12,867✔
123
   m_processor_features = 0;
12,867✔
124

125
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
126
   defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
127

128
   m_processor_features = detect_cpu_features();
12,867✔
129

130
#endif
131

132
   m_processor_features |= CPUID::CPUID_INITIALIZED_BIT;
12,867✔
133

134
   if(runtime_check_if_big_endian()) {
12,867✔
135
      m_processor_features |= CPUID::CPUID_IS_BIG_ENDIAN_BIT;
136
   }
137

138
   std::string clear_cpuid_env;
12,867✔
139
   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
12,867✔
140
      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
316✔
141
         for(auto& bit : CPUID::bit_from_string(cpuid)) {
316✔
142
            const uint32_t cleared = ~static_cast<uint32_t>(bit);
158✔
143
            m_processor_features &= cleared;
158✔
144
         }
158✔
145
      }
158✔
146
   }
147
}
12,867✔
148

149
std::vector<CPUID::CPUID_bits> CPUID::bit_from_string(std::string_view tok) {
198✔
150
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
151
   if(tok == "sse2" || tok == "simd") {
230✔
152
      return {CPUID::CPUID_SSE2_BIT};
7✔
153
   }
154
   if(tok == "ssse3") {
200✔
155
      return {CPUID::CPUID_SSSE3_BIT};
6✔
156
   }
157
   // aes_ni is the string printed on the console when running "botan cpuid"
158
   if(tok == "aesni" || tok == "aes_ni") {
349✔
159
      return {CPUID::CPUID_AESNI_BIT};
4✔
160
   }
161
   if(tok == "clmul") {
184✔
162
      return {CPUID::CPUID_CLMUL_BIT};
3✔
163
   }
164
   if(tok == "avx2") {
184✔
165
      return {CPUID::CPUID_AVX2_BIT};
6✔
166
   }
167
   if(tok == "avx512") {
324✔
168
      return {CPUID::CPUID_AVX512_BIT};
2✔
169
   }
170
   // there were two if statements testing "sha" and "intel_sha" separately; combined
171
   if(tok == "sha" || tok == "intel_sha") {
175✔
172
      return {CPUID::CPUID_SHA_BIT};
3✔
173
   }
174
   if(tok == "rdtsc") {
169✔
175
      return {CPUID::CPUID_RDTSC_BIT};
1✔
176
   }
177
   if(tok == "bmi2") {
168✔
178
      return {CPUID::CPUID_BMI_BIT};
4✔
179
   }
180
   if(tok == "adx") {
162✔
181
      return {CPUID::CPUID_ADX_BIT};
×
182
   }
183
   if(tok == "rdrand") {
163✔
184
      return {CPUID::CPUID_RDRAND_BIT};
151✔
185
   }
186
   if(tok == "rdseed") {
12✔
187
      return {CPUID::CPUID_RDSEED_BIT};
×
188
   }
189
   if(tok == "avx512_aes") {
11✔
190
      return {CPUID::CPUID_AVX512_AES_BIT};
×
191
   }
192
   if(tok == "avx512_clmul") {
12✔
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 {};
11✔
231
}
232

233
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc