Skip to content

Commit b25d484

Browse files
committed
linuxkm/lkcapi_sha_glue.c: implement mutex-free sync mechanism for wc_linuxkm_drbg_ctx in new get_drbg(), get_drbg_n(), and put_drbg();
linuxkm/x86_vector_register_glue.c: implement support for WC_FPU_INHIBITED_FLAG, and an `int inhibit_p` argument to save_vector_registers_x86(); wolfcrypt/src/random.c: implement linuxkm support for RDSEED and HAVE_ENTROPY_MEMUSE; wolfssl/wolfcrypt/error-crypt.h and wolfcrypt/src/error.c: add WC_ACCEL_INHIBIT_E "Crypto acceleration is currently inhibited"; linuxkm/module_hooks.c and linuxkm/x86_vector_register_glue.c: remove broken and bit-rotten WOLFSSL_COMMERCIAL_LICENSE and LINUXKM_FPU_STATES_FOLLOW_THREADS code paths.
1 parent 8cc2ba7 commit b25d484

8 files changed

Lines changed: 224 additions & 269 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,6 @@ LIBWOLFSSL_VERSION_GIT_ORIGIN
294294
LIBWOLFSSL_VERSION_GIT_SHORT_HASH
295295
LIBWOLFSSL_VERSION_GIT_TAG
296296
LINUXKM_DONT_FORCE_FIPS_ENABLED
297-
LINUXKM_FPU_STATES_FOLLOW_THREADS
298297
LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
299298
LINUX_CYCLE_COUNT
300299
LINUX_RUSAGE_UTIME
@@ -652,7 +651,6 @@ WOLFSSL_CHECK_MEM_ZERO
652651
WOLFSSL_CHIBIOS
653652
WOLFSSL_CLANG_TIDY
654653
WOLFSSL_CLIENT_EXAMPLE
655-
WOLFSSL_COMMERCIAL_LICENSE
656654
WOLFSSL_CONTIKI
657655
WOLFSSL_CRL_ALLOW_MISSING_CDP
658656
WOLFSSL_CUSTOM_CONFIG

linuxkm/linuxkm_wc_port.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@
367367
extern __must_check int allocate_wolfcrypt_linuxkm_fpu_states(void);
368368
extern void free_wolfcrypt_linuxkm_fpu_states(void);
369369
extern __must_check int can_save_vector_registers_x86(void);
370-
extern __must_check int save_vector_registers_x86(void);
370+
extern __must_check int save_vector_registers_x86(int inhibit_p);
371371
extern void restore_vector_registers_x86(void);
372372

373373
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
@@ -383,29 +383,36 @@
383383
#endif
384384
#endif
385385
#ifndef SAVE_VECTOR_REGISTERS
386-
#define SAVE_VECTOR_REGISTERS(fail_clause) { \
387-
int _svr_ret = save_vector_registers_x86(); \
388-
if (_svr_ret != 0) { \
389-
fail_clause \
390-
} \
386+
#define SAVE_VECTOR_REGISTERS(fail_clause) { \
387+
int _svr_ret = save_vector_registers_x86(0); \
388+
if (_svr_ret != 0) { \
389+
fail_clause \
390+
} \
391391
}
392392
#endif
393393
#ifndef SAVE_VECTOR_REGISTERS2
394394
#ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
395395
#define SAVE_VECTOR_REGISTERS2() ({ \
396396
int _fuzzer_ret = SAVE_VECTOR_REGISTERS2_fuzzer(); \
397397
(_fuzzer_ret == 0) ? \
398-
save_vector_registers_x86() : \
398+
save_vector_registers_x86(0) : \
399399
_fuzzer_ret; \
400400
})
401401
#else
402-
#define SAVE_VECTOR_REGISTERS2() save_vector_registers_x86()
402+
#define SAVE_VECTOR_REGISTERS2() save_vector_registers_x86(0)
403403
#endif
404404
#endif
405405
#ifndef RESTORE_VECTOR_REGISTERS
406406
#define RESTORE_VECTOR_REGISTERS() restore_vector_registers_x86()
407407
#endif
408408

409+
#ifndef DISABLE_VECTOR_REGISTERS
410+
#define DISABLE_VECTOR_REGISTERS() save_vector_registers_x86(1)
411+
#endif
412+
#ifndef REENABLE_VECTOR_REGISTERS
413+
#define REENABLE_VECTOR_REGISTERS() restore_vector_registers_x86()
414+
#endif
415+
409416
#elif defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
410417

411418
#error kernel module ARM SIMD is not yet tested or usable.

linuxkm/lkcapi_sha_glue.c

Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ struct wc_swallow_the_semicolon
941941

