mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #8840 from douzzer/20250605-linuxkm-DRBG-multithread-round-1
20250605-linuxkm-DRBG-multithread-round-1pull/8757/merge
commit
c5e63b84ca
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue