Skip to content

Commit 29cf3eb

Browse files
committed
linuxkm/lkcapi_sha_glue.c: refactor DRBG wrapper to instantiate one DRBG per core, to relieve contention.
1 parent fbc483e commit 29cf3eb

1 file changed

Lines changed: 71 additions & 28 deletions

File tree

linuxkm/lkcapi_sha_glue.c

Lines changed: 71 additions & 28 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,34 @@ 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;
947-
948-
wc_LockMutex(&ctx->lock);
974+
int my_cpu =
975+
raw_smp_processor_id(); /* Note, core is not locked, so the actual core
976+
* ID may change while executing, hence the
977+
* mutex.
978+
* The mutex is also needed to coordinate with
979+
* wc_linuxkm_drbg_seed(), which seeds all
980+
* instances.
981+
*/
982+
wolfSSL_Mutex *lock = &ctx->rngs[my_cpu].lock;
983+
WC_RNG *rng = &ctx->rngs[my_cpu].rng;
984+
985+
wc_LockMutex(lock);
949986

950987
if (slen > 0) {
951-
ret = wc_RNG_DRBG_Reseed(&ctx->rng, src, slen);
988+
ret = wc_RNG_DRBG_Reseed(rng, src, slen);
952989
if (ret != 0) {
953990
ret = -EINVAL;
954991
goto out;
955992
}
956993
}
957994

958-
ret = wc_RNG_GenerateBlock(&ctx->rng, dst, dlen);
995+
ret = wc_RNG_GenerateBlock(rng, dst, dlen);
959996
if (ret != 0)
960997
ret = -EINVAL;
961998

962999
out:
9631000

964-
wc_UnLockMutex(&ctx->lock);
1001+
wc_UnLockMutex(lock);
9651002

9661003
return ret;
9671004
}
@@ -971,21 +1008,27 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
9711008
{
9721009
struct wc_linuxkm_drbg_ctx *ctx = (struct wc_linuxkm_drbg_ctx *)crypto_rng_ctx(tfm);
9731010
int ret;
1011+
unsigned int i;
9741012

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

978-
wc_LockMutex(&ctx->lock);
1016+
for (i = 0; i < nr_cpu_ids; ++i) {
1017+
wolfSSL_Mutex *lock = &ctx->rngs[i].lock;
1018+
WC_RNG *rng = &ctx->rngs[i].rng;
9791019

980-
ret = wc_RNG_DRBG_Reseed(&ctx->rng, seed, slen);
981-
if (ret != 0) {
982-
ret = -EINVAL;
983-
goto out;
984-
}
1020+
wc_LockMutex(lock);
9851021

986-
out:
1022+
ret = wc_RNG_DRBG_Reseed(rng, seed, slen);
1023+
if (ret != 0) {
1024+
ret = -EINVAL;
1025+
}
1026+
1027+
wc_UnLockMutex(lock);
9871028

988-
wc_UnLockMutex(&ctx->lock);
1029+
if (ret != 0)
1030+
break;
1031+
}
9891032

9901033
return ret;
9911034
}

0 commit comments

Comments
 (0)