From 6146485d2a3a36947eae87a43124b9b033799987 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 9 Feb 2024 00:47:23 -0600 Subject: [PATCH] linuxkm/linuxkm_wc_port.h: * add support for DEBUG_LINUXKM_FORTIFY_OVERLAY to allow KASAN analysis of the overlay without actually enabling CONFIG_FORTIFY_SOURCE (which is buggy in combination with KASAN). * make SAVE_VECTOR_REGISTERS2 definition conditional on !defined(SAVE_VECTOR_REGISTERS2). wolfssl/wolfcrypt/memory.h: fix the DEBUG_VECTOR_REGISTER_ACCESS definition for SAVE_VECTOR_REGISTERS to properly omit the on-success bookkeeping code even if the supplied fail_clause doesn't return. wolfcrypt/src/rsa.c: in wc_MakeRsaKey() primality loop, invoke RESTORE_VECTOR_REGISTERS() SAVE_VECTOR_REGISTERS() to prevent lengthy kernel lockups. wolfcrypt/src/dh.c: in wc_DhGenerateParams() primality loop, invoke RESTORE_VECTOR_REGISTERS() SAVE_VECTOR_REGISTERS() to prevent lengthy kernel lockups. wolfcrypt/src/{curve25519.c,dh.c,dsa.c,ecc.c,eccsi.c,rsa.c,sakke.c,sp_int.c}: when WOLFSSL_LINUXKM, force {SAVE,RESTORE}_VECTOR_REGISTERS() to WC_DO_NOTHING if settings gate out applicable asm. --- linuxkm/linuxkm_wc_port.h | 6 +++++- wolfcrypt/src/curve25519.c | 8 ++++++++ wolfcrypt/src/dh.c | 18 ++++++++++++++++-- wolfcrypt/src/dsa.c | 8 ++++++++ wolfcrypt/src/ecc.c | 8 ++++++++ wolfcrypt/src/eccsi.c | 8 ++++++++ wolfcrypt/src/rsa.c | 23 ++++++++++++++++++----- wolfcrypt/src/sakke.c | 8 ++++++++ wolfcrypt/src/sp_int.c | 8 ++++++++ wolfssl/wolfcrypt/memory.h | 30 ++++++++++++++++-------------- 10 files changed, 103 insertions(+), 22 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 2580e406d..b94957fcf 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -120,7 +120,7 @@ #include #include - #ifdef CONFIG_FORTIFY_SOURCE + #if defined(CONFIG_FORTIFY_SOURCE) || defined(DEBUG_LINUXKM_FORTIFY_OVERLAY) #ifdef __PIE__ /* the inline definitions in fortify-string.h use non-inline * fortify_panic(). @@ -345,6 +345,8 @@ fail_clause \ } \ } + #endif + #ifndef SAVE_VECTOR_REGISTERS2 #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING #define SAVE_VECTOR_REGISTERS2() ({ \ int _fuzzer_ret = SAVE_VECTOR_REGISTERS2_fuzzer(); \ @@ -363,6 +365,8 @@ #include #ifndef SAVE_VECTOR_REGISTERS #define SAVE_VECTOR_REGISTERS(fail_clause) { int _svr_ret = save_vector_registers_arm(); if (_svr_ret != 0) { fail_clause } } + #endif + #ifndef SAVE_VECTOR_REGISTERS2 #define SAVE_VECTOR_REGISTERS2() save_vector_registers_arm() #endif #ifndef RESTORE_VECTOR_REGISTERS diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index e5c3593ba..2c967dd8d 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -51,6 +51,14 @@ #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(USE_INTEL_SPEEDUP) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + const curve25519_set_type curve25519_sets[] = { { CURVE25519_KEYSIZE, diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index e638a51ce..6b6860121 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -55,6 +55,13 @@ #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif /* Possible DH enable options: @@ -3003,7 +3010,7 @@ int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh) /* loop until p is prime */ if (ret == 0) { - do { + for (;;) { if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY) ret = PRIME_GEN_E; @@ -3014,7 +3021,14 @@ int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh) else primeCheckCount++; } - } while (ret == 0 && primeCheck == MP_NO); + + if (ret != 0 || primeCheck == MP_YES) + break; + + /* linuxkm: release the kernel for a moment before iterating. */ + RESTORE_VECTOR_REGISTERS(); + SAVE_VECTOR_REGISTERS(ret = _svr_ret; break;); + }; } /* tmp2 += (2*loop_check_prime) diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 3cdcffe3c..08f70db5d 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -42,6 +42,14 @@ #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + #ifdef _MSC_VER /* disable for while(0) cases (MSVC bug) */ #pragma warning(disable:4127) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index fcbe8e776..39e804c26 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -213,6 +213,14 @@ ECC Curve Sizes: #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #define GEN_MEM_ERR MP_MEM #elif defined(USE_FAST_MATH) diff --git a/wolfcrypt/src/eccsi.c b/wolfcrypt/src/eccsi.c index 836243bed..0b12991ef 100644 --- a/wolfcrypt/src/eccsi.c +++ b/wolfcrypt/src/eccsi.c @@ -43,6 +43,14 @@ #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ #define wc_ecc_key_get_priv(key) (&((key)->k)) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 56a6efa83..351cf25b7 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -62,6 +62,14 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #include #endif +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + /* Possible RSA enable options: * NO_RSA: Overall control of RSA default: on @@ -712,8 +720,7 @@ int wc_CheckRsaKey(RsaKey* key) ret = wc_InitRng(rng); - if (ret == 0) - SAVE_VECTOR_REGISTERS(ret = _svr_ret;); + SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (ret == 0) { if (INIT_MP_INT_SIZE(tmp, mp_bitsused(&key->n)) != MP_OKAY) @@ -4830,7 +4837,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif isPrime = 0; i = 0; - do { + for (;;) { #ifdef SHOW_GEN printf("."); fflush(stdout); @@ -4853,9 +4860,15 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) i++; #else /* Keep the old retry behavior in non-FIPS build. */ - (void)i; #endif - } while (err == MP_OKAY && !isPrime && i < failCount); + + if (err != MP_OKAY || isPrime || i >= failCount) + break; + + /* linuxkm: release the kernel for a moment before iterating. */ + RESTORE_VECTOR_REGISTERS(); + SAVE_VECTOR_REGISTERS(err = _svr_ret; break;); + }; } if (err == MP_OKAY && !isPrime) diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c index 2629365fa..8e5342c80 100644 --- a/wolfcrypt/src/sakke.c +++ b/wolfcrypt/src/sakke.c @@ -44,6 +44,14 @@ #include #include +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ #define wc_ecc_key_get_priv(key) (&((key)->k)) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 1b5cda87a..627b3c980 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -115,6 +115,14 @@ This library provides single precision (SP) integer math functions. #include +#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) + /* force off unneeded vector register save/restore. */ + #undef SAVE_VECTOR_REGISTERS + #define SAVE_VECTOR_REGISTERS(...) WC_DO_NOTHING + #undef RESTORE_VECTOR_REGISTERS + #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING +#endif + /* DECL_SP_INT: Declare one variable of type 'sp_int'. */ #if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \ !defined(WOLFSSL_SP_NO_MALLOC) diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 1b5b82e35..36619577b 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -283,27 +283,29 @@ WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag, #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE abort(); #elif defined(DEBUG_VECTOR_REGISTERS_EXIT_ON_FAIL) #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE exit(1); - #else + #elif !defined(DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE) #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE #endif #define SAVE_VECTOR_REGISTERS(fail_clause) { \ int _svr_ret = wc_debug_vector_registers_retval; \ if (_svr_ret != 0) { fail_clause } \ - ++wc_svr_count; \ - if (wc_svr_count > 5) { \ - fprintf(stderr, \ - ("%s @ L%d : incr : " \ - "wc_svr_count %d (last op %s L%d)\n"), \ - __FILE__, \ - __LINE__, \ - wc_svr_count, \ - wc_svr_last_file, \ - wc_svr_last_line); \ - DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE \ + else { \ + ++wc_svr_count; \ + if (wc_svr_count > 5) { \ + fprintf(stderr, \ + ("%s @ L%d : incr : " \ + "wc_svr_count %d (last op %s L%d)\n"), \ + __FILE__, \ + __LINE__, \ + wc_svr_count, \ + wc_svr_last_file, \ + wc_svr_last_line); \ + DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE \ + } \ + wc_svr_last_file = __FILE__; \ + wc_svr_last_line = __LINE__; \ } \ - wc_svr_last_file = __FILE__; \ - wc_svr_last_line = __LINE__; \ } WOLFSSL_API extern THREAD_LS_T int wc_debug_vector_registers_retval;