From c010c156424d5c06f9b6d16a839e04bbea5b31c1 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 21 Jun 2023 11:19:57 -0400 Subject: [PATCH] added runtime check for bmi2 and adx --- src/secp256k1.c | 5 +++++ src/selftest.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/secp256k1.c b/src/secp256k1.c index 4c11e7f0b8..7faf445760 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -83,6 +83,11 @@ static int secp256k1_context_is_proper(const secp256k1_context* ctx) { } void secp256k1_selftest(void) { + if (!SECP256K1_CHECKMEM_RUNNING()) { + if (!secp256k1_selftest_cpuid()) { + secp256k1_callback_call(&default_error_callback, "required CPU flags are not present."); + } + } if (!secp256k1_selftest_passes()) { secp256k1_callback_call(&default_error_callback, "self test failed"); } diff --git a/src/selftest.h b/src/selftest.h index d083ac9524..37a1712a21 100644 --- a/src/selftest.h +++ b/src/selftest.h @@ -25,6 +25,34 @@ static int secp256k1_selftest_sha256(void) { return secp256k1_memcmp_var(out, output32, 32) == 0; } +static int secp256k1_selftest_cpuid(void) { + int ret = 1; + +#if defined(USE_ASM_X86_64) + /* getting the CPU flags from the cpu, more information in the Intel manual, + * Table 3-8 Information Returned by CPUID instruction (3-194, Vol.2A) + */ + const int CPU_FLAG_ENUMERATION = 7; + const int LEAF_NODE_ZERO = 0; + + /* for the cpu self test, we need BMI2 and ADX support */ + const int BIT_ADX = 19; + const int BIT_BMI2 = 8; + int flags = 0; + int has_adx = 0; + int has_bmi2 = 0; + __asm__ __volatile__("cpuid\n" + : "=b"(flags) + : "a"(CPU_FLAG_ENUMERATION), "c"(LEAF_NODE_ZERO) + : "rdx", "cc"); + + has_adx = (flags >> BIT_ADX) & 1; + has_bmi2 = (flags >> BIT_BMI2) & 1; + ret = has_adx && has_bmi2; +#endif + return ret; +} + static int secp256k1_selftest_passes(void) { return secp256k1_selftest_sha256(); }