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.
This commit is contained in:
Daniel Pouzzner
2025-12-16 16:59:28 -06:00
parent 50b51adc93
commit 38b675ef68

View File

@@ -176,7 +176,8 @@
#define LINUXKM_LKCAPI_DONT_REGISTER_SHA3_512_HMAC
#endif
#if defined(NO_HMAC) && defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_HMAC)
#if defined(NO_HMAC) && defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_HMAC) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HMAC_ALL)
#error Config conflict: target kernel has CONFIG_CRYPTO_HMAC, but module has NO_HMAC
#endif
@@ -196,7 +197,8 @@
#define LINUXKM_LKCAPI_REGISTER_SHA1_HMAC
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA1)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA1) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA1)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA1, but module has NO_SHA
#endif
@@ -220,7 +222,8 @@
#define LINUXKM_LKCAPI_REGISTER_SHA2_224_HMAC
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_224)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module is missing WOLFSSL_SHA224
#endif
@@ -244,7 +247,8 @@
#define LINUXKM_LKCAPI_REGISTER_SHA2_256_HMAC
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA256) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_256)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA256, but module has NO_SHA256
#endif
@@ -268,7 +272,8 @@
#define LINUXKM_LKCAPI_REGISTER_SHA2_384_HMAC
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_384)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA384
#endif
@@ -292,7 +297,8 @@
#define LINUXKM_LKCAPI_REGISTER_SHA2_512_HMAC
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA512) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA2_512)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA512, but module is missing WOLFSSL_SHA512
#endif
@@ -345,7 +351,8 @@
#endif
#endif
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA3)
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_SHA3) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_SHA3)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA3, but module is missing WOLFSSL_SHA3
#endif
@@ -379,6 +386,10 @@
#endif
/* setup for LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT is in linuxkm_wc_port.h */
#else
#if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && defined(CONFIG_CRYPTO_DRBG) && \
!defined(LINUXKM_LKCAPI_DONT_REGISTER_HASH_DRBG)
#error Config conflict: target kernel has CONFIG_CRYPTO_SHA3, but module is missing WOLFSSL_SHA3
#endif
#undef LINUXKM_LKCAPI_REGISTER_HASH_DRBG
#endif
@@ -757,6 +768,7 @@ WC_MAYBE_UNUSED static void km_hmac_exit_tfm(struct crypto_shash *tfm)
}
WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) {
int ret;
struct km_sha_hmac_state *t_ctx = (struct km_sha_hmac_state *)shash_desc_ctx(desc);
struct km_sha_hmac_pstate *p_ctx = (struct km_sha_hmac_pstate *)crypto_shash_ctx(desc->tfm);
@@ -764,34 +776,12 @@ WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) {
if (! t_ctx->wc_hmac)
return -ENOMEM;
XMEMCPY(t_ctx->wc_hmac, &p_ctx->wc_hmac, sizeof *t_ctx->wc_hmac);
#ifdef WOLFSSL_SMALL_STACK_CACHE
/* The cached W buffer from the persistent ctx can't be used because it
* would be double-freed, first by km_hmac_free_tstate(), then by
* km_hmac_exit_tfm().
*/
switch (t_ctx->wc_hmac->macType) {
#ifndef NO_SHA256
case WC_SHA256:
#ifdef WOLFSSL_SHA224
case WC_SHA224:
#endif
t_ctx->wc_hmac->hash.sha256.W = NULL;
break;
#endif /* WOLFSSL_SHA256 */
#ifdef WOLFSSL_SHA512
case WC_SHA512:
#ifdef WOLFSSL_SHA384
case WC_SHA384:
#endif
t_ctx->wc_hmac->hash.sha512.W = NULL;
break;
#endif /* WOLFSSL_SHA512 */
ret = wc_HmacCopy(&p_ctx->wc_hmac, t_ctx->wc_hmac);
if (ret != 0) {
free(t_ctx->wc_hmac);
t_ctx->wc_hmac = NULL;
return -EINVAL;
}
#endif /* WOLFSSL_SMALL_STACK_CACHE */
return 0;
}
@@ -1073,7 +1063,7 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
return NULL;
}
if (tfm == crypto_default_rng) {
if ((tfm == crypto_default_rng) && (preempt_count() == 0)) {
#if defined(CONFIG_SMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
migrate_disable(); /* this actually makes irq_count() nonzero, so that
* DISABLE_VECTOR_REGISTERS() is superfluous, but
@@ -1108,14 +1098,14 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
* caller can't sleep and the requested DRBG is busy, it returns immediately --
* this avoids priority inversions and deadlocks.
*/
static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, int n) {
static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, int n, int can_spin) {
int can_sleep = (preempt_count() == 0);
for (;;) {
int expected = 0;
if (likely(__atomic_compare_exchange_n(&ctx->rngs[n].lock, &expected, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)))
return &ctx->rngs[n];
if (can_sleep) {
if (can_sleep && can_spin) {
if (signal_pending(current))
return NULL;
cond_resched();
@@ -1242,7 +1232,7 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
* up, to assure they can't possibly phase-lock to each other.
*/
for (n = ctx->n_rngs - 1; n >= 0; --n) {
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 1);
if (! drbg) {
ret = -EINTR;
@@ -1313,6 +1303,14 @@ static int wc_linuxkm_drbg_loaded = 0;
#ifdef LINUXKM_DRBG_GET_RANDOM_BYTES
#ifndef WOLFSSL_SMALL_STACK_CACHE
/* WOLFSSL_SMALL_STACK_CACHE eliminates post-init heap allocations in SHA-2
* and the Hash DRBG, fixing circular call dependencies between
* get_random_u32() from kernel heap and wolfCrypt DRBG.
*/
#error LINUXKM_DRBG_GET_RANDOM_BYTES requires WOLFSSL_SMALL_STACK_CACHE.
#endif
#if !(defined(HAVE_ENTROPY_MEMUSE) || defined(HAVE_INTEL_RDSEED) || \
defined(HAVE_AMD_RDSEED) || defined(WC_LINUXKM_RDSEED_IN_GLUE_LAYER))
#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) {
return -EFAULT;
for (n = ctx->n_rngs - 1; n >= 0; --n) {
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 0);
int V_offset;
if (! drbg)
return -EINTR;
continue;
for (i = 0, V_offset = 0; i < len; ++i) {
((struct DRBG_internal *)drbg->rng.drbg)->V[V_offset++] += ((byte *)buf)[i];
@@ -1523,7 +1521,7 @@ static int wc_crng_reseed(void) {
return -EFAULT;
for (n = ctx->n_rngs - 1; n >= 0; --n) {
struct wc_rng_inst *drbg = get_drbg_n(ctx, n);
struct wc_rng_inst *drbg = get_drbg_n(ctx, n, 1);
if (! drbg)
return -EINTR;