summaryrefslogtreecommitdiff
path: root/src/libtpmtss/tpm_tss_tss2.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2018-02-19 18:17:21 +0100
committerYves-Alexis Perez <corsac@corsac.net>2018-02-19 18:17:21 +0100
commit7793611ee71b576dd9c66dee327349fa64e38740 (patch)
treef1379ec1aed52a3c772874d4ed690b90975b9623 /src/libtpmtss/tpm_tss_tss2.c
parente1d78dc2faaa06e7c3f71ef674a71e4de2f0758e (diff)
downloadvyos-strongswan-7793611ee71b576dd9c66dee327349fa64e38740.tar.gz
vyos-strongswan-7793611ee71b576dd9c66dee327349fa64e38740.zip
New upstream version 5.6.2
Diffstat (limited to 'src/libtpmtss/tpm_tss_tss2.c')
-rw-r--r--src/libtpmtss/tpm_tss_tss2.c209
1 files changed, 205 insertions, 4 deletions
diff --git a/src/libtpmtss/tpm_tss_tss2.c b/src/libtpmtss/tpm_tss_tss2.c
index 4c0d95fe5..8b91fb44a 100644
--- a/src/libtpmtss/tpm_tss_tss2.c
+++ b/src/libtpmtss/tpm_tss_tss2.c
@@ -150,14 +150,56 @@ static bool is_supported_alg(private_tpm_tss_tss2_t *this, TPM_ALG_ID alg_id)
static bool get_algs_capability(private_tpm_tss_tss2_t *this)
{
TPMS_CAPABILITY_DATA cap_data;
+ TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM_ALG_ID alg;
- uint32_t rval, i;
+ uint32_t rval, i, offset, revision = 0, year = 0;
size_t len = BUF_LEN;
- char buf[BUF_LEN];
+ char buf[BUF_LEN], manufacturer[5], vendor_string[17];
char *pos = buf;
int written;
+ /* get fixed properties */
+ rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES,
+ PT_FIXED, MAX_TPM_PROPERTIES, &more_data, &cap_data, 0);
+ if (rval != TPM_RC_SUCCESS)
+ {
+ DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_TPM_PROPERTIES: 0x%06x",
+ LABEL, rval);
+ return FALSE;
+ }
+ memset(manufacturer, '\0', sizeof(manufacturer));
+ memset(vendor_string, '\0', sizeof(vendor_string));
+
+ /* print fixed properties */
+ for (i = 0; i < cap_data.data.tpmProperties.count; i++)
+ {
+ tp = cap_data.data.tpmProperties.tpmProperty[i];
+ switch (tp.property)
+ {
+ case TPM_PT_REVISION:
+ revision = tp.value;
+ break;
+ case TPM_PT_YEAR:
+ year = tp.value;
+ break;
+ case TPM_PT_MANUFACTURER:
+ htoun32(manufacturer, tp.value);
+ break;
+ case TPM_PT_VENDOR_STRING_1:
+ case TPM_PT_VENDOR_STRING_2:
+ case TPM_PT_VENDOR_STRING_3:
+ case TPM_PT_VENDOR_STRING_4:
+ offset = 4 * (tp.property - TPM_PT_VENDOR_STRING_1);
+ htoun32(vendor_string + offset, tp.value);
+ break;
+ default:
+ break;
+ }
+ }
+ DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u", LABEL, manufacturer,
+ vendor_string, (float)revision/100, year);
+
/* get supported algorithms */
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS,
0, TPM_PT_ALGORITHM_SET, &more_data, &cap_data, 0);
@@ -433,6 +475,7 @@ METHOD(tpm_tss_t, get_public, chunk_t,
{
DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key "
"failed", LABEL);
+ return chunk_empty;
}
break;
}
@@ -563,8 +606,93 @@ METHOD(tpm_tss_t, extend_pcr, bool,
private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value,
chunk_t data, hash_algorithm_t alg)
{
- /* TODO */
- return FALSE;
+ uint32_t rval;
+ TPM_ALG_ID alg_id;
+ TPML_DIGEST_VALUES digest_values;
+ TPMS_AUTH_COMMAND session_data_cmd;
+ TPMS_AUTH_RESPONSE session_data_rsp;
+ TSS2_SYS_CMD_AUTHS sessions_data_cmd;
+ TSS2_SYS_RSP_AUTHS sessions_data_rsp;
+ TPMS_AUTH_COMMAND *session_data_cmd_array[1];
+ TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
+
+ session_data_cmd_array[0] = &session_data_cmd;
+ session_data_rsp_array[0] = &session_data_rsp;
+
+ sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
+ sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
+
+ sessions_data_cmd.cmdAuthsCount = 1;
+ sessions_data_rsp.rspAuthsCount = 1;
+
+ session_data_cmd.sessionHandle = TPM_RS_PW;
+ session_data_cmd.hmac.t.size = 0;
+ session_data_cmd.nonce.t.size = 0;
+
+ *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
+
+ /* check if hash algorithm is supported by TPM */
+ alg_id = hash_alg_to_tpm_alg_id(alg);
+ if (!is_supported_alg(this, alg_id))
+ {
+ DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
+ LABEL, hash_algorithm_short_names, alg);
+ return FALSE;
+ }
+
+ digest_values.count = 1;
+ digest_values.digests[0].hashAlg = alg_id;
+
+ switch (alg)
+ {
+ case HASH_SHA1:
+ if (data.len != HASH_SIZE_SHA1)
+ {
+ return FALSE;
+ }
+ memcpy(digest_values.digests[0].digest.sha1, data.ptr,
+ HASH_SIZE_SHA1);
+ break;
+ case HASH_SHA256:
+ if (data.len != HASH_SIZE_SHA256)
+ {
+ return FALSE;
+ }
+ memcpy(digest_values.digests[0].digest.sha256, data.ptr,
+ HASH_SIZE_SHA256);
+ break;
+ case HASH_SHA384:
+ if (data.len != HASH_SIZE_SHA384)
+ {
+ return FALSE;
+ }
+ memcpy(digest_values.digests[0].digest.sha384, data.ptr,
+ HASH_SIZE_SHA384);
+ break;
+ case HASH_SHA512:
+ if (data.len != HASH_SIZE_SHA512)
+ {
+ return FALSE;
+ }
+ memcpy(digest_values.digests[0].digest.sha512, data.ptr,
+ HASH_SIZE_SHA512);
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* extend PCR */
+ rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &sessions_data_cmd,
+ &digest_values, &sessions_data_rsp);
+ if (rval != TPM_RC_SUCCESS)
+ {
+ DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x",
+ LABEL, pcr_num, rval);
+ return FALSE;
+ }
+
+ /* get updated PCR value */
+ return read_pcr(this, pcr_num, pcr_value, alg);
}
METHOD(tpm_tss_t, quote, bool,
@@ -913,6 +1041,78 @@ METHOD(tpm_tss_t, get_random, bool,
return TRUE;
}
+METHOD(tpm_tss_t, get_data, bool,
+ private_tpm_tss_tss2_t *this, uint32_t hierarchy, uint32_t handle,
+ chunk_t pin, chunk_t *data)
+{
+ uint16_t nv_size, nv_offset = 0;
+ uint32_t rval;
+
+ TPM2B_NAME nv_name = { { sizeof(TPM2B_NAME)-2, } };
+ TPM2B_NV_PUBLIC nv_public = { { 0, } };
+ TPM2B_MAX_NV_BUFFER nv_data = { { sizeof(TPM2B_MAX_NV_BUFFER)-2, } };
+ TPMS_AUTH_COMMAND session_data_cmd;
+ TPMS_AUTH_RESPONSE session_data_rsp;
+ TSS2_SYS_CMD_AUTHS sessions_data_cmd;
+ TSS2_SYS_RSP_AUTHS sessions_data_rsp;
+ TPMS_AUTH_COMMAND *session_data_cmd_array[1];
+ TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
+
+ /* get size of NV object */
+ rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public,
+ &nv_name, 0);
+ if (rval != TPM_RC_SUCCESS)
+ {
+ DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval);
+ return FALSE;
+ }
+ nv_size = nv_public.t.nvPublic.dataSize;
+ *data = chunk_alloc(nv_size);
+
+ /*prepare NV read session */
+ session_data_cmd_array[0] = &session_data_cmd;
+ session_data_rsp_array[0] = &session_data_rsp;
+
+ sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
+ sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
+
+ sessions_data_cmd.cmdAuthsCount = 1;
+ sessions_data_rsp.rspAuthsCount = 1;
+
+ session_data_cmd.sessionHandle = TPM_RS_PW;
+ session_data_cmd.nonce.t.size = 0;
+ session_data_cmd.hmac.t.size = 0;
+
+ if (pin.len > 0)
+ {
+ session_data_cmd.hmac.t.size = min(sizeof(session_data_cmd.hmac.t) - 2,
+ pin.len);
+ memcpy(session_data_cmd.hmac.t.buffer, pin.ptr,
+ session_data_cmd.hmac.t.size);
+ }
+ *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
+
+ /* read NV data an NV buffer block at a time */
+ while (nv_size > 0)
+ {
+ rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle,
+ &sessions_data_cmd, min(nv_size, MAX_NV_BUFFER_SIZE),
+ nv_offset, &nv_data, &sessions_data_rsp);
+
+ if (rval != TPM_RC_SUCCESS)
+ {
+ DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval);
+ chunk_free(data);
+ return FALSE;
+ }
+ memcpy(data->ptr + nv_offset, nv_data.t.buffer, nv_data.t.size);
+ nv_offset += nv_data.t.size;
+ nv_size -= nv_data.t.size;
+ }
+
+ return TRUE;
+}
+
METHOD(tpm_tss_t, destroy, void,
private_tpm_tss_tss2_t *this)
{
@@ -939,6 +1139,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.quote = _quote,
.sign = _sign,
.get_random = _get_random,
+ .get_data = _get_data,
.destroy = _destroy,
},
);