942942
struct wc_linuxkm_drbg_ctx {
943943
struct wc_rng_inst {
944-
wolfSSL_Mutex lock;
944+
wolfSSL_Atomic_Int lock;
945945
WC_RNG rng;
946946
} *rngs; /* one per CPU ID */
947947
};
@@ -952,7 +952,6 @@ static inline void wc_linuxkm_drbg_ctx_clear(struct wc_linuxkm_drbg_ctx * ctx)
952952

953953
if (ctx->rngs) {
954954
for (i = 0; i < nr_cpu_ids; ++i) {
955-
(void)wc_FreeMutex(&ctx->rngs[i].lock);
956955
wc_FreeRng(&ctx->rngs[i].rng);
957956
}
958957
free(ctx->rngs);
@@ -974,11 +973,7 @@ static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
974973
XMEMSET(ctx->rngs, 0, sizeof(*ctx->rngs) * nr_cpu_ids);
975974

976975
for (i = 0; i < nr_cpu_ids; ++i) {
977-
ret = wc_InitMutex(&ctx->rngs[i].lock);
978-
if (ret != 0) {
979-
ret = -EINVAL;
980-
break;
981-
}
976+
ctx->rngs[i].lock = 0;
982977

983978
/* Note the new DRBG instance is seeded, and later reseeded, from system
984979
* get_random_bytes() via wc_GenerateSeed().
@@ -1006,39 +1001,96 @@ static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
10061001
return;
10071002
}
10081003

1004+
static int wc_linuxkm_drbg_default_instance_registered = 0;
1005+
1006+
static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
1007+
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
1008+
int n;
1009+
1010+
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
1011+
int disabled_vector_registers = 0;
1012+
1013+
if (tfm == crypto_default_rng) {
1014+
/* The persistent default stdrng needs to use interrupt-safe mechanisms,
1015+
* because we use it as the back end for get_random_bytes(). With
1016+
* SMALL_STACK_CACHE, this only affects the ephemeral SHA256 instances used
1017+
* by the seed generator, but without SMALL_STACK_CACHE it affects every
1018+
* DRBG call.
1019+
*/
1020+
int ret = DISABLE_VECTOR_REGISTERS();
1021+
if (ret != 0) {
1022+
pr_err("get_drbg DISABLE_VECTOR_REGISTERS returned %d", ret);
1023+
} else {
1024+
disabled_vector_registers = 1;
1025+
}
1026+
}
1027+
#endif
1028+
1029+
n = raw_smp_processor_id();
1030+
1031+
for (;;) {
1032+
if (likely(__atomic_test_and_set(&ctx->rngs[n].lock,__ATOMIC_ACQUIRE))) {
1033+
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
1034+
if (disabled_vector_registers)
1035+
ctx->rngs[n].lock = 2;
1036+
else
1037+
ctx->rngs[n].lock = 1; /* be sure. */
1038+
#endif
1039+
return &ctx->rngs[n];
1040+
}
1041+
++n;
1042+
if (n >= (int)nr_cpu_ids)
1043+
n = 0;
1044+
}
1045+
1046+
__builtin_unreachable();
1047+
}
1048+
1049+
static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, int n) {
1050+
for (;;) {
1051+
if (likely(__atomic_test_and_set(&ctx->rngs[n].lock,__ATOMIC_ACQUIRE)))
1052+
return &ctx->rngs[n];
1053+
cond_resched();
1054+
}
1055+
1056+
__builtin_unreachable();
1057+
}
1058+
1059+
static inline void put_drbg(struct wc_rng_inst *drbg) {
1060+
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
1061+
if (drbg->lock == 2)
1062+
REENABLE_VECTOR_REGISTERS();
1063+
#endif
1064+
__atomic_store_n(&(drbg->lock),0,__ATOMIC_RELEASE);
1065+
}
1066+
10091067
static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
10101068
const u8 *src, unsigned int slen,
10111069
u8 *dst, unsigned int dlen)
10121070
{
1013-
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
10141071
int ret;
10151072
/* Note, core is not locked, so the actual core ID may change while
1016-
* executing, hence the mutex.
1017-
* The mutex is also needed to coordinate with wc_linuxkm_drbg_seed(), which
1073+
* executing, hence the lock.
1074+
* The lock is also needed to coordinate with wc_linuxkm_drbg_seed(), which
10181075
* seeds all instances.
10191076
*/
1020-
int my_cpu = raw_smp_processor_id();
1021-
wolfSSL_Mutex *lock = &ctx->rngs[my_cpu].lock;
1022-
WC_RNG *rng = &ctx->rngs[my_cpu].rng;
1023-
1024-
if (wc_LockMutex(lock) != 0)
1025-
return -EINVAL;
1077+
struct wc_rng_inst *drbg = get_drbg(tfm);
10261078

10271079
if (slen > 0) {
1028-
ret = wc_RNG_DRBG_Reseed(rng, src, slen);
1080+
ret = wc_RNG_DRBG_Reseed(&drbg->rng, src, slen);
10291081
if (ret != 0) {
10301082
ret = -EINVAL;
10311083
goto out;
10321084
}
10331085
}
10341086

1035-
ret = wc_RNG_GenerateBlock(rng, dst, dlen);
1087+
ret = wc_RNG_GenerateBlock(&drbg->rng, dst, dlen);
10361088
if (ret != 0)
10371089
ret = -EINVAL;
10381090

10391091
out:
10401092

1041-
wc_UnLockMutex(lock);
1093+
put_drbg(drbg);
10421094

10431095
return ret;
10441096
}
@@ -1049,7 +1101,7 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
10491101
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
10501102
u8 *seed_copy = NULL;
10511103
int ret;
1052-
unsigned int i;
1104+
int n;
10531105

