Skip to content

Commit 33773a9

Browse files
committed
Add a new define that causes the RSA code to use the global RNG.
If WE_RSA_USE_GLOBAL_RNG is defined, we_rsa.c will use the global wolfEngine RNG rather than instantiating local WC_RNGs where needed. This solves a problem with OpenSSH integration, where sshd forks a process to handle a client ssh connection. In this scenario, the forked process doesn't have privileges to read /dev/urandom, which is required to initialize a new WC_RNG. Using the already initialized global RNG is the solution.
1 parent 4067767 commit 33773a9

File tree

1 file changed

+83
-23
lines changed

1 file changed

+83
-23
lines changed

src/we_rsa.c

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323

2424
#ifdef WE_HAVE_RSA
2525

26+
/*
27+
* Macros
28+
* ------
29+
* WE_RSA_USE_GLOBAL_RNG:
30+
* Use the global wolfEngine RNG when an RNG is needed, as opposed to a
31+
* local one.
32+
*/
33+
2634
/* Maximum DER digest size, taken from wolfSSL. Sum of the maximum size of the
2735
encoded digest, algorithm tag, and sequence tag. */
2836
#define MAX_DER_DIGEST_SZ 98
@@ -43,7 +51,7 @@ typedef struct we_Rsa
4351
{
4452
/** wolfSSL structure for holding RSA key data. */
4553
RsaKey key;
46-
#ifndef WE_SINGLE_THREADED
54+
#ifndef WE_RSA_USE_GLOBAL_RNG
4755
/** Random number generator for RSA operations. */
4856
WC_RNG rng;
4957
#endif
@@ -353,19 +361,22 @@ static int we_rsa_init(RSA *rsa)
353361
}
354362
}
355363

356-
#ifndef WE_SINGLE_THREADED
364+
#ifndef WE_RSA_USE_GLOBAL_RNG
357365
if (ret == 1) {
358366
rc = wc_InitRng(&engineRsa->rng);
359367
if (rc != 0) {
368+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK,
369+
"wc_InitRng", rc);
360370
ret = 0;
361371
}
362372
}
363373
#endif
374+
364375
#ifdef WC_RSA_BLINDING
365376
if (ret == 1) {
366377
/* Set RNG for use when performing private operations or generating
367378
* random padding. */
368-
#ifndef WE_SINGLE_THREADED
379+
#ifndef WE_RSA_USE_GLOBAL_RNG
369380
rc = wc_RsaSetRNG(&engineRsa->key, &engineRsa->rng);
370381
#else
371382
rc = wc_RsaSetRNG(&engineRsa->key, we_rng);
@@ -391,9 +402,9 @@ static int we_rsa_init(RSA *rsa)
391402
}
392403

