Skip to content

Commit f33814b

Browse files
authored
Merge pull request #9151 from douzzer/20250830-linuxkm-fix-get_drbg
20250830-linuxkm-fix-get_drbg
2 parents 7ef9428 + aa96c35 commit f33814b

11 files changed

Lines changed: 74 additions & 38 deletions

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ WC_RSA_NO_FERMAT_CHECK
605605
WC_SHA384
606606
WC_SHA384_DIGEST_SIZE
607607
WC_SHA512
608+
WC_SKIP_INCLUDED_C_FILES
608609
WC_SSIZE_TYPE
609610
WC_STRICT_SIG
610611
WC_WANT_FLAG_DONT_USE_AESNI

linuxkm/linuxkm_wc_port.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,17 @@
422422
#define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
423423
#endif
424424

425+
/* setup for LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT needs to be here
426+
* to assure that calls to get_random_bytes() in random.c are gated out
427+
* (they would recurse, potentially infinitely).
428+
*/
429+
#if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && \
430+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG) && \
431+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG_DEFAULT)) && \
432+
!defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT)
433+
#define LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
434+
#endif
435+
425436
#ifndef __PIE__
426437
#include <linux/crypto.h>
427438
#include <linux/scatterlist.h>

linuxkm/lkcapi_aes_glue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020
*/
2121

22+
/* included by linuxkm/lkcapi_glue.c */
23+
#ifndef WC_SKIP_INCLUDED_C_FILES
24+
2225
#ifndef LINUXKM_LKCAPI_REGISTER
2326
#error lkcapi_aes_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2427
#endif
@@ -4312,3 +4315,5 @@ static int linuxkm_test_aesecb(void) {
43124315
#endif /* LINUXKM_LKCAPI_REGISTER_AESECB */
43134316

43144317
#endif /* LINUXKM_LKCAPI_REGISTER_AES */
4318+
4319+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_dh_glue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2121
*/
2222

23+
/* included by linuxkm/lkcapi_glue.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
25+
2326
#ifndef LINUXKM_LKCAPI_REGISTER
2427
#error lkcapi_dh_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2528
#endif
@@ -2966,3 +2969,5 @@ static int linuxkm_test_kpp_driver(const char * driver,
29662969
}
29672970

29682971
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
2972+
2973+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_ecdh_glue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2121
*/
2222

23+
/* included by linuxkm/lkcapi_glue.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
25+
2326
#ifndef LINUXKM_LKCAPI_REGISTER
2427
#error lkcapi_ecdh_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2528
#endif
@@ -991,3 +994,5 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver,
991994
}
992995

993996
#endif /* LINUXKM_LKCAPI_REGISTER_ECDH */
997+
998+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_ecdsa_glue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2121
*/
2222

23+
/* included by linuxkm/lkcapi_glue.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
25+
2326
#ifndef LINUXKM_LKCAPI_REGISTER
2427
#error lkcapi_ecdsa_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2528
#endif
@@ -843,3 +846,5 @@ static int linuxkm_test_ecdsa_nist_driver(const char * driver,
843846
}
844847

845848
#endif /* LINUXKM_LKCAPI_REGISTER_ECDSA */
849+
850+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_glue.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222

2323
/* included by linuxkm/module_hooks.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
2425

2526
#ifndef LINUXKM_LKCAPI_REGISTER
2627
#error lkcapi_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
@@ -981,3 +982,5 @@ static int linuxkm_lkcapi_unregister(void)
981982

982983
return seen_err;
983984
}
985+
986+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_rsa_glue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2121
*/
2222

23+
/* included by linuxkm/lkcapi_glue.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
25+
2326
#ifndef LINUXKM_LKCAPI_REGISTER
2427
#error lkcapi_rsa_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2528
#endif
@@ -3250,3 +3253,5 @@ static int get_hash_enc_len(int hash_oid)
32503253
return enc_len;
32513254
}
32523255
#endif /* LINUXKM_LKCAPI_REGISTER_RSA */
3256+
3257+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/lkcapi_sha_glue.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020
*/
2121

22+
/* included by linuxkm/lkcapi_glue.c */
23+
#ifndef WC_SKIP_INCLUDED_C_FILES
24+
2225
#ifndef LINUXKM_LKCAPI_REGISTER
2326
#error lkcapi_sha_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
2427
#endif
@@ -374,10 +377,7 @@
374377
!defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG)
375378
#define LINUXKM_LKCAPI_REGISTER_HASH_DRBG
376379
#endif
377-
#if (defined(LINUXKM_LKCAPI_REGISTER_ALL) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG_DEFAULT)) && \
378-
!defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT)
379-
#define LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
380-
#endif
380+
/* setup for LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT is in linuxkm_wc_port.h */
381381
#else
382382
#undef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
383383
#endif
@@ -968,7 +968,6 @@ struct wc_linuxkm_drbg_ctx {
968968
struct wc_rng_inst {
969969
wolfSSL_Atomic_Int lock;
970970
WC_RNG rng;
971-
int disabled_vec_ops;
972971
} *rngs; /* one per CPU ID */
973972
};
974973

@@ -1090,14 +1089,8 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
10901089

