Skip to content

Commit 38b675e

Browse files
committed
linuxkm/lkcapi_sha_glue.c:
* as for other glue families, when LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG, don't "#error Config conflict" if explicit LINUXKM_LKCAPI_DONT_REGISTER_foo is defined for the missing algorithm; * in km_hmac_init(), use wc_HmacCopy() to copy p_ctx->wc_hmac to t_ctx->wc_hmac; * in get_drbg(), when tfm == crypto_default_rng, only migrate_disable() and local_bh_disable() if preempt_count() == 0, i.e. if not in already in an uninterruptible context; * add can_spin argument to get_drbg_n() -- wc_linuxkm_drbg_seed() can_spin, wc_mix_pool_bytes() !can_spin, and wc_crng_reseed() can_spin; * add compile-time assert that WOLFSSL_SMALL_STACK_CACHE is defined if LINUXKM_DRBG_GET_RANDOM_BYTES; .wolfssl_known_macro_extras: add CONFIG_CRYPTO_DRBG.
1 parent 50b51ad commit 38b675e

File tree

1 file changed

+39
-41
lines changed

1 file changed

+39
-41
lines changed

linuxkm/lkcapi_sha_glue.c

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@
176176
#define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512_HMAC
177177
#endif
178178

179-
#if defined(NO_HMAC) && defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_HMAC)
179+
#if defined(NO_HMAC) && defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_HMAC) && \
180+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HMAC_ALL)
180181
#error Config conflict: target kernel has CONFIG_CRYPTO_HMAC, but module has NO_HMAC
181182
#endif
182183

@@ -196,7 +197,8 @@
196197
#define LINUXKM_LKCAPI_REGISTER_SHA1_HMAC
197198
#endif
198199
#else
199-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA1)
200+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA1) && \
201+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA1)
200202
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA1, but module has NO_SHA
201203
#endif
202204

@@ -220,7 +222,8 @@
220222
#define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC
221223
#endif
222224
#else
223-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256)
225+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256) && \
226+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_224)
224227
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module is missing WOLFSSL_SHA224
225228
#endif
226229

@@ -244,7 +247,8 @@
244247
#define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC
245248
#endif
246249
#else
247-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256)
250+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256) && \
251+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_256)
248252
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module has NO_SHA256
249253
#endif
250254

@@ -268,7 +272,8 @@
268272
#define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC
269273
#endif
270274
#else
271-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512)
275+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512) && \
276+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_384)
272277
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA384
273278
#endif
274279

@@ -292,7 +297,8 @@
292297
#define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC
293298
#endif
294299
#else
295-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512)
300+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512) && \
301+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_512)
296302
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA512
297303
#endif
298304

@@ -345,7 +351,8 @@
345351
#endif
346352
#endif
347353
#else
348-
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA3)
354+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA3) && \
355+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3)
349356
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA3, but module is missing WOLFSSL_SHA3
350357
#endif
351358

@@ -379,6 +386,10 @@
379386
#endif
380387
/* setup for LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT is in linuxkm_wc_port.h */
381388
#else
389+
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_DRBG) && \
390+
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG)
391+
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA3, but module is missing WOLFSSL_SHA3
392+
#endif
382393
#undef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
383394
#endif
384395

@@ -757,41 +768,20 @@ WC_MAYBE_UNUSED static void km_hmac_exit_tfm(struct crypto_shash *tfm)
757768
}
758769

759770
WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) {
771+
int ret;
760772
struct km_sha_hmac_state *t_ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc);
761773
struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(desc->tfm);
762774

763775
t_ctx->wc_hmac = malloc(sizeof *t_ctx->wc_hmac);
764776
if (! t_ctx->wc_hmac)
765777
return -ENOMEM;
766778