393404
if ((ret == 0) && (engineRsa != NULL)) {
394-
/* Disopse of the wolfSSL RSA key, RNG and internal object on failure.
405+
/* Dispose of the wolfSSL RSA key, RNG and internal object on failure.
395406
*/
396-
#ifndef WE_SINGLE_THREADED
407+
#ifndef WE_RSA_USE_GLOBAL_RNG
397408
wc_FreeRng(&engineRsa->rng);
398409
#endif
399410
wc_FreeRsaKey(&engineRsa->key);
@@ -422,7 +433,7 @@ static int we_rsa_finish(RSA *rsa)
422433
/* Remove reference to internal RSA object. */
423434
RSA_set_ex_data(rsa, WE_RSA_EX_DATA_IDX, NULL);
424435
/* Dispose of the wolfSSL RNG, RSA key and internal object. */
425-
#ifndef WE_SINGLE_THREADED
436+
#ifndef WE_RSA_USE_GLOBAL_RNG
426437
wc_FreeRng(&engineRsa->rng);
427438
#endif
428439
wc_FreeRsaKey(&engineRsa->key);
@@ -448,7 +459,7 @@ static int we_rsa_pub_enc_int(size_t fromLen, const unsigned char *from,
448459
{
449460
int ret;
450461
const EVP_MD *mdMGF1 = NULL;
451-
#ifndef WE_SINGLE_THREADED
462+
#ifndef WE_RSA_USE_GLOBAL_RNG
452463
WC_RNG *rng = &rsa->rng;
453464
#else
454465
WC_RNG *rng = we_rng;
@@ -460,6 +471,14 @@ static int we_rsa_pub_enc_int(size_t fromLen, const unsigned char *from,
460471
"toLen = %zu, to = %p, rsa = %p]", fromLen,
461472
from, toLen, to, rsa);
462473

474+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
475+
ret = wc_LockMutex(we_rng_mutex);
476+
if (ret != 0) {
477+
WOLFENGINE_ERROR_FUNC(WE_LOG_CIPHER, "wc_LockMutex", ret);
478+
return -1;
479+
}
480+
#endif
481+
463482
switch (rsa->padMode) {
464483
case RSA_PKCS1_PADDING:
465484
WOLFENGINE_MSG(WE_LOG_PK, "padMode: RSA_PKCS1_PADDING");
@@ -511,6 +530,10 @@ static int we_rsa_pub_enc_int(size_t fromLen, const unsigned char *from,
511530
ret = -1;
512531
}
513532

533+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
534+
wc_UnLockMutex(we_rng_mutex);
535+
#endif
536+
514537
WOLFENGINE_LEAVE(WE_LOG_PK, "we_rsa_pub_enc_int", ret);
515538

516539
return ret;
@@ -764,7 +787,7 @@ static int we_rsa_priv_enc_int(size_t fromLen, const unsigned char *from,
764787
int ret = 1;
765788
unsigned int tLen = (unsigned int)toLen;
766789
const EVP_MD *mdMGF1;
767-
#ifndef WE_SINGLE_THREADED
790+
#ifndef WE_RSA_USE_GLOBAL_RNG
768791
WC_RNG *rng = &rsa->rng;
769792
#else
770793
WC_RNG *rng = we_rng;
@@ -776,6 +799,14 @@ static int we_rsa_priv_enc_int(size_t fromLen, const unsigned char *from,
776799
"toLen = %zu, to = %p, rsa = %p]", fromLen, from,
777800
toLen, to, rsa);
778801

802+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
803+
ret = wc_LockMutex(we_rng_mutex);
804+
if (ret != 0) {
805+
WOLFENGINE_ERROR_FUNC(WE_LOG_CIPHER, "wc_LockMutex", ret);
806+
return -1;
807+
}
808+
#endif
809+
779810
switch (rsa->padMode) {
780811
case RSA_PKCS1_PADDING:
781812
WOLFENGINE_MSG(WE_LOG_PK, "padMode: RSA_PKCS1_PADDING");
@@ -833,6 +864,10 @@ static int we_rsa_priv_enc_int(size_t fromLen, const unsigned char *from,
833864
ret = -1;
834865
}
835866

867+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
868+
wc_UnLockMutex(we_rng_mutex);
869+
#endif
870+
836871
WOLFENGINE_LEAVE(WE_LOG_PK, "we_rsa_priv_enc_int", ret);
837872

838873
return ret;
@@ -936,7 +971,7 @@ static int we_rsa_pub_dec_int(size_t fromLen, const unsigned char *from,
936971
int ret = 1;
937972
unsigned int tLen = (unsigned int)toLen;
938973
const EVP_MD *mdMGF1;
939-
#ifndef WE_SINGLE_THREADED
974+
#ifndef WE_RSA_USE_GLOBAL_RNG
940975
WC_RNG *rng = &rsa->rng;
941976
#else
942977
WC_RNG *rng = we_rng;
@@ -968,12 +1003,24 @@ static int we_rsa_pub_dec_int(size_t fromLen, const unsigned char *from,
9681003
break;
9691004
case RSA_NO_PADDING:
9701005
WOLFENGINE_MSG(WE_LOG_PK, "padMode: RSA_NO_PADDING");
971-
ret = wc_RsaDirect((byte*)from, (unsigned int)fromLen, to,
972-
&tLen, &rsa->key, RSA_PUBLIC_DECRYPT, rng);
973-
if (ret < 0) {
974-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_RsaDirect", ret);
1006+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
1007+
if (wc_LockMutex(we_rng_mutex) != 0) {
1008+
WOLFENGINE_ERROR_FUNC(WE_LOG_CIPHER, "wc_LockMutex", ret);
9751009
ret = -1;
9761010
}
1011+
else
1012+
#endif
1013+
{
1014+
ret = wc_RsaDirect((byte*)from, (unsigned int)fromLen, to,
1015+
&tLen, &rsa->key, RSA_PUBLIC_DECRYPT, rng);
1016+
if (ret < 0) {
1017+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_RsaDirect", ret);
1018+
ret = -1;
1019+
}
1020+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
1021+
wc_UnLockMutex(we_rng_mutex);
1022+
#endif
1023+
}
9771024
break;
9781025
case RSA_PKCS1_PSS_PADDING:
9791026
WOLFENGINE_MSG(WE_LOG_PK, "padMode: RSA_PKCS1_PSS_PADDING");
@@ -1175,7 +1222,7 @@ static int we_rsa_keygen_int(we_Rsa *rsa, RSA **osslKey, int bits, long e)
11751222
{
11761223
int ret = 1;
11771224
int rc = 0;
1178-
#ifndef WE_SINGLE_THREADED
1225+
#ifndef WE_RSA_USE_GLOBAL_RNG
11791226
WC_RNG *rng = &rsa->rng;
11801227
#else
11811228
WC_RNG *rng = we_rng;
@@ -1186,7 +1233,7 @@ static int we_rsa_keygen_int(we_Rsa *rsa, RSA **osslKey, int bits, long e)
11861233
"bits = %d, e = %ld]", rsa, osslKey, bits, e);
11871234

11881235
/* Validate parameters. */
1189-
if (rsa == NULL) {
1236+
if (ret == 1 && rsa == NULL) {
11901237
WOLFENGINE_ERROR_MSG(WE_LOG_PK, "we_rsa_keygen_int: rsa NULL");
11911238
ret = 0;
11921239
}
@@ -1203,12 +1250,25 @@ static int we_rsa_keygen_int(we_Rsa *rsa, RSA **osslKey, int bits, long e)
12031250
}
12041251

12051252
if (ret == 1) {
1206-
/* Generate and RSA key with wolfSSL. */
1207-
rc = wc_MakeRsaKey(&rsa->key, bits, e, rng);
1253+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
1254+
rc = wc_LockMutex(we_rng_mutex);
12081255
if (rc != 0) {
1209-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_MakeRsaKey", rc);
1256+
WOLFENGINE_ERROR_FUNC(WE_LOG_CIPHER, "wc_LockMutex", ret);
12101257
ret = 0;
12111258
}
1259+
else
1260+
#endif
1261+
{
1262+
/* Generate and RSA key with wolfSSL. */
1263+
rc = wc_MakeRsaKey(&rsa->key, bits, e, rng);
1264+
if (rc != 0) {
1265+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_MakeRsaKey", rc);
1266+
ret = 0;
1267+
}
1268+
#if defined(WE_RSA_USE_GLOBAL_RNG) && !defined(WE_SINGLE_THREADED)
1269+
wc_UnLockMutex(we_rng_mutex);
1270+
#endif
1271+
}
12121272
}
12131273

12141274
if (ret == 1) {
@@ -1354,7 +1414,7 @@ static int we_rsa_pkey_init(EVP_PKEY_CTX *ctx)
13541414
}
13551415
}
13561416

1357-
#ifndef WE_SINGLE_THREADED
1417+
#ifndef WE_RSA_USE_GLOBAL_RNG
13581418
if (ret == 1) {
13591419
rc = wc_InitRng(&rsa->rng);
13601420
if (rc != 0) {
@@ -1376,9 +1436,9 @@ static int we_rsa_pkey_init(EVP_PKEY_CTX *ctx)
13761436
if ((ret == 0) && (rsa != NULL)) {
13771437
/* Dispose of the wolfSSL RSA key, RNG and internal object on failure.
13781438
*/
1379-
#ifndef WE_SINGLE_THREADED
1439+
#ifndef WE_RSA_USE_GLOBAL_RNG
13801440
wc_FreeRng(&rsa->rng);
1381-
#endif
1441+
#endif
13821442
wc_FreeRsaKey(&rsa->key);
13831443
OPENSSL_free(rsa);
13841444
}
@@ -1405,7 +1465,7 @@ static void we_rsa_pkey_cleanup(EVP_PKEY_CTX *ctx)
14051465
/* Remove reference to internal RSA object. */
14061466
EVP_PKEY_CTX_set_data(ctx, NULL);
14071467
/* Free the wolfSSL RSA key. */
1408-
#ifndef WE_SINGLE_THREADED
1468+
#ifndef WE_RSA_USE_GLOBAL_RNG
14091469
wc_FreeRng(&rsa->rng);
14101470
#endif
14111471
wc_FreeRsaKey(&rsa->key);
@@ -2466,7 +2526,7 @@ static int we_rsa_pkey_decrypt(EVP_PKEY_CTX *ctx, unsigned char *plaintext,
24662526
#ifdef WC_RSA_BLINDING
24672527
/* Always need RNG. */
24682528
if (ret == 1) {
2469-
#ifndef WE_SINGLE_THREADED
2529+
#ifndef WE_RSA_USE_GLOBAL_RNG
24702530
rc = wc_RsaSetRNG(&rsa->key, &rsa->rng);
24712531
#else
24722532
rc = wc_RsaSetRNG(&rsa->key, we_rng);

0 commit comments

Comments
 (0)