mirror of https://github.com/wolfSSL/wolfTPM.git
Merge pull request #417 from dgarske/tpm_threadls
Improve active TPM thread mutex and possible mutex recursionpull/368/merge
commit
761cb4adea
|
@ -79,11 +79,41 @@ check_function_exists("gettimeofday" HAVE_GETTIMEOFDAY)
|
|||
# * wait state
|
||||
# * small stack
|
||||
|
||||
# Single threaded
|
||||
set(WOLFTPM_SINGLE_THREADED "no" CACHE STRING
|
||||
"Enable wolfTPM single threaded (default: disabled)")
|
||||
set_property(CACHE WOLFTPM_SINGLE_THREADED
|
||||
PROPERTY STRINGS "yes;no")
|
||||
if(WOLFTPM_SINGLE_THREADED)
|
||||
list(APPEND WOLFTPM_DEFINITIONS
|
||||
"-DSINGLE_THREADED")
|
||||
endif()
|
||||
|
||||
# Mutex locking
|
||||
set(WOLFTPM_NO_LOCK "no" CACHE STRING
|
||||
"Enable thread mutex locking (default: enabled)")
|
||||
set_property(CACHE WOLFTPM_NO_LOCK
|
||||
PROPERTY STRINGS "yes;no")
|
||||
if(NOT WOLFTPM_NO_LOCK)
|
||||
list(APPEND WOLFTPM_DEFINITIONS
|
||||
"-DWOLFTPM_NO_LOCK")
|
||||
endif()
|
||||
|
||||
# Active TPM - Thread local storage
|
||||
set(WOLFTPM_NO_ACTIVE_THREAD_LS "no" CACHE STRING
|
||||
"Disable active TPM thread local storage (default: disabled)")
|
||||
set_property(CACHE WOLFTPM_NO_ACTIVE_THREAD_LS
|
||||
PROPERTY STRINGS "yes;no")
|
||||
if(NOT WOLFTPM_NO_ACTIVE_THREAD_LS)
|
||||
list(APPEND WOLFTPM_DEFINITIONS
|
||||
"-DWOLFTPM_NO_ACTIVE_THREAD_LS")
|
||||
endif()
|
||||
|
||||
# Provisioning
|
||||
set(WOLFTPM_PROVISIONING "yes" CACHE STRING
|
||||
"Enable support for Provisioning Initial Device Identity (IDevID) and Attestation Identity Keys (default: enabled)")
|
||||
set_property(CACHE WOLFTPM_PROVISIONING
|
||||
PROPERTY STRINGS "yes;no;verbose")
|
||||
PROPERTY STRINGS "yes;no")
|
||||
if(WOLFTPM_PROVISIONING)
|
||||
list(APPEND WOLFTPM_DEFINITIONS
|
||||
"-DWOLFTPM_PROVISIONING")
|
||||
|
|
|
@ -378,7 +378,7 @@ run_tpm_tls_client() { # Usage: run_tpm_tls_client [ecc/rsa] [tpmargs] [tlsversi
|
|||
generate_port
|
||||
pushd $WOLFSSL_PATH >> $TPMPWD/run.out 2>&1
|
||||
echo -e "./examples/server/server -v $3 -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem"
|
||||
./examples/server/server -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem &> $TPMPWD/run.out &
|
||||
./examples/server/server -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem >> $TPMPWD/run.out 2>&1 &
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "tls server $1 $2 failed! $RESULT" && exit 1
|
||||
popd >> $TPMPWD/run.out 2>&1
|
||||
|
|
|
@ -535,7 +535,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
|
|||
rc = wolfSSL_CTX_use_certificate_file(ctx, useCert, WOLFSSL_FILETYPE_PEM);
|
||||
#endif
|
||||
if (rc != WOLFSSL_SUCCESS) {
|
||||
#ifndef NO_FILESYSTEM
|
||||
#if !defined(NO_FILESYSTEM) && !defined(WOLFTPM_MFG_IDENTITY)
|
||||
printf("Error loading ECC client cert: %s\n", useCert);
|
||||
#else
|
||||
printf("Error loading ECC client cert\n");
|
||||
|
|
102
src/tpm2.c
102
src/tpm2.c
|
@ -37,23 +37,26 @@
|
|||
/* --- 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
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_NO_LOCK) && \
|
||||
!defined(SINGLE_THREADED)
|
||||
/* if a mutex lock is supported, then don't use thread local on gActiveTPM */
|
||||
#undef WOLFTPM_NO_ACTIVE_THREAD_LS
|
||||
#define WOLFTPM_NO_ACTIVE_THREAD_LS
|
||||
|
||||
static wolfSSL_Mutex gHwLock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gHwLock);
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#ifdef WOLFTPM_LINUX_DEV
|
||||
#define INTERNAL_SEND_COMMAND TPM2_LINUX_SendCommand
|
||||
#define TPM2_INTERNAL_CLEANUP(ctx)
|
||||
|
@ -160,7 +163,7 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
|
|||
|
||||
if (session->sessionHandle != TPM_RS_PW) {
|
||||
/* Generate fresh nonce */
|
||||
rc = TPM2_GetNonce(session->nonceCaller.buffer,
|
||||
rc = TPM2_GetNonceNoLock(session->nonceCaller.buffer,
|
||||
session->nonceCaller.size);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
return rc;
|
||||
|
@ -5464,6 +5467,7 @@ TPM_RC TPM2_GetProductInfo(uint8_t* info, uint16_t size)
|
|||
size = packet.size - 26;
|
||||
XMEMCPY(info, &packet.buf[25], size);
|
||||
}
|
||||
TPM2_ReleaseLock(ctx);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -5686,9 +5690,7 @@ int TPM2_GetHashType(TPMI_ALG_HASH hashAlg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Can optionally define WOLFTPM2_USE_HW_RNG to force using TPM hardware for
|
||||
* RNG source */
|
||||
int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
|
||||
int TPM2_GetNonceNoLock(byte* nonceBuf, int nonceSz)
|
||||
{
|
||||
int rc;
|
||||
TPM2_CTX* ctx = TPM2_GetActiveCtx();
|
||||
|
@ -5717,44 +5719,58 @@ int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
|
|||
#else
|
||||
/* Call GetRandom directly, so a custom packet buffer can be used.
|
||||
* This won't conflict when being called from TPM2_CommandProcess. */
|
||||
rc = TPM2_AcquireLock(ctx);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
while (randSz < nonceSz) {
|
||||
UINT16 inSz = nonceSz - randSz, outSz = 0;
|
||||
if (inSz > MAX_RNG_REQ_SIZE) {
|
||||
inSz = MAX_RNG_REQ_SIZE;
|
||||
}
|
||||
|
||||
TPM2_Packet_InitBuf(&packet, buffer, (int)sizeof(buffer));
|
||||
TPM2_Packet_AppendU16(&packet, inSz);
|
||||
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetRandom);
|
||||
rc = TPM2_SendCommand(ctx, &packet);
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("TPM2_GetNonce (%d bytes at %d): %d (%s)\n",
|
||||
inSz, randSz, rc, TPM2_GetRCString(rc));
|
||||
#endif
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
TPM2_Packet_ParseU16(&packet, &outSz);
|
||||
if (outSz > MAX_RNG_REQ_SIZE) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_GetNonce out size error\n");
|
||||
#endif
|
||||
rc = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
TPM2_Packet_ParseBytes(&packet, &nonceBuf[randSz], outSz);
|
||||
randSz += outSz;
|
||||
while (randSz < nonceSz) {
|
||||
UINT16 inSz = nonceSz - randSz, outSz = 0;
|
||||
if (inSz > MAX_RNG_REQ_SIZE) {
|
||||
inSz = MAX_RNG_REQ_SIZE;
|
||||
}
|
||||
TPM2_ReleaseLock(ctx);
|
||||
|
||||
TPM2_Packet_InitBuf(&packet, buffer, (int)sizeof(buffer));
|
||||
TPM2_Packet_AppendU16(&packet, inSz);
|
||||
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetRandom);
|
||||
rc = TPM2_SendCommand(ctx, &packet);
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("TPM2_GetNonce (%d bytes at %d): %d (%s)\n",
|
||||
inSz, randSz, rc, TPM2_GetRCString(rc));
|
||||
#endif
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
TPM2_Packet_ParseU16(&packet, &outSz);
|
||||
if (outSz > MAX_RNG_REQ_SIZE) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_GetNonce out size error\n");
|
||||
#endif
|
||||
rc = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
TPM2_Packet_ParseBytes(&packet, &nonceBuf[randSz], outSz);
|
||||
randSz += outSz;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
|
||||
{
|
||||
int rc;
|
||||
TPM2_CTX* ctx = TPM2_GetActiveCtx();
|
||||
|
||||
if (ctx == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
rc = TPM2_AcquireLock(ctx);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = TPM2_GetNonceNoLock(nonceBuf, nonceSz);
|
||||
TPM2_ReleaseLock(ctx);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Get name for object/handle */
|
||||
int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name)
|
||||
{
|
||||
|
|
|
@ -1592,7 +1592,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
|
|||
authSesIn.symmetric.algorithm = TPM_ALG_NULL;
|
||||
}
|
||||
authSesIn.nonceCaller.size = hashDigestSz;
|
||||
rc = TPM2_GetNonce(authSesIn.nonceCaller.buffer,
|
||||
rc = TPM2_GetNonceNoLock(authSesIn.nonceCaller.buffer,
|
||||
authSesIn.nonceCaller.size);
|
||||
if (rc < 0) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
|
@ -1604,7 +1604,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
|
|||
if (authSesIn.tpmKey != TPM_RH_NULL) {
|
||||
/* Generate random salt */
|
||||
session->salt.size = hashDigestSz;
|
||||
rc = TPM2_GetNonce(session->salt.buffer, session->salt.size);
|
||||
rc = TPM2_GetNonceNoLock(session->salt.buffer, session->salt.size);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
@ -2481,6 +2481,7 @@ int wolfTPM2_ImportRsaPrivateKeySeed(WOLFTPM2_DEV* dev,
|
|||
TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg, TPMA_OBJECT attributes,
|
||||
byte* seed, word32 seedSz)
|
||||
{
|
||||
int rc = 0;
|
||||
TPM2B_PUBLIC pub;
|
||||
TPM2B_SENSITIVE sens;
|
||||
word32 digestSz;
|
||||
|
@ -2544,11 +2545,13 @@ int wolfTPM2_ImportRsaPrivateKeySeed(WOLFTPM2_DEV* dev,
|
|||
else {
|
||||
/* assign random seed */
|
||||
sens.sensitiveArea.seedValue.size = digestSz;
|
||||
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
|
||||
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
|
||||
sens.sensitiveArea.seedValue.size);
|
||||
}
|
||||
|
||||
return wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
|
||||
if (rc == 0) {
|
||||
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int wolfTPM2_ImportRsaPrivateKey(WOLFTPM2_DEV* dev,
|
||||
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob, const byte* rsaPub,
|
||||
|
@ -2633,6 +2636,7 @@ int wolfTPM2_ImportEccPrivateKeySeed(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* pare
|
|||
const byte* eccPriv, word32 eccPrivSz,
|
||||
TPMA_OBJECT attributes, byte* seed, word32 seedSz)
|
||||
{
|
||||
int rc = 0;
|
||||
TPM2B_PUBLIC pub;
|
||||
TPM2B_SENSITIVE sens;
|
||||
word32 digestSz;
|
||||
|
@ -2696,11 +2700,14 @@ int wolfTPM2_ImportEccPrivateKeySeed(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* pare
|
|||
else {
|
||||
/* assign random seed */
|
||||
sens.sensitiveArea.seedValue.size = digestSz;
|
||||
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
|
||||
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
|
||||
sens.sensitiveArea.seedValue.size);
|
||||
}
|
||||
|
||||
return wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
|
||||
if (rc == 0) {
|
||||
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, &pub, &sens);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wolfTPM2_ImportEccPrivateKey(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
|
||||
|
@ -3234,13 +3241,14 @@ int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
|
|||
else {
|
||||
/* assign random seed */
|
||||
sens.sensitiveArea.seedValue.size = digestSz;
|
||||
TPM2_GetNonce(sens.sensitiveArea.seedValue.buffer,
|
||||
rc = TPM2_GetNonceNoLock(sens.sensitiveArea.seedValue.buffer,
|
||||
sens.sensitiveArea.seedValue.size);
|
||||
}
|
||||
|
||||
|
||||
/* Import Private Key */
|
||||
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, pub, &sens);
|
||||
if (rc == 0) {
|
||||
/* Import Private Key */
|
||||
rc = wolfTPM2_ImportPrivateKey(dev, parentKey, keyBlob, pub, &sens);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFTPM2_PEM_DECODE
|
||||
|
@ -5776,7 +5784,7 @@ int wolfTPM2_ChangeHierarchyAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
|
|||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = TPM2_GetNonce(in.newAuth.buffer, in.newAuth.size);
|
||||
rc = TPM2_GetNonceNoLock(in.newAuth.buffer, in.newAuth.size);
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = TPM2_HierarchyChangeAuth(&in);
|
||||
|
|
|
@ -3434,7 +3434,9 @@ WOLFTPM_API TPMI_ALG_HASH TPM2_GetTpmHashType(int hashType);
|
|||
/*!
|
||||
\ingroup TPM2_Proprietary
|
||||
\brief Generate a fresh nonce of random numbers
|
||||
\note Can use the TPM random number generator if WOLFTPM2_USE_HW_RNG is defined
|
||||
\note Can use the TPM random number generator if WOLFTPM2_USE_HW_RNG is defined.
|
||||
To force use of the TPM's RNG use WOLFTPM2_USE_HW_RNG. Please make sure you
|
||||
have parameter encryption enabled to protect the RNG data over the bus.
|
||||
|
||||
\return TPM_RC_SUCCESS: successful
|
||||
\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);
|
|||
*/
|
||||
WOLFTPM_API int TPM2_GetNonce(byte* nonceBuf, int nonceSz);
|
||||
|
||||
/* Internal API for getting nonce without taking lock */
|
||||
WOLFTPM_LOCAL int TPM2_GetNonceNoLock(byte* nonceBuf, int nonceSz);
|
||||
|
||||
/*!
|
||||
\ingroup TPM2_Proprietary
|
||||
\brief Helper function to prepare a correct PCR selection
|
||||
|
|
Loading…
Reference in New Issue