767-
XMEMCPY(t_ctx->wc_hmac, &p_ctx->wc_hmac, sizeof *t_ctx->wc_hmac);
768-
769-
#ifdef WOLFSSL_SMALL_STACK_CACHE
770-
/* The cached W buffer from the persistent ctx can't be used because it
771-
* would be double-freed, first by km_hmac_free_tstate(), then by
772-
* km_hmac_exit_tfm().
773-
*/
774-
switch (t_ctx->wc_hmac->macType) {
775-
776-
#ifndef NO_SHA256
777-
case WC_SHA256:
778-
#ifdef WOLFSSL_SHA224
779-
case WC_SHA224:
780-
#endif
781-
t_ctx->wc_hmac->hash.sha256.W = NULL;
782-
break;
783-
#endif /* WOLFSSL_SHA256 */
784-
785-
#ifdef WOLFSSL_SHA512
786-
case WC_SHA512:
787-
#ifdef WOLFSSL_SHA384
788-
case WC_SHA384:
789-
#endif
790-
t_ctx->wc_hmac->hash.sha512.W = NULL;
791-
break;
792-
#endif /* WOLFSSL_SHA512 */
779+
ret = wc_HmacCopy(&p_ctx->wc_hmac, t_ctx->wc_hmac);
780+
if (ret != 0) {
781+
free(t_ctx->wc_hmac);
782+
t_ctx->wc_hmac = NULL;
783+
return -EINVAL;
793784
}
794-
#endif /* WOLFSSL_SMALL_STACK_CACHE */
795785

796786
return 0;
797787
}
@@ -1073,7 +1063,7 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
10731063
return NULL;
10741064
}
10751065

1076-
if (tfm == crypto_default_rng) {
1066+
if ((tfm == crypto_default_rng) && (preempt_count() == 0)) {
10771067
#if defined(CONFIG_SMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
10781068
migrate_disable(); /* this actually makes irq_count() nonzero, so that
10791069
* DISABLE_VECTOR_REGISTERS() is superfluous, but
@@ -1108,14 +1098,14 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
11081098
* caller can't sleep and the requested DRBG is busy, it returns immediately --
11091099
* this avoids priority inversions and deadlocks.
11101100
*/
1111-
static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, int n) {
1101+
static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, int n, int can_spin) {
11121102
int can_sleep = (preempt_count() == 0);
11131103

11141104
for (;;) {
11151105
int expected = 0;
11161106
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)))
11171107
return &ctx->rngs[n];
1118-
if (can_sleep) {
1108+
if (can_sleep && can_spin) {
11191109
if (signal_pending(current))
11201110
return NULL;
11211111
cond_resched();
@@ -1242,7 +1232,7 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
12421232
* up, to assure they can't possibly phase-lock to each other.
12431233
*/
12441234
for (n = ctx->n_rngs - 1; n >= 0; --n) {
1245-
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
1235+
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 1);
12461236

12471237
if (! drbg) {
12481238
ret = -EINTR;
@@ -1313,6 +1303,14 @@ static int wc_linuxkm_drbg_loaded = 0;
13131303

13141304
#ifdef LINUXKM_DRBG_GET_RANDOM_BYTES
13151305

1306+
#ifndef WOLFSSL_SMALL_STACK_CACHE
1307+
/* WOLFSSL_SMALL_STACK_CACHE eliminates post-init heap allocations in SHA-2
1308+
* and the Hash DRBG, fixing circular call dependencies between
1309+
* get_random_u32() from kernel heap and wolfCrypt DRBG.
1310+
*/
1311+
#error LINUXKM_DRBG_GET_RANDOM_BYTES requires WOLFSSL_SMALL_STACK_CACHE.
1312+
#endif
1313+
13161314
#if !(defined(HAVE_ENTROPY_MEMUSE) || defined(HAVE_INTEL_RDSEED) || \
13171315
defined(HAVE_AMD_RDSEED) || defined(WC_LINUXKM_RDSEED_IN_GLUE_LAYER))
13181316
#error LINUXKM_DRBG_GET_RANDOM_BYTES requires a native or intrinsic entropy source.
@@ -1491,11 +1489,11 @@ static int wc_mix_pool_bytes(const void *buf, size_t len) {
14911489
return -EFAULT;
14921490

14931491
for (n = ctx->n_rngs - 1; n >= 0; --n) {
1494-
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
1492+
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 0);
14951493
int V_offset;
14961494

14971495
if (! drbg)
1498-
return -EINTR;
1496+
continue;
14991497

15001498
for (i = 0, V_offset = 0; i < len; ++i) {
15011499
((struct DRBG_internal *)drbg->rng.drbg)->V[V_offset++] += ((byte *)buf)[i];
@@ -1523,7 +1521,7 @@ static int wc_crng_reseed(void) {
15231521
return -EFAULT;
15241522

15251523
for (n = ctx->n_rngs - 1; n >= 0; --n) {
1526-
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
1524+
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 1);
15271525

15281526
if (! drbg)
15291527
return -EINTR;

0 commit comments

Comments
 (0)