Skip to content

Commit 761cb4a

Browse files
authored
Merge pull request #417 from dgarske/tpm_threadls
Improve active TPM thread mutex and possible mutex recursion
2 parents 5770675 + c364166 commit 761cb4a

6 files changed

Lines changed: 116 additions & 57 deletions

File tree

CMakeLists.txt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,41 @@ check_function_exists("gettimeofday" HAVE_GETTIMEOFDAY)
7979
# * wait state
8080
# * small stack
8181

82+
# Single threaded
83+
set(WOLFTPM_SINGLE_THREADED "no" CACHE STRING
84+
"Enable wolfTPM single threaded (default: disabled)")
85+
set_property(CACHE WOLFTPM_SINGLE_THREADED
86+
PROPERTY STRINGS "yes;no")
87+
if(WOLFTPM_SINGLE_THREADED)
88+
list(APPEND WOLFTPM_DEFINITIONS
89+
"-DSINGLE_THREADED")
90+
endif()
91+
92+
# Mutex locking
93+
set(WOLFTPM_NO_LOCK "no" CACHE STRING
94+
"Enable thread mutex locking (default: enabled)")
95+
set_property(CACHE WOLFTPM_NO_LOCK
96+
PROPERTY STRINGS "yes;no")
97+
if(NOT WOLFTPM_NO_LOCK)
98+
list(APPEND WOLFTPM_DEFINITIONS
99+
"-DWOLFTPM_NO_LOCK")
100+
endif()
101+
102+
# Active TPM - Thread local storage
103+
set(WOLFTPM_NO_ACTIVE_THREAD_LS "no" CACHE STRING
104+
"Disable active TPM thread local storage (default: disabled)")
105+
set_property(CACHE WOLFTPM_NO_ACTIVE_THREAD_LS
106+
PROPERTY STRINGS "yes;no")
107+
if(NOT WOLFTPM_NO_ACTIVE_THREAD_LS)
108+
list(APPEND WOLFTPM_DEFINITIONS
109+
"-DWOLFTPM_NO_ACTIVE_THREAD_LS")
110+
endif()
111+
82112
# Provisioning
83113
set(WOLFTPM_PROVISIONING "yes" CACHE STRING
84114
"Enable support for Provisioning Initial Device Identity (IDevID) and Attestation Identity Keys (default: enabled)")
85115
set_property(CACHE WOLFTPM_PROVISIONING
86-
PROPERTY STRINGS "yes;no;verbose")
116+
PROPERTY STRINGS "yes;no")
87117
if(WOLFTPM_PROVISIONING)
88118
list(APPEND WOLFTPM_DEFINITIONS
89119
"-DWOLFTPM_PROVISIONING")

examples/run_examples.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ run_tpm_tls_client() { # Usage: run_tpm_tls_client [ecc/rsa] [tpmargs] [tlsversi
378378
generate_port
379379
pushd $WOLFSSL_PATH >> $TPMPWD/run.out 2>&1
380380
echo -e "./examples/server/server -v $3 -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem"
381-
./examples/server/server -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem &> $TPMPWD/run.out &
381+
./examples/server/server -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem >> $TPMPWD/run.out 2>&1 &
382382
RESULT=$?
383383
[ $RESULT -ne 0 ] && echo -e "tls server $1 $2 failed! $RESULT" && exit 1
384384
popd >> $TPMPWD/run.out 2>&1

examples/tls/tls_server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
535535
rc = wolfSSL_CTX_use_certificate_file(ctx, useCert, WOLFSSL_FILETYPE_PEM);
536536
#endif
537537
if (rc != WOLFSSL_SUCCESS) {
538-
#ifndef NO_FILESYSTEM
538+
#if !defined(NO_FILESYSTEM) && !defined(WOLFTPM_MFG_IDENTITY)
539539
printf("Error loading ECC client cert: %s\n", useCert);
540540
#else
541541
printf("Error loading ECC client cert\n");

src/tpm2.c

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,26 @@
3737
/* --- Local Variables -- */
3838
/******************************************************************************/
3939

40-
41-
#ifdef WOLFTPM_NO_ACTIVE_THREAD_LS
42-
/* if using gHwLock and want to use a shared active TPM2_CTX between threads */
43-
static TPM2_CTX* gActiveTPM;
44-
#else
45-
static THREAD_LS_T TPM2_CTX* gActiveTPM;
46-
#endif
47-
4840
#ifndef WOLFTPM2_NO_WOLFCRYPT
4941
static volatile int gWolfCryptRefCount = 0;
5042
#endif
5143

5244
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_NO_LOCK) && \
5345
!defined(SINGLE_THREADED)
46+
/* if a mutex lock is supported, then don't use thread local on gActiveTPM */
47+
#undef WOLFTPM_NO_ACTIVE_THREAD_LS
48+
#define WOLFTPM_NO_ACTIVE_THREAD_LS
49+
5450
static wolfSSL_Mutex gHwLock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gHwLock);
5551
#endif
5652

