libtpmtss: Protect TPM 2.0 context by mutex

Each private key object created to access a key residing in a TPM 2.0
creates a context structure used for communication with the TSS.
When multiple IKE SAs are established at the same time and using the
same private key, it is possible to make concurrent calls to the
TSS with the same context which results in multiple threads writing
to the same place in memory causing undefined behaviour.

Fix this by protecting calls to the TSS with a mutex unique for
each TPM 2.0 context object.
This commit is contained in:
krinfels
2019-06-26 16:30:01 +02:00
committed by Andreas Steffen
parent 07a6e59b1c
commit 4b25885025
2 changed files with 78 additions and 4 deletions
+39 -2
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2018 Tobias Brunner * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2016-2018 Andreas Steffen * Copyright (C) 2016-2019 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
#include <asn1/asn1.h> #include <asn1/asn1.h>
#include <asn1/oid.h> #include <asn1/oid.h>
#include <bio/bio_reader.h> #include <bio/bio_reader.h>
#include <threading/mutex.h>
#include <tpm20.h> #include <tpm20.h>
@@ -75,6 +76,11 @@ struct private_tpm_tss_tss2_t {
*/ */
bool fips_186_4; 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; int written;
/* get fixed properties */ /* get fixed properties */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES,
PT_FIXED, MAX_TPM_PROPERTIES, &more_data, &cap_data, 0); PT_FIXED, MAX_TPM_PROPERTIES, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_TPM_PROPERTIES: 0x%06x", 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" : "")); fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
/* get supported algorithms */ /* get supported algorithms */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS,
0, TPM_PT_ALGORITHM_SET, &more_data, &cap_data, 0); 0, TPM_PT_ALGORITHM_SET, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_ALGS: 0x%06x", 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); DBG2(DBG_PTS, "%s algorithms:%s", LABEL, buf);
/* get supported ECC curves */ /* get supported ECC curves */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ECC_CURVES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ECC_CURVES,
0, TPM_PT_LOADED_CURVES, &more_data, &cap_data, 0); 0, TPM_PT_LOADED_CURVES, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM_ECC_CURVES: 0x%06x", 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; sessions_data.rspAuthsCount = 1;
/* read public key for a given object handle from TPM 2.0 NVRAM */ /* 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, rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name,
&qualified_name, &sessions_data); &qualified_name, &sessions_data);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x", 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)); memset(&pcr_values, 0, sizeof(TPML_DIGEST));
/* read the PCR value */ /* read the PCR value */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection, rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection,
&pcr_update_counter, &pcr_selection, &pcr_values, 0); &pcr_update_counter, &pcr_selection, &pcr_values, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x", 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 */ /* extend PCR */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &sessions_data_cmd, rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &sessions_data_cmd,
&digest_values, &sessions_data_rsp); &digest_values, &sessions_data_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x", DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x",
@@ -866,9 +884,11 @@ METHOD(tpm_tss_t, quote, bool,
return FALSE; return FALSE;
} }
this->mutex->lock(this->mutex);
rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &sessions_data_cmd, rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &sessions_data_cmd,
&qualifying_data, &scheme, &pcr_selection, &quoted, &qualifying_data, &scheme, &pcr_selection, &quoted,
&sig, &sessions_data_rsp); &sig, &sessions_data_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval); 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); memcpy(buffer.t.buffer, data.ptr, data.len);
buffer.t.size = data.len; buffer.t.size = data.len;
this->mutex->lock(this->mutex);
rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy, rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy,
&hash, &validation, 0); &hash, &validation, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Hash failed: 0x%06x", LABEL, rval); 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; TPM2B_AUTH null_auth;
null_auth.t.size = 0; null_auth.t.size = 0;
this->mutex->lock(this->mutex);
rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth, rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth,
alg_id, &sequence_handle, 0); alg_id, &sequence_handle, 0);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x", DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x",
LABEL, rval); LABEL, rval);
this->mutex->unlock(this->mutex);
return FALSE; return FALSE;
} }
@@ -1083,6 +1107,7 @@ METHOD(tpm_tss_t, sign, bool,
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x", DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x",
LABEL, rval); LABEL, rval);
this->mutex->unlock(this->mutex);
return FALSE; return FALSE;
} }
} }
@@ -1091,6 +1116,7 @@ METHOD(tpm_tss_t, sign, bool,
rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle, rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle,
&sessions_data_cmd, &buffer, hierarchy, &sessions_data_cmd, &buffer, hierarchy,
&hash, &validation, 0); &hash, &validation, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_SequenceComplete failed: 0x%06x", 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, rval = Tss2_Sys_Sign(this->sys_context, handle, &sessions_data_cmd, &hash,
&sig_scheme, &validation, &sig, &sessions_data_rsp); &sig_scheme, &validation, &sig, &sessions_data_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Sign failed: 0x%06x", LABEL, rval); 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); len = min(bytes, random_len);
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL); rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL);
this->mutex->unlock(this->mutex);
if (rval != TSS2_RC_SUCCESS) if (rval != TSS2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_GetRandom failed: 0x%06x", LABEL, rval); 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]; TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
/* query maximum TPM data transmission size */ /* query maximum TPM data transmission size */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES,
TPM_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0); TPM_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for " DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for "
@@ -1216,8 +1248,10 @@ METHOD(tpm_tss_t, get_data, bool,
MAX_NV_BUFFER_SIZE); MAX_NV_BUFFER_SIZE);
/* get size of NV object */ /* get size of NV object */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public, rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public,
&nv_name, 0); &nv_name, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval); 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 */ /* read NV data a maximum data size block at a time */
while (nv_size > 0) while (nv_size > 0)
{ {
this->mutex->lock(this->mutex);
rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle, rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle,
&sessions_data_cmd, min(nv_size, max_data_size), &sessions_data_cmd, min(nv_size, max_data_size),
nv_offset, &nv_data, &sessions_data_rsp); nv_offset, &nv_data, &sessions_data_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM_RC_SUCCESS) if (rval != TPM_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval); 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) private_tpm_tss_tss2_t *this)
{ {
finalize_context(this); finalize_context(this);
this->mutex->destroy(this->mutex);
free(this); free(this);
} }
@@ -1300,6 +1336,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.get_data = _get_data, .get_data = _get_data,
.destroy = _destroy, .destroy = _destroy,
}, },
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
); );
available = initialize_tcti_tabrmd_context(this); available = initialize_tcti_tabrmd_context(this);
+39 -2
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2018 Tobias Brunner * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2018 Andreas Steffen * Copyright (C) 2018-2019 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
#include <asn1/asn1.h> #include <asn1/asn1.h>
#include <asn1/oid.h> #include <asn1/oid.h>
#include <bio/bio_reader.h> #include <bio/bio_reader.h>
#include <threading/mutex.h>
#include <tss2/tss2_sys.h> #include <tss2/tss2_sys.h>
@@ -71,6 +72,11 @@ struct private_tpm_tss_tss2_t {
*/ */
bool fips_186_4; 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; int written;
/* get fixed properties */ /* get fixed properties */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES,
TPM2_PT_FIXED, TPM2_MAX_TPM_PROPERTIES, TPM2_PT_FIXED, TPM2_MAX_TPM_PROPERTIES,
&more_data, &cap_data, 0); &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_TPM_PROPERTIES: 0x%06x", 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" : "")); fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
/* get supported algorithms */ /* get supported algorithms */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ALGS, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ALGS,
0, TPM2_PT_ALGORITHM_SET, &more_data, &cap_data, 0); 0, TPM2_PT_ALGORITHM_SET, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_ALGS: 0x%06x", 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); DBG2(DBG_PTS, "%s algorithms:%s", LABEL, buf);
/* get supported ECC curves */ /* get supported ECC curves */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ECC_CURVES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ECC_CURVES,
0, TPM2_PT_LOADED_CURVES, &more_data, &cap_data, 0); 0, TPM2_PT_LOADED_CURVES, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s GetCapability failed for TPM2_ECC_CURVES: 0x%06x", 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 */ /* 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, rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name,
&qualified_name, &auth_rsp); &qualified_name, &auth_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x", 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)); memset(&pcr_values, 0, sizeof(TPML_DIGEST));
/* read the PCR value */ /* read the PCR value */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection, rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection,
&pcr_update_counter, &pcr_selection, &pcr_values, 0); &pcr_update_counter, &pcr_selection, &pcr_values, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x", 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 */ /* extend PCR */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &auth_cmd, rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &auth_cmd,
&digest_values, &auth_rsp); &digest_values, &auth_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x", DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x",
@@ -786,9 +804,11 @@ METHOD(tpm_tss_t, quote, bool,
return FALSE; return FALSE;
} }
this->mutex->lock(this->mutex);
rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &auth_cmd, rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &auth_cmd,
&qualifying_data, &scheme, &pcr_selection, &quoted, &qualifying_data, &scheme, &pcr_selection, &quoted,
&sig, &auth_rsp); &sig, &auth_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval); 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); memcpy(buffer.buffer, data.ptr, data.len);
buffer.size = data.len; buffer.size = data.len;
this->mutex->lock(this->mutex);
rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy, rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy,
&hash, &validation, 0); &hash, &validation, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Hash failed: 0x%06x", LABEL, rval); 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; TPM2B_AUTH null_auth;
null_auth.size = 0; null_auth.size = 0;
this->mutex->lock(this->mutex);
rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth, rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth,
alg_id, &sequence_handle, 0); alg_id, &sequence_handle, 0);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x", DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x",
LABEL, rval); LABEL, rval);
this->mutex->unlock(this->mutex);
return FALSE; return FALSE;
} }
@@ -987,6 +1011,7 @@ METHOD(tpm_tss_t, sign, bool,
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x", DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x",
LABEL, rval); LABEL, rval);
this->mutex->unlock(this->mutex);
return FALSE; return FALSE;
} }
} }
@@ -995,6 +1020,7 @@ METHOD(tpm_tss_t, sign, bool,
rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle, rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle,
&auth_cmd, &buffer, hierarchy, &auth_cmd, &buffer, hierarchy,
&hash, &validation, 0); &hash, &validation, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_SequenceComplete failed: 0x%06x", 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, rval = Tss2_Sys_Sign(this->sys_context, handle, &auth_cmd, &hash,
&sig_scheme, &validation, &sig, &auth_rsp); &sig_scheme, &validation, &sig, &auth_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_Sign failed: 0x%06x", LABEL, rval); 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); len = min(bytes, random_len);
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL); rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL);
this->mutex->unlock(this->mutex);
if (rval != TSS2_RC_SUCCESS) if (rval != TSS2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_GetRandom failed: 0x%06x", LABEL, rval); 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; TSS2L_SYS_AUTH_RESPONSE auth_rsp;
/* query maximum TPM data transmission size */ /* query maximum TPM data transmission size */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES, rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_TPM_PROPERTIES,
TPM2_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0); TPM2_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for " 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); TPM2_MAX_NV_BUFFER_SIZE);
/* get size of NV object */ /* get size of NV object */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public, rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public,
&nv_name, 0); &nv_name, 0);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval); 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 */ /* read NV data a maximum data size block at a time */
while (nv_size > 0) while (nv_size > 0)
{ {
this->mutex->lock(this->mutex);
rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle, &auth_cmd, rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle, &auth_cmd,
min(nv_size, max_data_size), nv_offset, &nv_data, &auth_rsp); min(nv_size, max_data_size), nv_offset, &nv_data, &auth_rsp);
this->mutex->unlock(this->mutex);
if (rval != TPM2_RC_SUCCESS) if (rval != TPM2_RC_SUCCESS)
{ {
DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval); 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) private_tpm_tss_tss2_t *this)
{ {
finalize_context(this); finalize_context(this);
this->mutex->destroy(this->mutex);
free(this); free(this);
} }
@@ -1187,6 +1223,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.get_data = _get_data, .get_data = _get_data,
.destroy = _destroy, .destroy = _destroy,
}, },
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
); );
available = initialize_tcti_context(this); available = initialize_tcti_context(this);