From d27306b1c90bd887621b1adbff5c3dc99570df93 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 28 Apr 2025 23:09:15 -0700 Subject: [PATCH 1/4] Improve mutex locking protection for concurrent thread usage. Use a global mutex instead of one that is part of TPM2_CTX. ZD 19771 --- src/tpm2.c | 58 +++++++++++++++++++------------------------------- wolftpm/tpm2.h | 7 ------ 2 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/tpm2.c b/src/tpm2.c index 9984ee7..9129632 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -42,6 +42,11 @@ static THREAD_LS_T TPM2_CTX* gActiveTPM; static volatile int gWolfCryptRefCount = 0; #endif +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_NO_LOCK) && \ + !defined(SINGLE_THREADED) +static wolfSSL_Mutex gHwLock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gHwLock); +#endif + #ifdef WOLFTPM_LINUX_DEV #define INTERNAL_SEND_COMMAND TPM2_LINUX_SendCommand #define TPM2_INTERNAL_CLEANUP(ctx) @@ -61,43 +66,24 @@ static volatile int gWolfCryptRefCount = 0; /******************************************************************************/ static TPM_RC TPM2_AcquireLock(TPM2_CTX* ctx) { -#if defined(WOLFTPM2_NO_WOLFCRYPT) || defined(WOLFTPM_NO_LOCK) - (void)ctx; -#else - int ret; - - if (!ctx->hwLockInit) { - if (wc_InitMutex(&ctx->hwLock) != 0) { - #ifdef DEBUG_WOLFTPM - printf("TPM Mutex Init failed\n"); - #endif - return TPM_RC_FAILURE; - } - ctx->hwLockInit = 1; - ctx->lockCount = 0; +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_NO_LOCK) && \ + !defined(SINGLE_THREADED) + int ret = wc_LockMutex(&gHwLock); + if (ret != 0) { + return TPM_RC_FAILURE; } - - if (ctx->lockCount == 0) { - ret = wc_LockMutex(&ctx->hwLock); - if (ret != 0) - return TPM_RC_FAILURE; - } - ctx->lockCount++; #endif + (void)ctx; return TPM_RC_SUCCESS; } static void TPM2_ReleaseLock(TPM2_CTX* ctx) { -#if defined(WOLFTPM2_NO_WOLFCRYPT) || defined(WOLFTPM_NO_LOCK) - (void)ctx; -#else - ctx->lockCount--; - if (ctx->lockCount == 0) { - wc_UnLockMutex(&ctx->hwLock); - } - +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_NO_LOCK) && \ + !defined(SINGLE_THREADED) + wc_UnLockMutex(&gHwLock); #endif + (void)ctx; } static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, @@ -507,6 +493,9 @@ static inline int TPM2_WolfCrypt_Init(void) if (rc == 0) rc = wc_SetSeed_Cb(wc_GenerateSeed); #endif + #ifndef WOLFSSL_MUTEX_INITIALIZER + wc_InitMutex(&gHwMutex); + #endif } gWolfCryptRefCount++; @@ -697,19 +686,16 @@ TPM_RC TPM2_Cleanup(TPM2_CTX* ctx) wc_FreeRng(&ctx->rng); } #endif - #ifndef WOLFTPM_NO_LOCK - if (ctx->hwLockInit) { - ctx->hwLockInit = 0; - wc_FreeMutex(&ctx->hwLock); - } - #endif /* track wolf initialize reference count in wolfTPM. wolfCrypt does not - properly track reference count in v4.1 or older releases */ + * properly track reference count in v4.1 or older releases */ gWolfCryptRefCount--; if (gWolfCryptRefCount < 0) gWolfCryptRefCount = 0; if (gWolfCryptRefCount == 0) { + #ifndef WOLFSSL_MUTEX_INITIALIZER + wc_FreeMutex(&gHwMutex); + #endif wolfCrypt_Cleanup(); } #endif /* !WOLFTPM2_NO_WOLFCRYPT */ diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 38e8f35..018e243 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -1855,10 +1855,6 @@ typedef struct TPM2_CTX { struct wolfTPM_winContext winCtx; #endif #ifndef WOLFTPM2_NO_WOLFCRYPT -#ifndef WOLFTPM_NO_LOCK - wolfSSL_Mutex hwLock; - int lockCount; -#endif #ifdef WOLFTPM2_USE_WOLF_RNG WC_RNG rng; #endif @@ -1878,9 +1874,6 @@ typedef struct TPM2_CTX { byte rid; /* Informational Bits - use unsigned int for best compiler compatibility */ #ifndef WOLFTPM2_NO_WOLFCRYPT - #ifndef WOLFTPM_NO_LOCK - unsigned int hwLockInit:1; - #endif #ifndef WC_NO_RNG unsigned int rngInit:1; #endif From ac800d3820507c742560db851de6cfadeef527cd Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 29 Apr 2025 22:10:00 -0700 Subject: [PATCH 2/4] Fix no `WOLFSSL_MUTEX_INITIALIZER` case. --- src/tpm2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tpm2.c b/src/tpm2.c index 9129632..407e2a7 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -493,8 +493,9 @@ static inline int TPM2_WolfCrypt_Init(void) if (rc == 0) rc = wc_SetSeed_Cb(wc_GenerateSeed); #endif - #ifndef WOLFSSL_MUTEX_INITIALIZER - wc_InitMutex(&gHwMutex); + #if !defined(WOLFTPM_NO_LOCK) && !defined(SINGLE_THREADED) && \ + !defined(WOLFSSL_MUTEX_INITIALIZER) + wc_InitMutex(&gHwLock); #endif } gWolfCryptRefCount++; @@ -693,8 +694,9 @@ TPM_RC TPM2_Cleanup(TPM2_CTX* ctx) if (gWolfCryptRefCount < 0) gWolfCryptRefCount = 0; if (gWolfCryptRefCount == 0) { - #ifndef WOLFSSL_MUTEX_INITIALIZER - wc_FreeMutex(&gHwMutex); + #if !defined(WOLFTPM_NO_LOCK) && !defined(SINGLE_THREADED) && \ + !defined(WOLFSSL_MUTEX_INITIALIZER) + wc_FreeMutex(&gHwLock); #endif wolfCrypt_Cleanup(); } From e7aad1ac22b2902d46f94dc949794f5bbebec374 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 2 May 2025 12:48:24 -0700 Subject: [PATCH 3/4] Support for pthread static mutex when building against older wolfSSL versions (like 5.6.6). --- wolftpm/tpm2_types.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h index d7f4ccd..678e172 100644 --- a/wolftpm/tpm2_types.h +++ b/wolftpm/tpm2_types.h @@ -234,6 +234,20 @@ typedef int64_t INT64; #endif #endif +/* if using older wolfSSL that does not have the pthread mutex initializer */ +#ifndef WOLFSSL_MUTEX_INITIALIZER + #if defined(WOLFSSL_PTHREADS) + #define WOLFSSL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + #endif +#endif +#ifndef WOLFSSL_MUTEX_INITIALIZER_CLAUSE + #ifdef WOLFSSL_MUTEX_INITIALIZER + #define WOLFSSL_MUTEX_INITIALIZER_CLAUSE(lockname) = WOLFSSL_MUTEX_INITIALIZER + #else + #define WOLFSSL_MUTEX_INITIALIZER_CLAUSE(lockname) /* null expansion */ + #endif +#endif + #ifndef WOLFTPM_CUSTOM_TYPES #include From f2e6be4e16192a41768d22774b0a94a70118721a Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 2 May 2025 12:53:48 -0700 Subject: [PATCH 4/4] Add build option `WOLFTPM_NO_ACTIVE_THREAD_LS` to remove thread local on `gActiveTPM`. --- src/tpm2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tpm2.c b/src/tpm2.c index 407e2a7..0ead8c3 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -37,7 +37,14 @@ /* --- Local Variables -- */ /******************************************************************************/ + +#ifdef WOLFTPM_NO_ACTIVE_THREAD_LS +/* if using gHwLock and want to use a shared active TPM2_CTX between threads */ +static TPM2_CTX* gActiveTPM; +#else static THREAD_LS_T TPM2_CTX* gActiveTPM; +#endif + #ifndef WOLFTPM2_NO_WOLFCRYPT static volatile int gWolfCryptRefCount = 0; #endif