diff --git a/src/tpm2-provider-signature.c b/src/tpm2-provider-signature.c index 2b83e88..1d14f8a 100644 --- a/src/tpm2-provider-signature.c +++ b/src/tpm2-provider-signature.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #include @@ -11,6 +12,10 @@ #include "tpm2-provider-types.h" #include "tpm2-provider-x509.h" +pthread_mutex_t tpm2_signature_initmutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t tpm2_signature_mutex; +int signature_initmtx_state = 0; + typedef struct tpm2_signature_ctx_st TPM2_SIGNATURE_CTX; struct tpm2_signature_ctx_st { @@ -46,6 +51,48 @@ static OSSL_FUNC_signature_settable_ctx_params_fn tpm2_rsa_signature_settable_ct static OSSL_FUNC_signature_set_ctx_params_fn tpm2_ecdsa_signature_set_ctx_params; static OSSL_FUNC_signature_settable_ctx_params_fn tpm2_ecdsa_signature_settable_ctx_params; +int +tpm2_signature_initmtx() +{ + int r; + + r = pthread_mutex_lock(&tpm2_signature_initmutex); + if (r) + return r; + + if (!signature_initmtx_state){ + pthread_mutexattr_t attr; + r = pthread_mutexattr_init(&attr); + if (r) + return r; + + r = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); + if (r) + return r; + + r = pthread_mutex_init(&tpm2_signature_mutex, &attr); + if (r) + return r; + + r = pthread_mutexattr_destroy(&attr); + if (r) + return r; + + signature_initmtx_state = 1; + } + + r = pthread_mutex_unlock(&tpm2_signature_initmutex); + return r; +} + +int +tpm2_signature_freemtx() +{ + int r; + r = pthread_mutex_destroy(&tpm2_signature_mutex); + return r; +} + static void * tpm2_signature_newctx(void *provctx, const char *propq) { @@ -55,6 +102,9 @@ tpm2_signature_newctx(void *provctx, const char *propq) if (sctx == NULL) return NULL; + if (tpm2_signature_initmtx()) + return NULL; + tpm2_hash_sequence_init((TPM2_HASH_SEQUENCE *)sctx, cprov, TPM2_ALG_NULL); sctx->capability = cprov->capability; sctx->signScheme.scheme = TPM2_ALG_NULL; @@ -69,7 +119,9 @@ tpm2_signature_freectx(void *ctx) if (sctx == NULL) return; - + if (tpm2_signature_freemtx()) + return; + tpm2_hash_sequence_flush((TPM2_HASH_SEQUENCE *)sctx); free(sctx->signature); OPENSSL_clear_free(sctx, sizeof(TPM2_SIGNATURE_CTX)); @@ -367,8 +419,15 @@ tpm2_rsa_signature_digest_init(void *ctx, const char *mdname, void *provkey, const OSSL_PARAM params[]) { TPM2_SIGNATURE_CTX *sctx = ctx; + pthread_t tid = pthread_self(); + + if (pthread_mutex_lock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX LOCK FAILED"); + } else { + DBG("SIGN MUTEX (%p) LOCKED (tid: %lu)\n", (void*)&tpm2_signature_mutex, (unsigned long)tid); + } - DBG("SIGN DIGEST_INIT rsa MD=%s\n", mdname); + DBG("SIGN DIGEST_INIT rsa MD=%s (tid: %lu)\n", mdname, (unsigned long)tid); sctx->pkey = provkey; return (tpm2_rsa_signature_set_ctx_params(sctx, params) @@ -468,14 +527,21 @@ tpm2_signature_digest_sign(void *ctx, unsigned char *sig, size_t *siglen, TPM2_SIGNATURE_CTX *sctx = ctx; TPM2B_DIGEST *digest = NULL; TPMT_TK_HASHCHECK *validation = NULL; + pthread_t tid = pthread_self(); if (sig == NULL) { DBG("SIGN DIGEST_SIGN estimate\n"); *siglen = estimate_signature_size(&sctx->pkey->data.pub.publicArea); + if (pthread_mutex_unlock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX UNLOCK FAILED\n"); + } else { + DBG("SIGN MUTEX UNLOCKED (tid:%lu)\n", (unsigned long)tid); + } return *siglen > 0; } - else + else { DBG("SIGN DIGEST_SIGN\n"); + } if (sctx->signature) { /* we are about to perform another signature in this context */ @@ -484,8 +550,14 @@ tpm2_signature_digest_sign(void *ctx, unsigned char *sig, size_t *siglen, } if (!tpm2_hash_sequence_hash((TPM2_HASH_SEQUENCE *)sctx, data, datalen, - &digest, &validation)) + &digest, &validation)){ + if (pthread_mutex_unlock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX UNLOCK FAILED\n"); + } else { + DBG("SIGN MUTEX UNLOCKED (tid:%lu)\n", (unsigned long)tid); + } return 0; + } if (validation->digest.size == 0) DBG("SIGN DIGEST_SIGN zero size ticket\n"); @@ -495,10 +567,30 @@ tpm2_signature_digest_sign(void *ctx, unsigned char *sig, size_t *siglen, digest, &sctx->signScheme, validation, &sctx->signature); free(digest); free(validation); + if (r){ + if (pthread_mutex_unlock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX UNLOCK FAILED\n"); + } else { + DBG("SIGN MUTEX UNLOCKED (tid:%lu)\n", (unsigned long)tid); + } + return 0; + } TPM2_CHECK_RC(sctx->core, r, TPM2_ERR_CANNOT_SIGN, return 0); - if (!get_signature_buffer(sctx->signature, sig, siglen, sigsize)) + if (!get_signature_buffer(sctx->signature, sig, siglen, sigsize)){ + if (pthread_mutex_unlock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX UNLOCK FAILED\n"); + } else { + DBG("SIGN MUTEX UNLOCKED (tid:%lu)\n", (unsigned long)tid); + } return 0; + } + + if (pthread_mutex_unlock(&tpm2_signature_mutex)){ + DBG("SIGN MUTEX UNLOCK FAILED\n"); + } else { + DBG("SIGN MUTEX UNLOCKED (tid:%lu)\n", (unsigned long)tid); + } return 1; } @@ -707,4 +799,3 @@ const OSSL_DISPATCH tpm2_ecdsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void(*)(void))tpm2_ecdsa_signature_settable_ctx_params }, { 0, NULL } }; -