diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c index 884bbe077..e8a009cb6 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c @@ -58,11 +58,6 @@ struct private_wolfssl_ec_private_key_t { */ ecc_key ec; - /** - * Random number generator - */ - WC_RNG rng; - /** * Reference count */ @@ -79,25 +74,32 @@ static bool build_signature(private_wolfssl_ec_private_key_t *this, chunk_t hash, chunk_t *signature) { bool success = FALSE; + WC_RNG rng; mp_int r, s; + if (wc_InitRng(&rng) != 0) + { + return FALSE; + } if (mp_init(&r) != 0) { + wc_FreeRng(&rng); return FALSE; } if (mp_init(&s) != 0) { mp_free(&r); + wc_FreeRng(&rng); return FALSE; } - if (wc_ecc_sign_hash_ex(hash.ptr, hash.len, &this->rng, &this->ec, &r, - &s) == 0) + if (wc_ecc_sign_hash_ex(hash.ptr, hash.len, &rng, &this->ec, &r, &s) == 0) { success = wolfssl_mp_cat(this->ec.dp->size * 2, &r, &s, signature); } mp_free(&s); mp_free(&r); + wc_FreeRng(&rng); return success; } @@ -135,14 +137,19 @@ static bool build_der_signature(private_wolfssl_ec_private_key_t *this, { chunk_t dgst = chunk_empty; bool success = FALSE; + WC_RNG rng; word32 len; + if (wc_InitRng(&rng) != 0) + { + return FALSE; + } if (wolfssl_hash_chunk(hash, data, &dgst)) { *signature = chunk_alloc(wc_ecc_sig_size(&this->ec)); len = signature->len; if (wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len, - &this->rng, &this->ec) == 0) + &rng, &this->ec) == 0) { signature->len = len; success = TRUE; @@ -153,6 +160,7 @@ static bool build_der_signature(private_wolfssl_ec_private_key_t *this, } } chunk_free(&dgst); + wc_FreeRng(&rng); return success; } @@ -306,7 +314,6 @@ METHOD(private_key_t, destroy, void, if (ref_put(&this->ref)) { lib->encoding->clear_cache(lib->encoding, &this->ec); - wc_FreeRng(&this->rng); wc_ecc_free(&this->ec); free(this); } @@ -345,13 +352,6 @@ static private_wolfssl_ec_private_key_t *create_empty(void) free(this); return NULL; } - if (wc_InitRng(&this->rng) != 0) - { - DBG1(DBG_LIB, "RNG initialization for EC private key failed"); - wc_ecc_free(&this->ec); - free(this); - return NULL; - } return this; } @@ -364,6 +364,7 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type, private_wolfssl_ec_private_key_t *this; u_int key_size = 0; ecc_curve_id curve_id; + WC_RNG rng; while (TRUE) { @@ -407,13 +408,19 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type, return NULL; } - if (wc_ecc_make_key_ex(&this->rng, (key_size + 7) / 8, &this->ec, - curve_id) < 0) + if (wc_InitRng(&rng) != 0) { - DBG1(DBG_LIB, "EC private key generation failed"); destroy(this); return NULL; } + if (wc_ecc_make_key_ex(&rng, (key_size + 7) / 8, &this->ec, curve_id) < 0) + { + DBG1(DBG_LIB, "EC private key generation failed"); + destroy(this); + wc_FreeRng(&rng); + return NULL; + } + wc_FreeRng(&rng); return &this->public; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c index c27916979..8d517049c 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c @@ -57,6 +57,11 @@ struct private_wolfssl_rsa_private_key_t { */ WC_RNG rng; + /** + * Mutex to protect access to the RNG during API calls. + */ + wolfSSL_Mutex mutex; + /** * Reference count */ @@ -73,8 +78,12 @@ bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type, chunk_t *fp static bool build_signature(private_wolfssl_rsa_private_key_t *this, enum wc_HashType hash, chunk_t data, chunk_t *sig) { - int ret = wc_RsaSSL_Sign(data.ptr, data.len, sig->ptr, sig->len, &this->rsa, - &this->rng); + int ret; + + wc_LockMutex(&this->mutex); + ret = wc_RsaSSL_Sign(data.ptr, data.len, sig->ptr, sig->len, &this->rsa, + &this->rng); + wc_UnLockMutex(&this->mutex); if (ret > 0) { sig->len = ret; @@ -146,8 +155,10 @@ static bool build_emsa_pss_signature(private_wolfssl_rsa_private_key_t *this, if (wolfssl_hash_chunk(hash, data, &dgst)) { + wc_LockMutex(&this->mutex); ret = wc_RsaPSS_Sign_ex(dgst.ptr, dgst.len, sig->ptr, sig->len, hash, mgf, params->salt_len, &this->rsa, &this->rng); + wc_UnLockMutex(&this->mutex); if (ret > 0) { sig->len = ret; @@ -305,9 +316,11 @@ METHOD(private_key_t, decrypt, bool, } len = wc_RsaEncryptSize(&this->rsa); *plain = chunk_alloc(len); + wc_LockMutex(&this->mutex); len = wc_RsaPrivateDecrypt_ex(crypto.ptr, crypto.len, plain->ptr, len, &this->rsa, padding, hash, mgf, label.ptr, label.len); + wc_UnLockMutex(&this->mutex); if (len < 0) { DBG1(DBG_LIB, "RSA decryption failed"); @@ -401,6 +414,7 @@ METHOD(private_key_t, destroy, void, { lib->encoding->clear_cache(lib->encoding, &this->rsa); wc_FreeRsaKey(&this->rsa); + wc_FreeMutex(&this->mutex); wc_FreeRng(&this->rng); free(this); } @@ -439,15 +453,27 @@ static private_wolfssl_rsa_private_key_t *create_empty() free(this); return NULL; } + if (wc_InitMutex(&this->mutex) != 0) + { + DBG1(DBG_LIB, "init mutex failed, rsa private key create failed"); + wc_FreeRng(&this->rng); + free(this); + return NULL; + } if (wc_InitRsaKey(&this->rsa, NULL) != 0) { DBG1(DBG_LIB, "init RSA failed, rsa private key create failed"); + wc_FreeMutex(&this->mutex); wc_FreeRng(&this->rng); free(this); return NULL; } #ifdef WC_RSA_BLINDING - this->rsa.rng = &this->rng; + if (wc_RsaSetRNG(&this->rsa, &this->rng) != 0) + { + destroy(this); + return NULL; + } #endif return this; diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c index 341455094..ab5f6dbb5 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c @@ -57,6 +57,11 @@ struct private_wolfssl_rsa_public_key_t { */ WC_RNG rng; + /** + * Mutex to protect access to the RNG via API calls. + */ + wolfSSL_Mutex mutex; + /** * Reference counter */ @@ -81,7 +86,9 @@ static bool verify_signature(private_wolfssl_rsa_public_key_t *this, padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00); + wc_LockMutex(&this->mutex); len = wc_RsaSSL_VerifyInline(padded.ptr, len, &p, &this->rsa); + wc_UnLockMutex(&this->mutex); if (len > 0) { success = chunk_equals_const(data, chunk_create(p, len)); @@ -149,8 +156,10 @@ static bool verify_emsa_pss_signature(private_wolfssl_rsa_public_key_t *this, } padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00); + wc_LockMutex(&this->mutex); len = wc_RsaPSS_VerifyInline_ex(padded.ptr, len, &p, hash, mgf, params->salt_len, &this->rsa); + wc_UnLockMutex(&this->mutex); if (len > 0) { success = wc_RsaPSS_CheckPadding_ex(dgst.ptr, dgst.len, p, len, hash, @@ -280,9 +289,11 @@ METHOD(public_key_t, encrypt_, bool, } len = wc_RsaEncryptSize(&this->rsa); *crypto = chunk_alloc(len); + wc_LockMutex(&this->mutex); len = wc_RsaPublicEncrypt_ex(plain.ptr, plain.len, crypto->ptr, len, &this->rsa, &this->rng, padding, hash, mgf, label.ptr, label.len); + wc_UnLockMutex(&this->mutex); if (len < 0) { DBG1(DBG_LIB, "RSA encryption failed"); @@ -423,6 +434,7 @@ METHOD(public_key_t, destroy, void, { lib->encoding->clear_cache(lib->encoding, &this->rsa); wc_FreeRsaKey(&this->rsa); + wc_FreeMutex(&this->mutex); wc_FreeRng(&this->rng); free(this); } @@ -459,13 +471,28 @@ static private_wolfssl_rsa_public_key_t *create_empty() free(this); return NULL; } - if (wc_InitRsaKey(&this->rsa, NULL) != 0) + if (wc_InitMutex(&this->mutex) != 0) { - DBG1(DBG_LIB, "init RSA failed, rsa public key load failed"); + DBG1(DBG_LIB, "init mutex failed, rsa public key load failed"); wc_FreeRng(&this->rng); free(this); return NULL; } + if (wc_InitRsaKey(&this->rsa, NULL) != 0) + { + DBG1(DBG_LIB, "init RSA failed, rsa public key load failed"); + wc_FreeMutex(&this->mutex); + wc_FreeRng(&this->rng); + free(this); + return NULL; + } +#ifdef WC_RSA_BLINDING + if (wc_RsaSetRNG(&this->rsa, &this->rng) != 0) + { + destroy(this); + return NULL; + } +#endif return this; }