From: Christian Weisgerber Subject: libcrypto: switch aarch64 CPU feature detection to elf_aux_info() To: tech@openbsd.org Cc: Brent Cook Date: Tue, 4 Aug 2026 19:30:11 +0200 The aarch64 runtime environment provides pre-parsed CPU feature capabilities for free. We can just grab them with elf_aux_info() and no longer need to read the AA64ISAR0 register with sysctl or extract the bit fields. OK? Hint for -portable: This builds as-is on FreeBSD, too. ----------------------------------------------- commit fa0e19296490832c8f496272bd150d14d170fb50 from: Christian Weisgerber date: Tue Aug 4 17:10:07 2026 UTC switch aarch64 CPU feature detection to elf_aux_info() diff b2b8205756684c6db49759a3153d75acd569191f fa0e19296490832c8f496272bd150d14d170fb50 commit - b2b8205756684c6db49759a3153d75acd569191f commit + fa0e19296490832c8f496272bd150d14d170fb50 blob - b31a50ef7530b47b579bcaae6b551fd22bf5a861 blob + b9e12776a66281cc4e674de3e80f4a0c9991c89d --- lib/libcrypto/arch/aarch64/crypto_cpu_caps.c +++ lib/libcrypto/arch/aarch64/crypto_cpu_caps.c @@ -15,11 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include -#include - #include #include @@ -28,70 +25,29 @@ /* Machine dependent CPU capabilities. */ uint64_t crypto_cpu_caps_aarch64; -static inline uint64_t -extract_bits(uint64_t val, int start, int end) -{ - return (val >> end) & (1ULL << (1 + start - end)) - 1; -} - -static uint64_t -parse_isar0(uint64_t isar0) -{ - uint64_t caps = 0; - uint64_t feature; - - /* AES - bits [7:4] */ - feature = extract_bits(isar0, 7, 4); - if (feature >= 1) - caps |= CRYPTO_CPU_CAPS_AARCH64_AES; - if (feature >= 2) - caps |= CRYPTO_CPU_CAPS_AARCH64_PMULL; - - /* SHA1 - bits [11:8] */ - feature = extract_bits(isar0, 11, 8); - if (feature >= 1) - caps |= CRYPTO_CPU_CAPS_AARCH64_SHA1; - - /* SHA2 - bits [15:12] */ - feature = extract_bits(isar0, 15, 12); - if (feature >= 1) - caps |= CRYPTO_CPU_CAPS_AARCH64_SHA2; - if (feature >= 2) - caps |= CRYPTO_CPU_CAPS_AARCH64_SHA512; - - /* SHA3 - bits [35:32] */ - feature = extract_bits(isar0, 35, 32); - if (feature >= 1) - caps |= CRYPTO_CPU_CAPS_AARCH64_SHA3; - - return caps; -} - -static int -read_isar0(uint64_t *isar0) -{ - uint64_t isar; - int mib[2]; - size_t len; - - mib[0] = CTL_MACHDEP; - mib[1] = CPU_ID_AA64ISAR0; - len = sizeof(isar); - if (sysctl(mib, 2, &isar, &len, NULL, 0) == -1) - return 0; - - *isar0 = isar; - - return 1; -} - void crypto_cpu_caps_init(void) { - uint64_t isar = 0; + unsigned long hwcap; - if (!read_isar0(&isar)) + if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) != 0) return; - crypto_cpu_caps_aarch64 = parse_isar0(isar); + if (hwcap & HWCAP_AES) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_AES; + + if (hwcap & HWCAP_PMULL) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_PMULL; + + if (hwcap & HWCAP_SHA1) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA1; + + if (hwcap & HWCAP_SHA2) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA2; + + if (hwcap & HWCAP_SHA512) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA512; + + if (hwcap & HWCAP_SHA3) + crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA3; } -- Christian "naddy" Weisgerber naddy@mips.inka.de