diff --git a/include/wolfprovider/alg_funcs.h b/include/wolfprovider/alg_funcs.h index d1ca52f6..4c8bf2a4 100644 --- a/include/wolfprovider/alg_funcs.h +++ b/include/wolfprovider/alg_funcs.h @@ -175,6 +175,9 @@ typedef void (*DFUNC)(void); int wolfssl_prov_is_running(void); WC_RNG* wolfssl_prov_get_rng(WOLFPROV_CTX* provctx); +int wp_lock(wolfSSL_Mutex* mutex); +int wp_unlock(wolfSSL_Mutex* mutex); + /* Internal RSA types and functions. */ typedef struct wp_Rsa wp_Rsa; @@ -182,6 +185,7 @@ int wp_rsa_up_ref(wp_Rsa* rsa); void wp_rsa_free(wp_Rsa* rsa); int wp_rsa_get_type(wp_Rsa* rsa); int wp_rsa_get_bits(wp_Rsa* rsa); +wolfSSL_Mutex* wp_rsa_get_mutex(wp_Rsa* rsa); RsaKey* wp_rsa_get_key(wp_Rsa* rsa); void wp_rsa_get_pss_mds(wp_Rsa* rsa, char** mdName, char** mgfMdName); int wp_rsa_get_pss_salt_len(wp_Rsa* rsa); @@ -199,6 +203,7 @@ ecc_key* wp_ecc_get_key(wp_Ecc* ecc); WC_RNG* wp_ecc_get_rng(wp_Ecc* ecc); int wp_ecc_get_size(wp_Ecc* ecc); int wp_ecc_check_usage(wp_Ecc* ecc); +wolfSSL_Mutex* wp_ecc_get_mutex(wp_Ecc* ecc); /* Internal ECX types and functions. */ typedef struct wp_Ecx wp_Ecx; @@ -206,6 +211,7 @@ typedef struct wp_Ecx wp_Ecx; int wp_ecx_up_ref(wp_Ecx* ecx); void wp_ecx_free(wp_Ecx* ecx); void* wp_ecx_get_key(wp_Ecx* ecx); +wolfSSL_Mutex* wp_ecx_get_mutex(wp_Ecx* ecx); /* Internal DH types and functions. */ typedef struct wp_Dh wp_Dh; diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c index d05f51e3..25eaf11e 100644 --- a/src/wp_ecc_kmgmt.c +++ b/src/wp_ecc_kmgmt.c @@ -299,6 +299,17 @@ int wp_ecc_get_size(wp_Ecc* ecc) return (ecc->bits + 7) / 8; } +/** + * Get the mutex object from the ECC key object. + * + * @param [in] ecc ECC key object. + * @return Pointer to wolfSSL mutex object. + */ +wolfSSL_Mutex* wp_ecc_get_mutex(wp_Ecc* ecc) +{ + return &ecc->mutex; +} + /** * Create a new ECC key object. * diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c index af56de4a..0b648e2f 100644 --- a/src/wp_ecdsa_sig.c +++ b/src/wp_ecdsa_sig.c @@ -280,15 +280,21 @@ static int wp_ecdsa_sign(wp_EcdsaSigCtx *ctx, unsigned char *sig, sigSize = *sigLen; } len = (word32)sigSize; - PRIVATE_KEY_UNLOCK(); - rc = wc_ecc_sign_hash(tbs, (word32)tbsLen, sig, &len, - wp_ecc_get_rng(ctx->ecc), wp_ecc_get_key(ctx->ecc)); - PRIVATE_KEY_LOCK(); - if (rc != 0) { + if (wp_lock(wp_ecc_get_mutex(ctx->ecc)) != 1) { ok = 0; } - else { - *sigLen = len; + if (ok) { + PRIVATE_KEY_UNLOCK(); + rc = wc_ecc_sign_hash(tbs, (word32)tbsLen, sig, &len, + wp_ecc_get_rng(ctx->ecc), wp_ecc_get_key(ctx->ecc)); + PRIVATE_KEY_LOCK(); + wp_unlock(wp_ecc_get_mutex(ctx->ecc)); + if (rc != 0) { + ok = 0; + } + else { + *sigLen = len; + } } } } diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 0292dbc6..2ca82a55 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -243,6 +243,17 @@ void* wp_ecx_get_key(wp_Ecx* ecx) return (void*)&ecx->key; } +/** + * Get the mutex object from the ECX key object. + * + * @param [in] ecx ECX key object. + * @return Pointer to wolfSSL mutex object. + */ +wolfSSL_Mutex* wp_ecx_get_mutex(wp_Ecx* ecx) +{ + return &ecx->mutex; +} + /** * Create a new ECX key object. Base function. * diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index 15119532..2695c06c 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -436,12 +436,18 @@ static int wp_ed25519_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig, } } if (ok) { - rc = wc_ed25519_sign_msg(tbs, (word32)tbsLen, sig, &len, ed25519); - if (rc != 0) { + if (wp_lock(wp_ecx_get_mutex(ctx->ecx)) != 1) { ok = 0; } - else { - *sigLen = len; + if (ok) { + rc = wc_ed25519_sign_msg(tbs, (word32)tbsLen, sig, &len, ed25519); + wp_unlock(wp_ecx_get_mutex(ctx->ecx)); + if (rc != 0) { + ok = 0; + } + else { + *sigLen = len; + } } } } @@ -578,13 +584,19 @@ static int wp_ed448_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig, } } if (ok) { - rc = wc_ed448_sign_msg(tbs, (word32)tbsLen, sig, &len, - (ed448_key*)wp_ecx_get_key(ctx->ecx), NULL, 0); - if (rc != 0) { + if (wp_lock(wp_ecx_get_mutex(ctx->ecx)) != 1) { ok = 0; } - else { - *sigLen = len; + if (ok) { + rc = wc_ed448_sign_msg(tbs, (word32)tbsLen, sig, &len, + (ed448_key*)wp_ecx_get_key(ctx->ecx), NULL, 0); + wp_unlock(wp_ecx_get_mutex(ctx->ecx)); + if (rc != 0) { + ok = 0; + } + else { + *sigLen = len; + } } } } diff --git a/src/wp_internal.c b/src/wp_internal.c index 1ad85d63..9405f15f 100644 --- a/src/wp_internal.c +++ b/src/wp_internal.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,76 @@ void wp_provctx_unlock_rng(WOLFPROV_CTX* provCtx) } #endif +/** + * Lock the mutex. + * + * This function locks the mutex and translates the return value. + * Use wp_unlock() to unlock after operations are complete. + * + * @param [in] mutex Mutex object. + * @return 1 on success. + * @return 0 on failure or when single-threaded build. + */ +int wp_lock(wolfSSL_Mutex *mutex) +{ +#ifndef WP_SINGLE_THREADED + int ok = 1; + int rc; + + if (mutex == NULL) { + ok = 0; + } + else { + rc = wc_LockMutex(mutex); + if (rc < 0) { + ok = 0; + } + } + + WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); + return ok; +#else + (void)mutex; + WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1); + return 1; +#endif +} + +/** + * Unlock the mutex. + * + * This function unlocks the mutex and translates the return value. + * Should only be called after a successful wp_lock() call. + * + * @param [in] mutex Mutex object. + * @return 1 on success. + * @return 0 on failure or when single-threaded build. + */ +int wp_unlock(wolfSSL_Mutex* mutex) +{ +#ifndef WP_SINGLE_THREADED + int ok = 1; + int rc; + + if (mutex == NULL) { + ok = 0; + } + else { + rc = wc_UnLockMutex(mutex); + if (rc < 0) { + ok = 0; + } + } + + WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); + return ok; +#else + (void)mutex; + WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1); + return 1; +#endif +} + /** * Convert the string name of an object to an OpenSSL Numeric ID (NID). diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index cbd560bf..04d99699 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -330,6 +330,17 @@ int wp_rsa_get_bits(wp_Rsa* rsa) return rsa->bits; } +/** + * Get the mutex object from the RSA key object. + * + * @param [in] rsa RSA key object. + * @return Pointer to wolfSSL mutex object. + */ +wolfSSL_Mutex* wp_rsa_get_mutex(wp_Rsa* rsa) +{ + return &rsa->mutex; +} + /** * Check the RSA key size is valid. * diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 55d33ec0..c147bbff 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -609,13 +609,19 @@ static int wp_rsa_sign_pkcs1(wp_RsaSigCtx* ctx, unsigned char* sig, } } if (ok) { - PRIVATE_KEY_UNLOCK(); - rc = wc_RsaSSL_Sign(tbs, (word32)tbsLen, sig, (word32)sigSize, - wp_rsa_get_key(ctx->rsa), &ctx->rng); - PRIVATE_KEY_LOCK(); - if (rc <= 0) { + if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { ok = 0; } + if (ok) { + PRIVATE_KEY_UNLOCK(); + rc = wc_RsaSSL_Sign(tbs, (word32)tbsLen, sig, (word32)sigSize, + wp_rsa_get_key(ctx->rsa), &ctx->rng); + PRIVATE_KEY_LOCK(); + wp_unlock(wp_rsa_get_mutex(ctx->rsa)); + if (rc <= 0) { + ok = 0; + } + } } if (ok) { *sigLen = rc; @@ -655,21 +661,29 @@ static int wp_rsa_sign_pss(wp_RsaSigCtx* ctx, unsigned char* sig, #endif wp_rsa_get_key(ctx->rsa), EVP_PKEY_OP_SIGN); - PRIVATE_KEY_UNLOCK(); - rc = wc_RsaPSS_Sign_ex(tbs, (word32)tbsLen, sig, (word32)sigSize, -#if LIBWOLFSSL_VERSION_HEX >= 0x05007004 - ctx->hash.type, -#else - ctx->hashType, -#endif - ctx->mgf, saltLen, wp_rsa_get_key(ctx->rsa), - &ctx->rng); - PRIVATE_KEY_LOCK(); - if (rc < 0) { - ok = 0; - } - else { - *sigLen = rc; + if (ok) { + if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { + ok = 0; + } + if (ok) { + PRIVATE_KEY_UNLOCK(); + rc = wc_RsaPSS_Sign_ex(tbs, (word32)tbsLen, sig, (word32)sigSize, + #if LIBWOLFSSL_VERSION_HEX >= 0x05007004 + ctx->hash.type, + #else + ctx->hashType, + #endif + ctx->mgf, saltLen, wp_rsa_get_key(ctx->rsa), + &ctx->rng); + PRIVATE_KEY_LOCK(); + wp_unlock(wp_rsa_get_mutex(ctx->rsa)); + if (rc < 0) { + ok = 0; + } + else { + *sigLen = rc; + } + } } WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); @@ -749,16 +763,21 @@ static int wp_rsa_sign_no_pad(wp_RsaSigCtx* ctx, unsigned char* sig, if (ok) { word32 len = (word32)sigSize; int rc; - - PRIVATE_KEY_UNLOCK(); - rc = wc_RsaDirect((byte*)tbs, (word32)tbsLen, sig, &len, - wp_rsa_get_key(ctx->rsa), RSA_PRIVATE_ENCRYPT, &ctx->rng); - PRIVATE_KEY_LOCK(); - if (rc < 0) { + if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { ok = 0; } - else { - *sigLen = rc; + if (ok) { + PRIVATE_KEY_UNLOCK(); + rc = wc_RsaDirect((byte*)tbs, (word32)tbsLen, sig, &len, + wp_rsa_get_key(ctx->rsa), RSA_PRIVATE_ENCRYPT, &ctx->rng); + PRIVATE_KEY_LOCK(); + wp_unlock(wp_rsa_get_mutex(ctx->rsa)); + if (rc < 0) { + ok = 0; + } + else { + *sigLen = rc; + } } } @@ -841,16 +860,21 @@ static int wp_rsa_sign_x931(wp_RsaSigCtx* ctx, unsigned char* sig, } if (ok) { word32 len = (word32)sigSize; - - PRIVATE_KEY_UNLOCK(); - rc = wc_RsaDirect(padded, paddedSz, sig, &len, - wp_rsa_get_key(ctx->rsa), RSA_PRIVATE_ENCRYPT, &ctx->rng); - PRIVATE_KEY_LOCK(); - if (rc < 0) { + if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { ok = 0; } - else { - *sigLen = rc; + if (ok) { + PRIVATE_KEY_UNLOCK(); + rc = wc_RsaDirect(padded, paddedSz, sig, &len, + wp_rsa_get_key(ctx->rsa), RSA_PRIVATE_ENCRYPT, &ctx->rng); + PRIVATE_KEY_LOCK(); + wp_unlock(wp_rsa_get_mutex(ctx->rsa)); + if (rc < 0) { + ok = 0; + } + else { + *sigLen = rc; + } } } if (padded != NULL) { @@ -914,6 +938,8 @@ static int wp_rsa_sign(wp_RsaSigCtx* ctx, unsigned char* sig, size_t* sigLen, { int ok = 1; + WOLFPROV_ENTER(WP_LOG_PK, __FUNCTION__); + if (!wolfssl_prov_is_running()) { ok = 0; } @@ -1311,6 +1337,8 @@ static int wp_rsa_verify(wp_RsaSigCtx* ctx, const unsigned char* sig, { int ok = 1; + WOLFPROV_ENTER(WP_LOG_PK, __FUNCTION__); + if (!wolfssl_prov_is_running()) { ok = 0; }