diff --git a/src/libtpmtss/tpm_tss_tss2_v1.c b/src/libtpmtss/tpm_tss_tss2_v1.c index 1c214afa3..0335fab91 100644 --- a/src/libtpmtss/tpm_tss_tss2_v1.c +++ b/src/libtpmtss/tpm_tss_tss2_v1.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2018 Tobias Brunner - * Copyright (C) 2016-2018 Andreas Steffen + * Copyright (C) 2016-2019 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -75,6 +76,11 @@ struct private_tpm_tss_tss2_t { */ bool fips_186_4; + /** + * Mutex controlling access to the TPM 2.0 context + */ + mutex_t *mutex; + }; /** @@ -168,8 +174,10 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) int written; /* get fixed properties */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES, PT_FIXED, MAX_TPM_PROPERTIES, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_TPM_PROPERTIES: 0x%06x", @@ -222,8 +230,10 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : "")); /* get supported algorithms */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS, 0, TPM_PT_ALGORITHM_SET, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_ALGS: 0x%06x", @@ -251,8 +261,10 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) DBG2(DBG_PTS, "%s algorithms:%s", LABEL, buf); /* get supported ECC curves */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ECC_CURVES, 0, TPM_PT_LOADED_CURVES, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM_ECC_CURVES: 0x%06x", @@ -440,8 +452,10 @@ bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle, sessions_data.rspAuthsCount = 1; /* read public key for a given object handle from TPM 2.0 NVRAM */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name, &qualified_name, &sessions_data); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x", @@ -704,8 +718,10 @@ METHOD(tpm_tss_t, read_pcr, bool, memset(&pcr_values, 0, sizeof(TPML_DIGEST)); /* read the PCR value */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection, &pcr_update_counter, &pcr_selection, &pcr_values, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x", @@ -800,8 +816,10 @@ METHOD(tpm_tss_t, extend_pcr, bool, } /* extend PCR */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &sessions_data_cmd, &digest_values, &sessions_data_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x", @@ -866,9 +884,11 @@ METHOD(tpm_tss_t, quote, bool, return FALSE; } + this->mutex->lock(this->mutex); rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &sessions_data_cmd, &qualifying_data, &scheme, &pcr_selection, "ed, &sig, &sessions_data_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval); @@ -1047,8 +1067,10 @@ METHOD(tpm_tss_t, sign, bool, memcpy(buffer.t.buffer, data.ptr, data.len); buffer.t.size = data.len; + this->mutex->lock(this->mutex); rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy, &hash, &validation, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Hash failed: 0x%06x", LABEL, rval); @@ -1061,12 +1083,14 @@ METHOD(tpm_tss_t, sign, bool, TPM2B_AUTH null_auth; null_auth.t.size = 0; + this->mutex->lock(this->mutex); rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth, alg_id, &sequence_handle, 0); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x", LABEL, rval); + this->mutex->unlock(this->mutex); return FALSE; } @@ -1083,6 +1107,7 @@ METHOD(tpm_tss_t, sign, bool, { DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x", LABEL, rval); + this->mutex->unlock(this->mutex); return FALSE; } } @@ -1091,6 +1116,7 @@ METHOD(tpm_tss_t, sign, bool, rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle, &sessions_data_cmd, &buffer, hierarchy, &hash, &validation, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_SequenceComplete failed: 0x%06x", @@ -1099,8 +1125,10 @@ METHOD(tpm_tss_t, sign, bool, } } + this->mutex->lock(this->mutex); rval = Tss2_Sys_Sign(this->sys_context, handle, &sessions_data_cmd, &hash, &sig_scheme, &validation, &sig, &sessions_data_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Sign failed: 0x%06x", LABEL, rval); @@ -1170,7 +1198,9 @@ METHOD(tpm_tss_t, get_random, bool, { len = min(bytes, random_len); + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL); + this->mutex->unlock(this->mutex); if (rval != TSS2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_GetRandom failed: 0x%06x", LABEL, rval); @@ -1204,8 +1234,10 @@ METHOD(tpm_tss_t, get_data, bool, TPMS_AUTH_RESPONSE *session_data_rsp_array[1]; /* query maximum TPM data transmission size */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES, TPM_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for " @@ -1216,8 +1248,10 @@ METHOD(tpm_tss_t, get_data, bool, MAX_NV_BUFFER_SIZE); /* get size of NV object */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public, &nv_name, 0); + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval); @@ -1252,10 +1286,11 @@ METHOD(tpm_tss_t, get_data, bool, /* read NV data a maximum data size block at a time */ while (nv_size > 0) { + this->mutex->lock(this->mutex); rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle, &sessions_data_cmd, min(nv_size, max_data_size), nv_offset, &nv_data, &sessions_data_rsp); - + this->mutex->unlock(this->mutex); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval); @@ -1274,6 +1309,7 @@ METHOD(tpm_tss_t, destroy, void, private_tpm_tss_tss2_t *this) { finalize_context(this); + this->mutex->destroy(this->mutex); free(this); } @@ -1300,6 +1336,7 @@ tpm_tss_t *tpm_tss_tss2_create() .get_data = _get_data, .destroy = _destroy, }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); available = initialize_tcti_tabrmd_context(this); diff --git a/src/libtpmtss/tpm_tss_tss2_v2.c b/src/libtpmtss/tpm_tss_tss2_v2.c index cac0dd661..e527443fb 100644 --- a/src/libtpmtss/tpm_tss_tss2_v2.c +++ b/src/libtpmtss/tpm_tss_tss2_v2.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2018 Tobias Brunner - * Copyright (C) 2018 Andreas Steffen + * Copyright (C) 2018-2019 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -71,6 +72,11 @@ struct private_tpm_tss_tss2_t { */ bool fips_186_4; + /** + * Mutex controlling access to the TPM 2.0 context + */ + mutex_t *mutex; + }; /** @@ -167,9 +173,11 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) int written; /* get fixed properties */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES, TPM2_PT_FIXED, TPM2_MAX_TPM_PROPERTIES, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_TPM_PROPERTIES: 0x%06x", @@ -222,8 +230,10 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : "")); /* get supported algorithms */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ALGS, 0, TPM2_PT_ALGORITHM_SET, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_ALGS: 0x%06x", @@ -251,8 +261,10 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) DBG2(DBG_PTS, "%s algorithms:%s", LABEL, buf); /* get supported ECC curves */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ECC_CURVES, 0, TPM2_PT_LOADED_CURVES, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s GetCapability failed for TPM2_ECC_CURVES: 0x%06x", @@ -394,8 +406,10 @@ bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle, /* read public key for a given object handle from TPM 2.0 NVRAM */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name, &qualified_name, &auth_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x", @@ -658,8 +672,10 @@ METHOD(tpm_tss_t, read_pcr, bool, memset(&pcr_values, 0, sizeof(TPML_DIGEST)); /* read the PCR value */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection, &pcr_update_counter, &pcr_selection, &pcr_values, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x", @@ -737,8 +753,10 @@ METHOD(tpm_tss_t, extend_pcr, bool, } /* extend PCR */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &auth_cmd, &digest_values, &auth_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x", @@ -786,9 +804,11 @@ METHOD(tpm_tss_t, quote, bool, return FALSE; } + this->mutex->lock(this->mutex); rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &auth_cmd, &qualifying_data, &scheme, &pcr_selection, "ed, &sig, &auth_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval); @@ -951,8 +971,10 @@ METHOD(tpm_tss_t, sign, bool, memcpy(buffer.buffer, data.ptr, data.len); buffer.size = data.len; + this->mutex->lock(this->mutex); rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy, &hash, &validation, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Hash failed: 0x%06x", LABEL, rval); @@ -965,12 +987,14 @@ METHOD(tpm_tss_t, sign, bool, TPM2B_AUTH null_auth; null_auth.size = 0; + this->mutex->lock(this->mutex); rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth, alg_id, &sequence_handle, 0); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x", LABEL, rval); + this->mutex->unlock(this->mutex); return FALSE; } @@ -987,6 +1011,7 @@ METHOD(tpm_tss_t, sign, bool, { DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x", LABEL, rval); + this->mutex->unlock(this->mutex); return FALSE; } } @@ -995,6 +1020,7 @@ METHOD(tpm_tss_t, sign, bool, rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle, &auth_cmd, &buffer, hierarchy, &hash, &validation, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_SequenceComplete failed: 0x%06x", @@ -1003,8 +1029,10 @@ METHOD(tpm_tss_t, sign, bool, } } + this->mutex->lock(this->mutex); rval = Tss2_Sys_Sign(this->sys_context, handle, &auth_cmd, &hash, &sig_scheme, &validation, &sig, &auth_rsp); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_Sign failed: 0x%06x", LABEL, rval); @@ -1074,7 +1102,9 @@ METHOD(tpm_tss_t, get_random, bool, { len = min(bytes, random_len); + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL); + this->mutex->unlock(this->mutex); if (rval != TSS2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_GetRandom failed: 0x%06x", LABEL, rval); @@ -1105,8 +1135,10 @@ METHOD(tpm_tss_t, get_data, bool, TSS2L_SYS_AUTH_RESPONSE auth_rsp; /* query maximum TPM data transmission size */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES, TPM2_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for " @@ -1117,8 +1149,10 @@ METHOD(tpm_tss_t, get_data, bool, TPM2_MAX_NV_BUFFER_SIZE); /* get size of NV object */ + this->mutex->lock(this->mutex); rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public, &nv_name, 0); + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval); @@ -1140,9 +1174,10 @@ METHOD(tpm_tss_t, get_data, bool, /* read NV data a maximum data size block at a time */ while (nv_size > 0) { + this->mutex->lock(this->mutex); rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle, &auth_cmd, min(nv_size, max_data_size), nv_offset, &nv_data, &auth_rsp); - + this->mutex->unlock(this->mutex); if (rval != TPM2_RC_SUCCESS) { DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval); @@ -1161,6 +1196,7 @@ METHOD(tpm_tss_t, destroy, void, private_tpm_tss_tss2_t *this) { finalize_context(this); + this->mutex->destroy(this->mutex); free(this); } @@ -1187,6 +1223,7 @@ tpm_tss_t *tpm_tss_tss2_create() .get_data = _get_data, .destroy = _destroy, }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); available = initialize_tcti_context(this);