|
176 | 176 | #define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512_HMAC |
177 | 177 | #endif |
178 | 178 |
|
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) |
180 | 181 | #error Config conflict: target kernel has CONFIG_CRYPTO_HMAC, but module has NO_HMAC |
181 | 182 | #endif |
182 | 183 |
|
|
196 | 197 | #define LINUXKM_LKCAPI_REGISTER_SHA1_HMAC |
197 | 198 | #endif |
198 | 199 | #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) |
200 | 202 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA1, but module has NO_SHA |
201 | 203 | #endif |
202 | 204 |
|
|
220 | 222 | #define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC |
221 | 223 | #endif |
222 | 224 | #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) |
224 | 227 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module is missing WOLFSSL_SHA224 |
225 | 228 | #endif |
226 | 229 |
|
|
244 | 247 | #define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC |
245 | 248 | #endif |
246 | 249 | #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) |
248 | 252 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module has NO_SHA256 |
249 | 253 | #endif |
250 | 254 |
|
|
268 | 272 | #define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC |
269 | 273 | #endif |
270 | 274 | #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) |
272 | 277 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA384 |
273 | 278 | #endif |
274 | 279 |
|
|
292 | 297 | #define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC |
293 | 298 | #endif |
294 | 299 | #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) |
296 | 302 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA512 |
297 | 303 | #endif |
298 | 304 |
|
|
345 | 351 | #endif |
346 | 352 | #endif |
347 | 353 | #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) |
349 | 356 | #error Config conflict: target kernel has CONFIG_CRYPTO_SHA3, but module is missing WOLFSSL_SHA3 |
350 | 357 | #endif |
351 | 358 |
|
|
379 | 386 | #endif |
380 | 387 | /* setup for LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT is in linuxkm_wc_port.h */ |
381 | 388 | #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 |
382 | 393 | #undef LINUXKM_LKCAPI_REGISTER_HASH_DRBG |
383 | 394 | #endif |
384 | 395 |
|
@@ -757,41 +768,20 @@ WC_MAYBE_UNUSED static void km_hmac_exit_tfm(struct crypto_shash *tfm) |
757 | 768 | } |
758 | 769 |
|
759 | 770 | WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) { |
| 771 | + int ret; |
760 | 772 | struct km_sha_hmac_state *t_ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc); |
761 | 773 | struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(desc->tfm); |
762 | 774 |
|
763 | 775 | t_ctx->wc_hmac = malloc(sizeof *t_ctx->wc_hmac); |
764 | 776 | if (! t_ctx->wc_hmac) |
765 | 777 | return -ENOMEM; |
766 | 778 |
|
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; |
793 | 784 | } |
794 | | -#endif /* WOLFSSL_SMALL_STACK_CACHE */ |
795 | 785 |
|
796 | 786 | return 0; |
797 | 787 | } |
@@ -1073,7 +1063,7 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) { |
1073 | 1063 | return NULL; |
1074 | 1064 | } |
1075 | 1065 |
|
1076 | | - if (tfm == crypto_default_rng) { |
| 1066 | + if ((tfm == crypto_default_rng) && (preempt_count() == 0)) { |
1077 | 1067 | #if defined(CONFIG_SMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) |
1078 | 1068 | migrate_disable(); /* this actually makes irq_count() nonzero, so that |
1079 | 1069 | * DISABLE_VECTOR_REGISTERS() is superfluous, but |
@@ -1108,14 +1098,14 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) { |
1108 | 1098 | * caller can't sleep and the requested DRBG is busy, it returns immediately -- |
1109 | 1099 | * this avoids priority inversions and deadlocks. |
1110 | 1100 | */ |
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) { |
1112 | 1102 | int can_sleep = (preempt_count() == 0); |
1113 | 1103 |
|
1114 | 1104 | for (;;) { |
1115 | 1105 | int expected = 0; |
1116 | 1106 | if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE))) |
1117 | 1107 | return &ctx->rngs[n]; |
1118 | | - if (can_sleep) { |
| 1108 | + if (can_sleep && can_spin) { |
1119 | 1109 | if (signal_pending(current)) |
1120 | 1110 | return NULL; |
1121 | 1111 | cond_resched(); |
@@ -1242,7 +1232,7 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm, |
1242 | 1232 | * up, to assure they can't possibly phase-lock to each other. |
1243 | 1233 | */ |
1244 | 1234 | 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); |
1246 | 1236 |
|
1247 | 1237 | if (! drbg) { |
1248 | 1238 | ret = -EINTR; |
@@ -1313,6 +1303,14 @@ static int wc_linuxkm_drbg_loaded = 0; |
1313 | 1303 |
|
1314 | 1304 | #ifdef LINUXKM_DRBG_GET_RANDOM_BYTES |
1315 | 1305 |
|
| 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 | + |
1316 | 1314 | #if !(defined(HAVE_ENTROPY_MEMUSE) || defined(HAVE_INTEL_RDSEED) || \ |
1317 | 1315 | defined(HAVE_AMD_RDSEED) || defined(WC_LINUXKM_RDSEED_IN_GLUE_LAYER)) |
1318 | 1316 | #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) { |
1491 | 1489 | return -EFAULT; |
1492 | 1490 |
|
1493 | 1491 | 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); |
1495 | 1493 | int V_offset; |
1496 | 1494 |
|
1497 | 1495 | if (! drbg) |
1498 | | - return -EINTR; |
| 1496 | + continue; |
1499 | 1497 |
|
1500 | 1498 | for (i = 0, V_offset = 0; i < len; ++i) { |
1501 | 1499 | ((struct DRBG_internal *)drbg->rng.drbg)->V[V_offset++] += ((byte *)buf)[i]; |
@@ -1523,7 +1521,7 @@ static int wc_crng_reseed(void) { |
1523 | 1521 | return -EFAULT; |
1524 | 1522 |
|
1525 | 1523 | 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); |
1527 | 1525 |
|
1528 | 1526 | if (! drbg) |
1529 | 1527 | return -EINTR; |
|
0 commit comments