10911090
for (;;) {
10921091
int expected = 0;
1093-
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, new_lock_value, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE))) {
1094-
struct wc_rng_inst *drbg = &ctx->rngs[n];
1095-
if (tfm == crypto_default_rng)
1096-
drbg->disabled_vec_ops = (DISABLE_VECTOR_REGISTERS() == 0);
1097-
else
1098-
drbg->disabled_vec_ops = 0;
1099-
return drbg;
1100-
}
1092+
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, new_lock_value, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)))
1093+
return &ctx->rngs[n];
11011094
++n;
11021095
if (n >= (int)ctx->n_rngs)
11031096
n = 0;
@@ -1115,11 +1108,8 @@ static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, in
11151108

11161109
for (;;) {
11171110
int expected = 0;
1118-
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE))) {
1119-
struct wc_rng_inst *drbg = &ctx->rngs[n];
1120-
drbg->disabled_vec_ops = 0;
1121-
return drbg;
1122-
}
1111+
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)))
1112+
return &ctx->rngs[n];
11231113
if (can_sleep) {
11241114
if (signal_pending(current))
11251115
return NULL;
@@ -1137,10 +1127,6 @@ static inline void put_drbg(struct wc_rng_inst *drbg) {
11371127
(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11381128
int migration_disabled = (drbg->lock == 2);
11391129
#endif
1140-
if (drbg->disabled_vec_ops) {
1141-
REENABLE_VECTOR_REGISTERS();
1142-
drbg->disabled_vec_ops = 0;
1143-
}
11441130
__atomic_store_n(&(drbg->lock),0,__ATOMIC_RELEASE);
11451131
#if defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_COUNT) && \
11461132
(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
@@ -1154,13 +1140,19 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
11541140
u8 *dst, unsigned int dlen)
11551141
{
11561142
int ret, retried = 0;
1143+
int need_fpu_restore;
11571144
struct wc_rng_inst *drbg = get_drbg(tfm);
11581145

11591146
if (! drbg) {
11601147
pr_err_once("BUG: get_drbg() failed.");
11611148
return -EFAULT;
11621149
}
11631150

1151+
/* for the default RNG, make sure we don't cache an underlying SHA256
1152+
* method that uses vector insns (forbidden from irq handlers).
1153+
*/
1154+
need_fpu_restore = (tfm == crypto_default_rng) ? (DISABLE_VECTOR_REGISTERS() == 0) : 0;
1155+
11641156
retry:
11651157

11661158
if (slen > 0) {
@@ -1194,6 +1186,8 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
11941186

11951187
out:
11961188

1189+
if (need_fpu_restore)
1190+
REENABLE_VECTOR_REGISTERS();
11971191
put_drbg(drbg);
11981192

11991193
return ret;
@@ -2054,3 +2048,5 @@ static int wc_linuxkm_drbg_cleanup(void) {
20542048
}
20552049

20562050
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG */
2051+
2052+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

linuxkm/x86_vector_register_glue.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222

2323
/* included by linuxkm/module_hooks.c */
24+
#ifndef WC_SKIP_INCLUDED_C_FILES
2425

2526
#if !defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) || !defined(CONFIG_X86)
2627
#error x86_vector_register_glue.c included in non-vectorized/non-x86 project.
@@ -346,24 +347,20 @@ WARN_UNUSED_RESULT int wc_save_vector_registers_x86(enum wc_svr_flags flags)
346347

347348
/* allow for nested calls */
348349
if (pstate && (pstate->fpu_state != 0U)) {
350+
if (pstate->fpu_state & WC_FPU_INHIBITED_FLAG) {
351+
/* don't allow recursive inhibit calls when already inhibited --
352+
* it would add no functionality and require keeping a separate
353+
* count of inhibit recursions.
354+
*/
355+
return WC_ACCEL_INHIBIT_E;
356+
}
349357
if (unlikely((pstate->fpu_state & WC_FPU_COUNT_MASK)
350358
== WC_FPU_COUNT_MASK))
351359
{
352360
pr_err("ERROR: wc_save_vector_registers_x86 recursion register overflow for "
353361
"pid %d on CPU %d.\n", pstate->pid, raw_smp_processor_id());
354362
return BAD_STATE_E;
355363
}
356-
if (pstate->fpu_state & WC_FPU_INHIBITED_FLAG) {
357-
if (flags & WC_SVR_FLAG_INHIBIT) {
358-
/* allow recursive inhibit calls as long as the whole stack of
359-
* them is inhibiting.
360-
*/
361-
++pstate->fpu_state;
362-
return 0;
363-
}
364-
else
365-
return WC_ACCEL_INHIBIT_E;
366-
}
367364
if (flags & WC_SVR_FLAG_INHIBIT) {
368365
++pstate->fpu_state;
369366
pstate->fpu_state |= WC_FPU_INHIBITED_FLAG;
@@ -535,3 +532,5 @@ void wc_restore_vector_registers_x86(enum wc_svr_flags flags)
535532

536533
return;
537534
}
535+
536+
#endif /* !WC_SKIP_INCLUDED_C_FILES */

0 commit comments

Comments
 (0)