Skip to content

Commit c5e63b8

Browse files
authored
Merge pull request #8840 from douzzer/20250605-linuxkm-DRBG-multithread-round-1
20250605-linuxkm-DRBG-multithread-round-1
2 parents 2fc1110 + ae15693 commit c5e63b8

3 files changed

Lines changed: 95 additions & 32 deletions

File tree

configure.ac

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7207,10 +7207,16 @@ then
72077207
fi
72087208
72097209
# Small Stack - Cache on object
7210+
if test "$ENABLED_LINUXKM_DEFAULTS" = "yes"
7211+
then
7212+
ENABLED_SMALL_STACK_CACHE_DEFAULT=yes
7213+
else
7214+
ENABLED_SMALL_STACK_CACHE_DEFAULT=no
7215+
fi
72107216
AC_ARG_ENABLE([smallstackcache],
72117217
[AS_HELP_STRING([--enable-smallstackcache],[Enable Small Stack Usage Caching (default: disabled)])],
72127218
[ ENABLED_SMALL_STACK_CACHE=$enableval ],
7213-
[ ENABLED_SMALL_STACK_CACHE=no ]
7219+
[ ENABLED_SMALL_STACK_CACHE=$ENABLED_SMALL_STACK_CACHE_DEFAULT ]
72147220
)
72157221
72167222
if test "x$ENABLED_SMALL_STACK_CACHE" = "xyes"

linuxkm/lkcapi_sha_glue.c

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -902,38 +902,65 @@ struct wc_swallow_the_semicolon
902902
#include <wolfssl/wolfcrypt/random.h>
903903

904904
struct wc_linuxkm_drbg_ctx {
905-
wolfSSL_Mutex lock;
906-
WC_RNG rng;
905+
struct wc_rng_inst {
906+
wolfSSL_Mutex lock;
907+
WC_RNG rng;
908+
} *rngs; /* one per CPU ID */
907909
};
908910

909911
static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
910912
{
911913
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
914+
unsigned int i;
912915
int ret;
913916

914-
ret = wc_InitMutex(&ctx->lock);
915-
if (ret != 0)
916-
return -EINVAL;
917+
ctx->rngs = (struct wc_rng_inst *)malloc(sizeof(*ctx->rngs) * nr_cpu_ids);
918+
if (! ctx->rngs)
919+
return -ENOMEM;
920+
XMEMSET(ctx->rngs, 0, sizeof(*ctx->rngs) * nr_cpu_ids);
921+
922+
for (i = 0; i < nr_cpu_ids; ++i) {
923+
ret = wc_InitMutex(&ctx->rngs[i].lock);
924+
if (ret != 0) {
925+
ret = -EINVAL;
926+
break;
927+
}
928+
929+
/* Note the new DRBG instance is seeded, and later reseeded, from system
930+
* get_random_bytes() via wc_GenerateSeed().
931+
*/
932+
ret = wc_InitRng(&ctx->rngs[i].rng);
933+
if (ret != 0) {
934+
ret = -EINVAL;
935+
break;
936+
}
937+
}
917938

918-
/* Note the new DRBG instance is seeded, and later reseeded, from system
919-
* get_random_bytes() via wc_GenerateSeed().
920-
*/
921-
ret = wc_InitRng(&ctx->rng);
922939
if (ret != 0) {
923-
(void)wc_FreeMutex(&ctx->lock);
924-
return -EINVAL;
940+
for (i = 0; i < nr_cpu_ids; ++i) {
941+
(void)wc_FreeMutex(&ctx->rngs[i].lock);
942+
wc_FreeRng(&ctx->rngs[i].rng);
943+
}
944+
free(ctx->rngs);
945+
ctx->rngs = NULL;
925946
}
926947

927-
return 0;
948+
return ret;
928949
}
929950