10541106
if (slen == 0)
10551107
return 0;
@@ -1059,25 +1111,21 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
10591111
return -ENOMEM;
10601112
XMEMCPY(seed_copy + 2, seed, slen);
10611113

1062-
for (i = 0; i < nr_cpu_ids; ++i) {
1063-
wolfSSL_Mutex *lock = &ctx->rngs[i].lock;
1064-
WC_RNG *rng = &ctx->rngs[i].rng;
1114+
for (n = nr_cpu_ids - 1; n >= 0; --n) {
1115+
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
10651116

10661117
/* perturb the seed with the CPU ID, so that no DRBG has the exact same
10671118
* seed.
10681119
*/
1069-
seed_copy[0] = (u8)(i >> 8);
1070-
seed_copy[1] = (u8)i;
1071-
1072-
if (wc_LockMutex(lock) != 0)
1073-
return -EINVAL;
1120+
seed_copy[0] = (u8)(n >> 8);
1121+
seed_copy[1] = (u8)n;
10741122

1075-
ret = wc_RNG_DRBG_Reseed(rng, seed_copy, slen + 2);
1123+
ret = wc_RNG_DRBG_Reseed(&drbg->rng, seed_copy, slen + 2);
10761124
if (ret != 0) {
10771125
ret = -EINVAL;
10781126
}
10791127

1080-
wc_UnLockMutex(lock);
1128+
put_drbg(drbg);
10811129

10821130
if (ret != 0)
10831131
break;
@@ -1103,7 +1151,6 @@ static struct rng_alg wc_linuxkm_drbg = {
11031151
}
11041152
};
11051153
static int wc_linuxkm_drbg_loaded = 0;
1106-
static int wc_linuxkm_drbg_default_instance_registered = 0;
11071154

11081155
WC_MAYBE_UNUSED static int wc_linuxkm_drbg_startup(void)
11091156
{
@@ -1222,7 +1269,18 @@ WC_MAYBE_UNUSED static int wc_linuxkm_drbg_startup(void)
12221269
return ret;
12231270
}
12241271

1272+
#ifdef DISABLE_VECTOR_REGISTERS
1273+
ret = DISABLE_VECTOR_REGISTERS();
1274+
if (ret != 0) {
1275+
pr_err("DISABLE_VECTOR_REGISTERS() returned %d", ret);
1276+
return -EINVAL;
1277+
}
1278+
#endif
12251279
ret = crypto_get_default_rng();
1280+
#ifdef DISABLE_VECTOR_REGISTERS
1281+
REENABLE_VECTOR_REGISTERS();
1282+
#endif
1283+
12261284
if (ret) {
12271285
pr_err("crypto_get_default_rng returned %d", ret);
12281286
return ret;

linuxkm/module_hooks.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@
2020
*/
2121

2222
#ifndef WOLFSSL_LICENSE
23-
#ifdef WOLFSSL_COMMERCIAL_LICENSE
24-
#define WOLFSSL_LICENSE "wolfSSL Commercial"
25-
#else
2623
#define WOLFSSL_LICENSE "GPL v2"
2724
#endif
28-
#endif
2925

3026
#define WOLFSSL_LINUXKM_NEED_LINUX_CURRENT
3127

@@ -454,22 +450,6 @@ static struct task_struct *my_get_current_thread(void) {
454450
return get_current();
455451
}
456452

457-
#if defined(WOLFSSL_LINUXKM_SIMD_X86) && defined(WOLFSSL_COMMERCIAL_LICENSE)
458-
459-
/* ditto for fpregs_lock/fpregs_unlock */
460-
#ifdef WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS
461-
static void my_fpregs_lock(void) {
462-
fpregs_lock();
463-
}
464-
465-
static void my_fpregs_unlock(void) {
466-
fpregs_unlock();
467-
}
468-
469-
#endif /* WOLFSSL_LINUXKM_SIMD_X86 && WOLFSSL_COMMERCIAL_LICENSE */
470-
471-
#endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
472-
473453
static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
474454
memset(
475455
&wolfssl_linuxkm_pie_redirect_table,

0 commit comments

Comments
 (0)