53+
#ifdef WOLFTPM_NO_ACTIVE_THREAD_LS
54+
/* if using gHwLock and want to use a shared active TPM2_CTX between threads */
55+
static TPM2_CTX* gActiveTPM;
56+
#else
57+
static THREAD_LS_T TPM2_CTX* gActiveTPM;
58+
#endif
59+
5760
#ifdef WOLFTPM_LINUX_DEV
5861
#define INTERNAL_SEND_COMMAND TPM2_LINUX_SendCommand
5962
#define TPM2_INTERNAL_CLEANUP(ctx)
@@ -160,7 +163,7 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
160163

161164
if (session->sessionHandle != TPM_RS_PW) {
162165
/* Generate fresh nonce */
163-
rc = TPM2_GetNonce(session->nonceCaller.buffer,
166+
rc = TPM2_GetNonceNoLock(session->nonceCaller.buffer,
164167
session->nonceCaller.size);
165168
if (rc != TPM_RC_SUCCESS) {
166169
return rc;
@@ -5464,6 +5467,7 @@ TPM_RC TPM2_GetProductInfo(uint8_t* info, uint16_t size)
54645467
size = packet.size - 26;
54655468
XMEMCPY(info, &packet.buf[25], size);
54665469
}
5470+
TPM2_ReleaseLock(ctx);
54675471
}
54685472
return rc;
54695473
}
@@ -5686,9 +5690,7 @@ int TPM2_GetHashType(TPMI_ALG_HASH hashAlg)
56865690
return 0;
56875691
}
56885692