930951
static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
931952
{
932953
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_tfm_ctx(tfm);
954+
unsigned int i;
933955

934-
wc_FreeRng(&ctx->rng);
935-
936-
(void)wc_FreeMutex(&ctx->lock);
956+
if (ctx->rngs) {
957+
for (i = 0; i < nr_cpu_ids; ++i) {
958+
(void)wc_FreeMutex(&ctx->rngs[i].lock);
959+
wc_FreeRng(&ctx->rngs[i].rng);
960+
}
961+
free(ctx->rngs);
962+
ctx->rngs = NULL;
963+
}
937964

938965
return;
939966
}
@@ -944,24 +971,33 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
944971
{
945972
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
946973
int ret;
974+
/* Note, core is not locked, so the actual core ID may change while
975+
* executing, hence the mutex.
976+
* The mutex is also needed to coordinate with wc_linuxkm_drbg_seed(), which
977+
* seeds all instances.
978+
*/
979+
int my_cpu = raw_smp_processor_id();
980+
wolfSSL_Mutex *lock = &ctx->rngs[my_cpu].lock;
981+
WC_RNG *rng = &ctx->rngs[my_cpu].rng;
947982

948-
wc_LockMutex(&ctx->lock);
983+
if (wc_LockMutex(lock) != 0)
984+
return -EINVAL;
949985

950986
if (slen > 0) {
951-
ret = wc_RNG_DRBG_Reseed(&ctx->rng, src, slen);
987+
ret = wc_RNG_DRBG_Reseed(rng, src, slen);
952988
if (ret != 0) {
953989
ret = -EINVAL;
954990
goto out;
955991
}
956992
}
957993

958-
ret = wc_RNG_GenerateBlock(&ctx->rng, dst, dlen);
994+
ret = wc_RNG_GenerateBlock(rng, dst, dlen);
959995
if (ret != 0)
960996
ret = -EINVAL;
961997

962998
out:
963999

964-
wc_UnLockMutex(&ctx->lock);
1000+
wc_UnLockMutex(lock);
9651001

9661002
return ret;
9671003
}
@@ -970,22 +1006,43 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
9701006
const u8 *seed, unsigned int slen)
9711007
{
9721008
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
1009+
u8 *seed_copy = NULL;
9731010
int ret;
1011+
unsigned int i;
9741012

9751013
if (slen == 0)
9761014
return 0;
9771015

978-
wc_LockMutex(&ctx->lock);
1016+
seed_copy = (u8 *)malloc(slen + 2);
1017+
if (! seed_copy)
1018+
return -ENOMEM;
1019+
XMEMCPY(seed_copy + 2, seed, slen);
9791020

980-
ret = wc_RNG_DRBG_Reseed(&ctx->rng, seed, slen);
981-
if (ret != 0) {
982-
ret = -EINVAL;
983-
goto out;
984-
}
1021+
for (i = 0; i < nr_cpu_ids; ++i) {
1022+
wolfSSL_Mutex *lock = &ctx->rngs[i].lock;
1023+
WC_RNG *rng = &ctx->rngs[i].rng;
9851024

986-
out:
1025+
/* perturb the seed with the CPU ID, so that no DRBG has the exact same
1026+
* seed.
1027+
*/
1028+
seed_copy[0] = (u8)(i >> 8);
1029+
seed_copy[1] = (u8)i;
1030+
1031+
if (wc_LockMutex(lock) != 0)
1032+
return -EINVAL;
1033+
1034+
ret = wc_RNG_DRBG_Reseed(rng, seed_copy, slen + 2);
1035+
if (ret != 0) {
1036+
ret = -EINVAL;
1037+
}
1038+
1039+
wc_UnLockMutex(lock);
1040+
1041+
if (ret != 0)
1042+
break;
1043+
}
9871044

988-
wc_UnLockMutex(&ctx->lock);
1045+
free(seed_copy);
9891046

9901047
return ret;
9911048
}

wolfcrypt/src/random.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -647,13 +647,13 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
647647
return DRBG_NEED_RESEED;
648648
}
649649
else {
650-
#ifndef WOLFSSL_SMALL_STACK
651-
byte digest[WC_SHA256_DIGEST_SIZE];
652-
#else
650+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
653651
byte* digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap,
654652
DYNAMIC_TYPE_DIGEST);
655653
if (digest == NULL)
656654
return DRBG_FAILURE;
655+
#else
656+
byte digest[WC_SHA256_DIGEST_SIZE];
657657
#endif
658658

659659
type = drbgGenerateH;
@@ -692,7 +692,7 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
692692
drbg->reseedCtr++;
693693
}
694694
ForceZero(digest, WC_SHA256_DIGEST_SIZE);
695-
#ifdef WOLFSSL_SMALL_STACK
695+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
696696
XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
697697
#endif
698698
}

0 commit comments

Comments
 (0)