Merge pull request #8840 from douzzer/20250605-linuxkm-DRBG-multithread-round-1

20250605-linuxkm-DRBG-multithread-round-1
pull/8757/merge
David Garske 2025-06-12 13:17:54 -07:00 committed by GitHub
commit c5e63b84ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 96 additions and 33 deletions

View File

@ -7207,10 +7207,16 @@ then
fi fi
# Small Stack - Cache on object # Small Stack - Cache on object
if test "$ENABLED_LINUXKM_DEFAULTS" = "yes"
then
ENABLED_SMALL_STACK_CACHE_DEFAULT=yes
else
ENABLED_SMALL_STACK_CACHE_DEFAULT=no
fi
AC_ARG_ENABLE([smallstackcache], AC_ARG_ENABLE([smallstackcache],
[AS_HELP_STRING([--enable-smallstackcache],[Enable Small Stack Usage Caching (default: disabled)])], [AS_HELP_STRING([--enable-smallstackcache],[Enable Small Stack Usage Caching (default: disabled)])],
[ ENABLED_SMALL_STACK_CACHE=$enableval ], [ ENABLED_SMALL_STACK_CACHE=$enableval ],
[ ENABLED_SMALL_STACK_CACHE=no ] [ ENABLED_SMALL_STACK_CACHE=$ENABLED_SMALL_STACK_CACHE_DEFAULT ]
) )
if test "x$ENABLED_SMALL_STACK_CACHE" = "xyes" if test "x$ENABLED_SMALL_STACK_CACHE" = "xyes"

View File

@ -902,38 +902,65 @@ struct wc_swallow_the_semicolon
#include <wolfssl/wolfcrypt/random.h> #include <wolfssl/wolfcrypt/random.h>
struct wc_linuxkm_drbg_ctx { struct wc_linuxkm_drbg_ctx {
wolfSSL_Mutex lock; struct wc_rng_inst {
WC_RNG rng; wolfSSL_Mutex lock;
WC_RNG rng;
} *rngs; /* one per CPU ID */
}; };
static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm) static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
{ {
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm); struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
unsigned int i;
int ret; int ret;
ret = wc_InitMutex(&ctx->lock); ctx->rngs = (struct wc_rng_inst *)malloc(sizeof(*ctx->rngs) * nr_cpu_ids);
if (ret != 0) if (! ctx->rngs)
return -EINVAL; return -ENOMEM;
XMEMSET(ctx->rngs, 0, sizeof(*ctx->rngs) * nr_cpu_ids);
/* Note the new DRBG instance is seeded, and later reseeded, from system for (i = 0; i < nr_cpu_ids; ++i) {
* get_random_bytes() via wc_GenerateSeed(). ret = wc_InitMutex(&ctx->rngs[i].lock);
*/ if (ret != 0) {
ret = wc_InitRng(&ctx->rng); ret = -EINVAL;
if (ret != 0) { break;
(void)wc_FreeMutex(&ctx->lock); }
return -EINVAL;
/* Note the new DRBG instance is seeded, and later reseeded, from system
* get_random_bytes() via wc_GenerateSeed().
*/
ret = wc_InitRng(&ctx->rngs[i].rng);
if (ret != 0) {
ret = -EINVAL;
break;
}
} }
return 0; if (ret != 0) {
for (i = 0; i < nr_cpu_ids; ++i) {
(void)wc_FreeMutex(&ctx->rngs[i].lock);
wc_FreeRng(&ctx->rngs[i].rng);
}
free(ctx->rngs);
ctx->rngs = NULL;
}
return ret;
} }
static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm) static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
{ {
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm); struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
unsigned int i;
wc_FreeRng(&ctx->rng); if (ctx->rngs) {
for (i = 0; i < nr_cpu_ids; ++i) {
(void)wc_FreeMutex(&ctx->lock); (void)wc_FreeMutex(&ctx->rngs[i].lock);
wc_FreeRng(&ctx->rngs[i].rng);
}
free(ctx->rngs);
ctx->rngs = NULL;
}
return; return;
} }
@ -944,24 +971,33 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
{ {
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm); struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
int ret; int ret;
/* Note, core is not locked, so the actual core ID may change while
* executing, hence the mutex.
* The mutex is also needed to coordinate with wc_linuxkm_drbg_seed(), which
* seeds all instances.
*/
int my_cpu = raw_smp_processor_id();
wolfSSL_Mutex *lock = &ctx->rngs[my_cpu].lock;
WC_RNG *rng = &ctx->rngs[my_cpu].rng;
wc_LockMutex(&ctx->lock); if (wc_LockMutex(lock) != 0)
return -EINVAL;
if (slen > 0) { if (slen > 0) {
ret = wc_RNG_DRBG_Reseed(&ctx->rng, src, slen); ret = wc_RNG_DRBG_Reseed(rng, src, slen);
if (ret != 0) { if (ret != 0) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
} }
ret = wc_RNG_GenerateBlock(&ctx->rng, dst, dlen); ret = wc_RNG_GenerateBlock(rng, dst, dlen);
if (ret != 0) if (ret != 0)
ret = -EINVAL; ret = -EINVAL;
out: out:
wc_UnLockMutex(&ctx->lock); wc_UnLockMutex(lock);
return ret; return ret;
} }
@ -970,22 +1006,43 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
const u8 *seed, unsigned int slen) const u8 *seed, unsigned int slen)
{ {
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm); struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
u8 *seed_copy = NULL;
int ret; int ret;
unsigned int i;
if (slen == 0) if (slen == 0)
return 0; return 0;
wc_LockMutex(&ctx->lock); seed_copy = (u8 *)malloc(slen + 2);
if (! seed_copy)
return -ENOMEM;
XMEMCPY(seed_copy + 2, seed, slen);
ret = wc_RNG_DRBG_Reseed(&ctx->rng, seed, slen); for (i = 0; i < nr_cpu_ids; ++i) {
if (ret != 0) { wolfSSL_Mutex *lock = &ctx->rngs[i].lock;
ret = -EINVAL; WC_RNG *rng = &ctx->rngs[i].rng;
goto out;
/* perturb the seed with the CPU ID, so that no DRBG has the exact same
* seed.
*/
seed_copy[0] = (u8)(i >> 8);
seed_copy[1] = (u8)i;
if (wc_LockMutex(lock) != 0)
return -EINVAL;
ret = wc_RNG_DRBG_Reseed(rng, seed_copy, slen + 2);
if (ret != 0) {
ret = -EINVAL;
}
wc_UnLockMutex(lock);
if (ret != 0)
break;
} }
out: free(seed_copy);
wc_UnLockMutex(&ctx->lock);
return ret; return ret;
} }

View File

@ -647,13 +647,13 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
return DRBG_NEED_RESEED; return DRBG_NEED_RESEED;
} }
else { else {
#ifndef WOLFSSL_SMALL_STACK #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
byte digest[WC_SHA256_DIGEST_SIZE];
#else
byte* digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap, byte* digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap,
DYNAMIC_TYPE_DIGEST); DYNAMIC_TYPE_DIGEST);
if (digest == NULL) if (digest == NULL)
return DRBG_FAILURE; return DRBG_FAILURE;
#else
byte digest[WC_SHA256_DIGEST_SIZE];
#endif #endif
type = drbgGenerateH; type = drbgGenerateH;
@ -692,7 +692,7 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
drbg->reseedCtr++; drbg->reseedCtr++;
} }
ForceZero(digest, WC_SHA256_DIGEST_SIZE); ForceZero(digest, WC_SHA256_DIGEST_SIZE);
#ifdef WOLFSSL_SMALL_STACK #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST); XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
#endif #endif
} }