5689-
/* Can optionally define WOLFTPM2_USE_HW_RNG to force using TPM hardware for
5690-
* RNG source */
5691-
int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
5693+
int TPM2_GetNonceNoLock(byte* nonceBuf, int nonceSz)
56925694
{
56935695
int rc;
56945696
TPM2_CTX* ctx = TPM2_GetActiveCtx();
@@ -5717,44 +5719,58 @@ int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
57175719
#else
57185720
/* Call GetRandom directly, so a custom packet buffer can be used.
57195721
* This won't conflict when being called from TPM2_CommandProcess. */
5720-
rc = TPM2_AcquireLock(ctx);
5721-
if (rc == TPM_RC_SUCCESS) {
5722-
while (randSz < nonceSz) {
5723-
UINT16 inSz = nonceSz - randSz, outSz = 0;
5724-
if (inSz > MAX_RNG_REQ_SIZE) {
5725-
inSz = MAX_RNG_REQ_SIZE;
5726-
}
5722+
while (randSz < nonceSz) {
5723+
UINT16 inSz = nonceSz - randSz, outSz = 0;
5724+
if (inSz > MAX_RNG_REQ_SIZE) {
5725+
inSz = MAX_RNG_REQ_SIZE;
5726+
}
57275727

5728-
TPM2_Packet_InitBuf(&packet, buffer, (int)sizeof(buffer));
5729-
TPM2_Packet_AppendU16(&packet, inSz);
5730-
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetRandom);
5731-
rc = TPM2_SendCommand(ctx, &packet);
5732-
#ifdef WOLFTPM_DEBUG_VERBOSE
5733-
printf("TPM2_GetNonce (%d bytes at %d): %d (%s)\n",
5734-
inSz, randSz, rc, TPM2_GetRCString(rc));
5735-
#endif
5736-
if (rc != TPM_RC_SUCCESS) {
5737-
break;
5738-
}
5728+
TPM2_Packet_InitBuf(&packet, buffer, (int)sizeof(buffer));
5729+
TPM2_Packet_AppendU16(&packet, inSz);
5730+
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetRandom);
5731+
rc = TPM2_SendCommand(ctx, &packet);
5732+
#ifdef WOLFTPM_DEBUG_VERBOSE
5733+
printf("TPM2_GetNonce (%d bytes at %d): %d (%s)\n",
5734+
inSz, randSz, rc, TPM2_GetRCString(rc));
5735+
#endif
5736+
if (rc != TPM_RC_SUCCESS) {
5737+
break;
5738+
}
57395739

5740-
TPM2_Packet_ParseU16(&packet, &outSz);
5741-
if (outSz > MAX_RNG_REQ_SIZE) {
5742-
#ifdef DEBUG_WOLFTPM
5743-
printf("TPM2_GetNonce out size error\n");
5744-
#endif
5745-
rc = BAD_FUNC_ARG;
5746-
break;
5747-
}
5748-
TPM2_Packet_ParseBytes(&packet, &nonceBuf[randSz], outSz);
5749-
randSz += outSz;
5740+
TPM2_Packet_ParseU16(&packet, &outSz);
5741+
if (outSz > MAX_RNG_REQ_SIZE) {
5742+
#ifdef DEBUG_WOLFTPM
5743+
printf("TPM2_GetNonce out size error\n");
5744+
#endif
5745+
rc = BAD_FUNC_ARG;
5746+
break;
57505747
}
5751-
TPM2_ReleaseLock(ctx);
5748+
TPM2_Packet_ParseBytes(&packet, &nonceBuf[randSz], outSz);
5749+
randSz += outSz;
57525750
}
57535751
#endif
57545752

57555753
return rc;
57565754
}
57575755

