blinit.c (17541B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifdef FREEBL_NO_DEPEND 6 #include "stubs.h" 7 #endif 8 9 #include "blapii.h" 10 #include "mpi.h" 11 #include "secerr.h" 12 #include "prtypes.h" 13 #include "prinit.h" 14 #include "prenv.h" 15 16 #if defined(_MSC_VER) && !defined(_M_IX86) 17 #include <intrin.h> /* for _xgetbv() */ 18 #endif 19 20 #if defined(_WIN64) && defined(__aarch64__) 21 #include <windows.h> 22 #endif 23 24 #if defined(DARWIN) 25 #include <TargetConditionals.h> 26 #endif 27 28 static PRCallOnceType coFreeblInit; 29 30 /* State variables. */ 31 static PRBool aesni_support_ = PR_FALSE; 32 static PRBool clmul_support_ = PR_FALSE; 33 static PRBool sha_support_ = PR_FALSE; 34 static PRBool avx_support_ = PR_FALSE; 35 static PRBool avx2_support_ = PR_FALSE; 36 static PRBool adx_support_ = PR_FALSE; 37 static PRBool ssse3_support_ = PR_FALSE; 38 static PRBool sse4_1_support_ = PR_FALSE; 39 static PRBool sse4_2_support_ = PR_FALSE; 40 static PRBool arm_neon_support_ = PR_FALSE; 41 static PRBool arm_aes_support_ = PR_FALSE; 42 static PRBool arm_sha1_support_ = PR_FALSE; 43 static PRBool arm_sha2_support_ = PR_FALSE; 44 static PRBool arm_pmull_support_ = PR_FALSE; 45 static PRBool ppc_crypto_support_ = PR_FALSE; 46 47 #ifdef NSS_X86_OR_X64 48 /* 49 * Adapted from the example code in "How to detect New Instruction support in 50 * the 4th generation Intel Core processor family" by Max Locktyukhin. 51 * https://www.intel.com/content/dam/develop/external/us/en/documents/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf 52 * 53 * XGETBV: 54 * Reads an extended control register (XCR) specified by ECX into EDX:EAX. 55 */ 56 static PRBool 57 check_xcr0_ymm() 58 { 59 PRUint32 xcr0; 60 #if defined(_MSC_VER) 61 #if defined(_M_IX86) 62 __asm { 63 mov ecx, 0 64 xgetbv 65 mov xcr0, eax 66 } 67 #else 68 xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ 69 #endif /* _M_IX86 */ 70 #else /* _MSC_VER */ 71 /* Old OSX compilers don't support xgetbv. Use byte form. */ 72 __asm__(".byte 0x0F, 0x01, 0xd0" 73 : "=a"(xcr0) 74 : "c"(0) 75 : "%edx"); 76 #endif /* _MSC_VER */ 77 /* Check if xmm and ymm state are enabled in XCR0. */ 78 return (xcr0 & 6) == 6; 79 } 80 81 #define ECX_AESNI (1 << 25) 82 #define ECX_CLMUL (1 << 1) 83 #define ECX_XSAVE (1 << 26) 84 #define ECX_OSXSAVE (1 << 27) 85 #define ECX_AVX (1 << 28) 86 #define EBX_AVX2 (1 << 5) 87 #define EBX_ADX (1 << 19) 88 #define EBX_BMI1 (1 << 3) 89 #define EBX_BMI2 (1 << 8) 90 #define EBX_SHA (1 << 29) 91 #define ECX_FMA (1 << 12) 92 #define ECX_MOVBE (1 << 22) 93 #define ECX_SSSE3 (1 << 9) 94 #define ECX_SSE4_1 (1 << 19) 95 #define ECX_SSE4_2 (1 << 20) 96 #define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX) 97 #define AVX2_EBX_BITS (EBX_AVX2 | EBX_BMI1 | EBX_BMI2) 98 #define AVX2_ECX_BITS (ECX_FMA | ECX_MOVBE) 99 100 void 101 CheckX86CPUSupport() 102 { 103 unsigned long eax, ebx, ecx, edx; 104 unsigned long eax7, ebx7, ecx7, edx7; 105 char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); 106 char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL"); 107 char *disable_hw_sha = PR_GetEnvSecure("NSS_DISABLE_HW_SHA"); 108 char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX"); 109 char *disable_avx2 = PR_GetEnvSecure("NSS_DISABLE_AVX2"); 110 char *disable_adx = PR_GetEnvSecure("NSS_DISABLE_ADX"); 111 char *disable_ssse3 = PR_GetEnvSecure("NSS_DISABLE_SSSE3"); 112 char *disable_sse4_1 = PR_GetEnvSecure("NSS_DISABLE_SSE4_1"); 113 char *disable_sse4_2 = PR_GetEnvSecure("NSS_DISABLE_SSE4_2"); 114 freebl_cpuid(1, &eax, &ebx, &ecx, &edx); 115 freebl_cpuid(7, &eax7, &ebx7, &ecx7, &edx7); 116 aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL); 117 clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL); 118 sha_support_ = (PRBool)((ebx7 & EBX_SHA) != 0 && disable_hw_sha == NULL); 119 /* For AVX we ensure that: 120 * - The AVX, OSXSAVE, and XSAVE bits of ECX from CPUID(EAX=1) are set, and 121 * - the SSE and AVX state bits of XCR0 are set (check_xcr0_ymm). 122 */ 123 avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() && 124 disable_avx == NULL; 125 /* For AVX2 we ensure that: 126 * - AVX is supported, 127 * - the AVX2, BMI1, and BMI2 bits of EBX from CPUID(EAX=7) are set, and 128 * - the FMA, and MOVBE bits of ECX from CPUID(EAX=1) are set. 129 * We do not check for LZCNT support. 130 */ 131 avx2_support_ = (PRBool)(avx_support_ == PR_TRUE && 132 (ebx7 & AVX2_EBX_BITS) == AVX2_EBX_BITS && 133 (ecx & AVX2_ECX_BITS) == AVX2_ECX_BITS && 134 disable_avx2 == NULL); 135 /* CPUID.(EAX=07H, ECX=0H):EBX.ADX[bit 19]=1 indicates 136 the processor supports ADCX and ADOX instructions.*/ 137 adx_support_ = (PRBool)((ebx7 & EBX_ADX) != 0 && disable_adx == NULL); 138 ssse3_support_ = (PRBool)((ecx & ECX_SSSE3) != 0 && 139 disable_ssse3 == NULL); 140 sse4_1_support_ = (PRBool)((ecx & ECX_SSE4_1) != 0 && 141 disable_sse4_1 == NULL); 142 sse4_2_support_ = (PRBool)((ecx & ECX_SSE4_2) != 0 && 143 disable_sse4_2 == NULL); 144 } 145 #endif /* NSS_X86_OR_X64 */ 146 147 /* clang-format off */ 148 #if (defined(__aarch64__) || defined(__arm__)) && !defined(TARGET_OS_IPHONE) 149 #ifndef __has_include 150 #define __has_include(x) 0 151 #endif 152 #if (__has_include(<sys/auxv.h>) || defined(__linux__)) && \ 153 defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__) 154 /* This might be conflict with host compiler */ 155 #if !defined(__ANDROID__) 156 #include <sys/auxv.h> 157 #endif 158 extern unsigned long getauxval(unsigned long type) __attribute__((weak)); 159 #elif defined(__arm__) || (!defined(__OpenBSD__) && !defined(_WIN64)) 160 static unsigned long (*getauxval)(unsigned long) = NULL; 161 #endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/ 162 163 #if defined(__FreeBSD__) && !defined(__aarch64__) && __has_include(<sys/auxv.h>) 164 /* Avoid conflict with static declaration above */ 165 #define getauxval freebl_getauxval 166 static unsigned long getauxval(unsigned long type) 167 { 168 /* Only AT_HWCAP* return unsigned long */ 169 if (type != AT_HWCAP && type != AT_HWCAP2) { 170 return 0; 171 } 172 173 unsigned long ret = 0; 174 elf_aux_info(type, &ret, sizeof(ret)); 175 return ret; 176 } 177 #endif 178 179 #ifndef AT_HWCAP2 180 #define AT_HWCAP2 26 181 #endif 182 #ifndef AT_HWCAP 183 #define AT_HWCAP 16 184 #endif 185 186 #endif /* defined(__aarch64__) || defined(__arm__) */ 187 /* clang-format on */ 188 189 #if defined(__aarch64__) 190 191 #if defined(__linux__) 192 // Defines from hwcap.h in Linux kernel - ARM64 193 #ifndef HWCAP_AES 194 #define HWCAP_AES (1 << 3) 195 #endif 196 #ifndef HWCAP_PMULL 197 #define HWCAP_PMULL (1 << 4) 198 #endif 199 #ifndef HWCAP_SHA1 200 #define HWCAP_SHA1 (1 << 5) 201 #endif 202 #ifndef HWCAP_SHA2 203 #define HWCAP_SHA2 (1 << 6) 204 #endif 205 #endif /* defined(__linux__) */ 206 207 #if defined(__FreeBSD__) 208 #include <stdint.h> 209 #include <machine/armreg.h> 210 // Support for older version of armreg.h 211 #ifndef ID_AA64ISAR0_AES_VAL 212 #define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES 213 #endif 214 #ifndef ID_AA64ISAR0_SHA1_VAL 215 #define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1 216 #endif 217 #ifndef ID_AA64ISAR0_SHA2_VAL 218 #define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2 219 #endif 220 #endif /* defined(__FreeBSD__) */ 221 222 #if defined(__OpenBSD__) 223 #include <sys/sysctl.h> 224 #include <machine/cpu.h> 225 #include <machine/armreg.h> 226 #endif /* defined(__OpenBSD__) */ 227 228 void 229 CheckARMSupport() 230 { 231 #if defined(_WIN64) 232 BOOL arm_crypto_support = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); 233 arm_aes_support_ = arm_crypto_support; 234 arm_pmull_support_ = arm_crypto_support; 235 arm_sha1_support_ = arm_crypto_support; 236 arm_sha2_support_ = arm_crypto_support; 237 #elif defined(__linux__) 238 if (getauxval) { 239 long hwcaps = getauxval(AT_HWCAP); 240 arm_aes_support_ = (hwcaps & HWCAP_AES) == HWCAP_AES; 241 arm_pmull_support_ = (hwcaps & HWCAP_PMULL) == HWCAP_PMULL; 242 arm_sha1_support_ = (hwcaps & HWCAP_SHA1) == HWCAP_SHA1; 243 arm_sha2_support_ = (hwcaps & HWCAP_SHA2) == HWCAP_SHA2; 244 } 245 #elif defined(__FreeBSD__) 246 /* qemu-user does not support register access from userspace */ 247 if (PR_GetEnvSecure("QEMU_EMULATING") == NULL) { 248 uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1); 249 arm_aes_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE; 250 arm_pmull_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_PMULL; 251 arm_sha1_support_ = ID_AA64ISAR0_SHA1_VAL(isar0) >= ID_AA64ISAR0_SHA1_BASE; 252 arm_sha2_support_ = ID_AA64ISAR0_SHA2_VAL(isar0) >= ID_AA64ISAR0_SHA2_BASE; 253 } 254 #elif defined(__OpenBSD__) 255 const int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 }; 256 uint64_t isar0; 257 size_t len = sizeof(isar0); 258 if (sysctl(isar0_mib, 2, &isar0, &len, NULL, 0) < 0) 259 return; 260 arm_aes_support_ = ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_BASE; 261 arm_pmull_support_ = ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_PMULL; 262 arm_sha1_support_ = ID_AA64ISAR0_SHA1(isar0) >= ID_AA64ISAR0_SHA1_BASE; 263 arm_sha2_support_ = ID_AA64ISAR0_SHA2(isar0) >= ID_AA64ISAR0_SHA2_BASE; 264 #elif defined(__ARM_FEATURE_CRYPTO) 265 /* 266 * Although no feature detection, default compiler option allows ARM 267 * Crypto Extension. 268 */ 269 arm_aes_support_ = PR_TRUE; 270 arm_pmull_support_ = PR_TRUE; 271 arm_sha1_support_ = PR_TRUE; 272 arm_sha2_support_ = PR_TRUE; 273 #endif 274 /* aarch64 must support NEON. */ 275 arm_neon_support_ = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON") == NULL; 276 arm_aes_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_AES") == NULL; 277 arm_pmull_support_ &= PR_GetEnvSecure("NSS_DISABLE_PMULL") == NULL; 278 arm_sha1_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA1") == NULL; 279 arm_sha2_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA2") == NULL; 280 } 281 #endif /* defined(__aarch64__) */ 282 283 #if defined(__arm__) 284 // Defines from hwcap.h in Linux kernel - ARM 285 /* 286 * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP 287 */ 288 #ifndef HWCAP_NEON 289 #define HWCAP_NEON (1 << 12) 290 #endif 291 292 /* 293 * HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2 294 */ 295 #ifndef HWCAP2_AES 296 #define HWCAP2_AES (1 << 0) 297 #endif 298 #ifndef HWCAP2_PMULL 299 #define HWCAP2_PMULL (1 << 1) 300 #endif 301 #ifndef HWCAP2_SHA1 302 #define HWCAP2_SHA1 (1 << 2) 303 #endif 304 #ifndef HWCAP2_SHA2 305 #define HWCAP2_SHA2 (1 << 3) 306 #endif 307 308 PRBool 309 GetNeonSupport() 310 { 311 char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); 312 if (disable_arm_neon) { 313 return PR_FALSE; 314 } 315 #if defined(__ARM_NEON) || defined(__ARM_NEON__) 316 // Compiler generates NEON instruction as default option. 317 // If no getauxval, compiler generate NEON instruction by default, 318 // we should allow NOEN support. 319 return PR_TRUE; 320 #elif !defined(__ANDROID__) 321 // Android's cpu-features.c detects features by the following logic 322 // 323 // - Call getauxval(AT_HWCAP) 324 // - Parse /proc/self/auxv if getauxval is nothing or returns 0 325 // - Parse /proc/cpuinfo if both cannot detect features 326 // 327 // But we don't use it for Android since Android document 328 // (https://developer.android.com/ndk/guides/cpu-features) says 329 // one problem with AT_HWCAP sometimes devices (Nexus 4 and emulator) 330 // are mistaken for IDIV. 331 if (getauxval) { 332 return (getauxval(AT_HWCAP) & HWCAP_NEON); 333 } 334 #endif /* defined(__ARM_NEON) || defined(__ARM_NEON__) */ 335 return PR_FALSE; 336 } 337 338 #ifdef __linux__ 339 static long 340 ReadCPUInfoForHWCAP2() 341 { 342 FILE *cpuinfo; 343 char buf[512]; 344 char *p; 345 long hwcap2 = 0; 346 347 cpuinfo = fopen("/proc/cpuinfo", "r"); 348 if (!cpuinfo) { 349 return 0; 350 } 351 while (fgets(buf, 511, cpuinfo)) { 352 if (!memcmp(buf, "Features", 8)) { 353 p = strstr(buf, " aes"); 354 if (p && (p[4] == ' ' || p[4] == '\n')) { 355 hwcap2 |= HWCAP2_AES; 356 } 357 p = strstr(buf, " sha1"); 358 if (p && (p[5] == ' ' || p[5] == '\n')) { 359 hwcap2 |= HWCAP2_SHA1; 360 } 361 p = strstr(buf, " sha2"); 362 if (p && (p[5] == ' ' || p[5] == '\n')) { 363 hwcap2 |= HWCAP2_SHA2; 364 } 365 p = strstr(buf, " pmull"); 366 if (p && (p[6] == ' ' || p[6] == '\n')) { 367 hwcap2 |= HWCAP2_PMULL; 368 } 369 break; 370 } 371 } 372 373 fclose(cpuinfo); 374 return hwcap2; 375 } 376 #endif /* __linux__ */ 377 378 void 379 CheckARMSupport() 380 { 381 char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); 382 if (getauxval) { 383 // Android's cpu-features.c uses AT_HWCAP2 for newer features. 384 // AT_HWCAP2 is implemented on newer devices / kernel, so we can trust 385 // it since cpu-features.c doesn't have workaround / fallback. 386 // Also, AT_HWCAP2 is supported by glibc 2.18+ on Linux/arm, If 387 // AT_HWCAP2 isn't supported by glibc or Linux kernel, getauxval will 388 // returns 0. 389 long hwcaps = getauxval(AT_HWCAP2); 390 #ifdef __linux__ 391 if (!hwcaps) { 392 // Some ARMv8 devices may not implement AT_HWCAP2. So we also 393 // read /proc/cpuinfo if AT_HWCAP2 is 0. 394 hwcaps = ReadCPUInfoForHWCAP2(); 395 } 396 #endif 397 arm_aes_support_ = hwcaps & HWCAP2_AES && disable_hw_aes == NULL; 398 arm_pmull_support_ = hwcaps & HWCAP2_PMULL; 399 arm_sha1_support_ = hwcaps & HWCAP2_SHA1; 400 arm_sha2_support_ = hwcaps & HWCAP2_SHA2; 401 } 402 arm_neon_support_ = GetNeonSupport(); 403 arm_sha1_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA1") == NULL; 404 arm_sha2_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA2") == NULL; 405 } 406 #endif /* defined(__arm__) */ 407 408 // Enable when Firefox can use it for Android API 16 and 17. 409 // #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__)) 410 // #include <cpu-features.h> 411 // void 412 // CheckARMSupport() 413 // { 414 // char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); 415 // char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); 416 // AndroidCpuFamily family = android_getCpuFamily(); 417 // uint64_t features = android_getCpuFeatures(); 418 // if (family == ANDROID_CPU_FAMILY_ARM64) { 419 // arm_aes_support_ = features & ANDROID_CPU_ARM64_FEATURE_AES && 420 // disable_hw_aes == NULL; 421 // arm_pmull_support_ = features & ANDROID_CPU_ARM64_FEATURE_PMULL; 422 // arm_sha1_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA1; 423 // arm_sha2_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA2; 424 // arm_neon_support_ = disable_arm_neon == NULL; 425 // } 426 // if (family == ANDROID_CPU_FAMILY_ARM) { 427 // arm_aes_support_ = features & ANDROID_CPU_ARM_FEATURE_AES && 428 // disable_hw_aes == NULL; 429 // arm_pmull_support_ = features & ANDROID_CPU_ARM_FEATURE_PMULL; 430 // arm_sha1_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA1; 431 // arm_sha2_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA2; 432 // arm_neon_support_ = hwcaps & ANDROID_CPU_ARM_FEATURE_NEON && 433 // disable_arm_neon == NULL; 434 // } 435 // } 436 // #endif /* defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__)) */ 437 438 PRBool 439 aesni_support() 440 { 441 return aesni_support_; 442 } 443 PRBool 444 clmul_support() 445 { 446 return clmul_support_; 447 } 448 PRBool 449 sha_support() 450 { 451 return sha_support_; 452 } 453 PRBool 454 avx_support() 455 { 456 return avx_support_; 457 } 458 PRBool 459 avx2_support() 460 { 461 return avx2_support_; 462 } 463 PRBool 464 adx_support() 465 { 466 return adx_support_; 467 } 468 PRBool 469 ssse3_support() 470 { 471 return ssse3_support_; 472 } 473 PRBool 474 sse4_1_support() 475 { 476 return sse4_1_support_; 477 } 478 PRBool 479 sse4_2_support() 480 { 481 return sse4_2_support_; 482 } 483 PRBool 484 arm_neon_support() 485 { 486 return arm_neon_support_; 487 } 488 PRBool 489 arm_aes_support() 490 { 491 return arm_aes_support_; 492 } 493 PRBool 494 arm_pmull_support() 495 { 496 return arm_pmull_support_; 497 } 498 PRBool 499 arm_sha1_support() 500 { 501 return arm_sha1_support_; 502 } 503 PRBool 504 arm_sha2_support() 505 { 506 return arm_sha2_support_; 507 } 508 PRBool 509 ppc_crypto_support() 510 { 511 return ppc_crypto_support_; 512 } 513 514 #if defined(__powerpc__) 515 516 #ifndef __has_include 517 #define __has_include(x) 0 518 #endif 519 520 /* clang-format off */ 521 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 12) 522 #if __has_include(<sys/auxv.h>) 523 #include <sys/auxv.h> 524 #endif 525 #elif (defined(__FreeBSD__) && __FreeBSD__ < 12) 526 #include <sys/sysctl.h> 527 #endif 528 529 // Defines from cputable.h in Linux kernel - PPC, letting us build on older kernels 530 #ifndef PPC_FEATURE2_VEC_CRYPTO 531 #define PPC_FEATURE2_VEC_CRYPTO 0x02000000 532 #endif 533 534 static void 535 CheckPPCSupport() 536 { 537 char *disable_hw_crypto = PR_GetEnvSecure("NSS_DISABLE_PPC_GHASH"); 538 539 unsigned long hwcaps = 0; 540 #if defined(__linux__) 541 #if __has_include(<sys/auxv.h>) 542 hwcaps = getauxval(AT_HWCAP2); 543 #endif 544 #elif defined(__FreeBSD__) 545 #if __FreeBSD__ >= 12 546 #if __has_include(<sys/auxv.h>) 547 elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps)); 548 #endif 549 #else 550 size_t len = sizeof(hwcaps); 551 sysctlbyname("hw.cpu_features2", &hwcaps, &len, NULL, 0); 552 #endif 553 #endif 554 555 ppc_crypto_support_ = hwcaps & PPC_FEATURE2_VEC_CRYPTO && disable_hw_crypto == NULL; 556 } 557 /* clang-format on */ 558 559 #endif /* __powerpc__ */ 560 561 static PRStatus 562 FreeblInit(void) 563 { 564 #ifdef NSS_X86_OR_X64 565 CheckX86CPUSupport(); 566 #elif (defined(__aarch64__) || defined(__arm__)) 567 CheckARMSupport(); 568 #elif (defined(__powerpc__)) 569 CheckPPCSupport(); 570 #endif 571 return PR_SUCCESS; 572 } 573 574 SECStatus 575 BL_Init(void) 576 { 577 if (PR_CallOnce(&coFreeblInit, FreeblInit) != PR_SUCCESS) { 578 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 579 return SECFailure; 580 } 581 RSA_Init(); 582 583 return SECSuccess; 584 }