@@ -902,38 +902,65 @@ struct wc_swallow_the_semicolon
902902#include <wolfssl/wolfcrypt/random.h>
903903
904904struct 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
909911static 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
930951static 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
962999out :
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