5756+
int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
5757+
{
5758+
int rc;
5759+
TPM2_CTX* ctx = TPM2_GetActiveCtx();
5760+
5761+
if (ctx == NULL) {
5762+
return BAD_FUNC_ARG;
5763+
}
5764+
5765+
rc = TPM2_AcquireLock(ctx);
5766+
if (rc == TPM_RC_SUCCESS) {
5767+
rc = TPM2_GetNonceNoLock(nonceBuf, nonceSz);
5768+
TPM2_ReleaseLock(ctx);
5769+
}
5770+
5771+
return rc;
5772+
}
5773+
57585774
/* Get name for object/handle */
57595775
int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name)
57605776
{

src/tpm2_wrap.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,7 +1592,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
15921592
authSesIn.symmetric.algorithm = TPM_ALG_NULL;
15931593
}
15941594
authSesIn.nonceCaller.size = hashDigestSz;
1595-
rc = TPM2_GetNonce(authSesIn.nonceCaller.buffer,
1595+
rc = TPM2_GetNonceNoLock(authSesIn.nonceCaller.buffer,
15961596
authSesIn.nonceCaller.size);
15971597
if (rc < 0) {
15981598
#ifdef DEBUG_WOLFTPM
@@ -1604,7 +1604,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
16041604
if (authSesIn.tpmKey != TPM_RH_NULL) {
16051605
/* Generate random salt */
16061606
session->salt.size = hashDigestSz;
1607-
rc = TPM2_GetNonce(session->salt.buffer, session->salt.size);
1607+
rc = TPM2_GetNonceNoLock(session->salt.buffer, session->salt.size);
16081608
if (rc != 0) {
16091609
return rc;
16101610
}
@@ -2481,6 +2481,7 @@ int wolfTPM2_ImportRsaPrivateKeySeed(WOLFTPM2_DEV* dev,
24812481
TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg, TPMA_OBJECT attributes,
24822482
byte* seed, word32 seedSz)
24832483
{
2484+
int rc = 0;
24842485
TPM2B_PUBLIC pub;
24852486
TPM2B_SENSITIVE sens;
24862487
word32 digestSz;
@@ -2544,11 +2545,13 @@ int wolfTPM2_ImportRsaPrivateKeySeed(WOLFTPM2_DEV* dev,
25442545
else {
25452546
/* assign random seed */
25462547
sens.sensitiveArea.seedValue.size = digestSz;
2547-
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
2548+
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
25482549
sens.sensitiveArea.seedValue.size);
25492550
}
2550-
2551-
return wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
2551+
if (rc == 0) {
2552+
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
2553+
}
2554+
return rc;
25522555
}
25532556
int wolfTPM2_ImportRsaPrivateKey(WOLFTPM2_DEV* dev,
25542557
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob, const byte* rsaPub,
@@ -2633,6 +2636,7 @@ int wolfTPM2_ImportEccPrivateKeySeed(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* pare
26332636
const byte* eccPriv, word32 eccPrivSz,
26342637
TPMA_OBJECT attributes, byte* seed, word32 seedSz)
26352638
{
2639+
int rc = 0;
26362640
TPM2B_PUBLIC pub;
26372641
TPM2B_SENSITIVE sens;
26382642
word32 digestSz;
@@ -2696,11 +2700,14 @@ int wolfTPM2_ImportEccPrivateKeySeed(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* pare
26962700
else {
26972701
/* assign random seed */
26982702
sens.sensitiveArea.seedValue.size = digestSz;
2699-
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
2703+
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
27002704
sens.sensitiveArea.seedValue.size);
27012705
}
27022706

2703-
return wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
2707+
if (rc == 0) {
2708+
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
2709+
}
2710+
return rc;
27042711
}
27052712

27062713
int wolfTPM2_ImportEccPrivateKey(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
@@ -3234,13 +3241,14 @@ int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
32343241
else {
32353242
/* assign random seed */
32363243
sens.sensitiveArea.seedValue.size = digestSz;
3237-
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
3244+
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
32383245
sens.sensitiveArea.seedValue.size);
32393246
}
32403247

3241-
3242-
/* Import Private Key */
3243-
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, pub, &sens);
3248+
if (rc == 0) {
3249+
/* Import Private Key */
3250+
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, pub, &sens);
3251+
}
32443252
}
32453253

32463254
#ifdef WOLFTPM2_PEM_DECODE
@@ -5776,7 +5784,7 @@ int wolfTPM2_ChangeHierarchyAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
57765784
}
57775785
}
57785786
if (rc == 0) {
5779-
rc = TPM2_GetNonce(in.newAuth.buffer, in.newAuth.size);
5787+
rc = TPM2_GetNonceNoLock(in.newAuth.buffer, in.newAuth.size);
57805788
}
57815789
if (rc == 0) {
57825790
rc = TPM2_HierarchyChangeAuth(&in);

wolftpm/tpm2.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3434,7 +3434,9 @@ WOLFTPM_API TPMI_ALG_HASH TPM2_GetTpmHashType(int hashType);
34343434
/*!
34353435
\ingroup TPM2_Proprietary
34363436
\brief Generate a fresh nonce of random numbers
3437-
\note Can use the TPM random number generator if WOLFTPM2_USE_HW_RNG is defined
3437+
\note Can use the TPM random number generator if WOLFTPM2_USE_HW_RNG is defined.
3438+
To force use of the TPM's RNG use WOLFTPM2_USE_HW_RNG. Please make sure you
3439+
have parameter encryption enabled to protect the RNG data over the bus.
34383440
34393441
\return TPM_RC_SUCCESS: successful
34403442
\return TPM_RC_FAILURE: generic failure (TPM IO issue or wolfcrypt configuration)
@@ -3456,6 +3458,9 @@ WOLFTPM_API TPMI_ALG_HASH TPM2_GetTpmHashType(int hashType);
34563458
*/
34573459
WOLFTPM_API int TPM2_GetNonce(byte* nonceBuf, int nonceSz);
34583460

3461+
/* Internal API for getting nonce without taking lock */
3462+
WOLFTPM_LOCAL int TPM2_GetNonceNoLock(byte* nonceBuf, int nonceSz);
3463+
34593464
/*!
34603465
\ingroup TPM2_Proprietary
34613466
\brief Helper function to prepare a correct PCR selection

0 commit comments

Comments
 (0)