aboutsummaryrefslogtreecommitdiff
path: root/libstb/tss
diff options
context:
space:
mode:
Diffstat (limited to 'libstb/tss')
-rw-r--r--libstb/tss/trustedTypes.C927
-rw-r--r--libstb/tss/trustedTypes.H467
-rw-r--r--libstb/tss/trustedbootCmds.C1009
-rw-r--r--libstb/tss/trustedbootCmds.H174
-rw-r--r--libstb/tss/trustedbootUtils.C97
-rw-r--r--libstb/tss/trustedbootUtils.H85
-rw-r--r--libstb/tss/trustedboot_reasoncodes.H95
7 files changed, 2854 insertions, 0 deletions
diff --git a/libstb/tss/trustedTypes.C b/libstb/tss/trustedTypes.C
new file mode 100644
index 0000000..edc0269
--- /dev/null
+++ b/libstb/tss/trustedTypes.C
@@ -0,0 +1,927 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedTypes.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedTypes.C
+ *
+ * @brief Trusted boot type inline functions
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include "trustedboot.H"
+#include "trustedTypes.H"
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ const uint8_t* unmarshalChunk(const uint8_t* i_tpmBuf,
+ size_t * io_tpmBufSize,
+ void* o_chunkPtr,
+ size_t i_chunkSize);
+
+ uint8_t* marshalChunk(uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize,
+ const void* i_chunkPtr,
+ size_t i_chunkSize);
+
+ const uint8_t* unmarshalChunk(const uint8_t* i_tpmBuf,
+ size_t * io_tpmBufSize,
+ void* o_chunkPtr,
+ size_t i_chunkSize)
+ {
+ if (NULL != i_tpmBuf)
+ {
+ if (i_chunkSize > *io_tpmBufSize)
+ {
+ return NULL;
+ }
+ memcpy(o_chunkPtr, i_tpmBuf, i_chunkSize);
+ i_tpmBuf += i_chunkSize;
+ *io_tpmBufSize -= i_chunkSize;
+ }
+ return i_tpmBuf;
+ }
+
+ uint8_t* marshalChunk(uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize,
+ const void* i_chunkPtr,
+ size_t i_chunkSize)
+ {
+ if (NULL != o_tpmBuf)
+ {
+ if ((*io_cmdSize + i_chunkSize) > i_tpmBufSize)
+ {
+ return NULL;
+ }
+ memcpy(o_tpmBuf, i_chunkPtr, i_chunkSize);
+ o_tpmBuf += i_chunkSize;
+ *io_cmdSize += i_chunkSize;
+ }
+ return o_tpmBuf;
+ }
+
+ uint32_t getDigestSize(const TPM_Alg_Id i_algId)
+ {
+ uint32_t ret = 0;
+ switch (i_algId)
+ {
+ case TPM_ALG_SHA1:
+ ret = TPM_ALG_SHA1_SIZE;
+ break;
+ case TPM_ALG_SHA256:
+ ret = TPM_ALG_SHA256_SIZE;
+ break;
+ default:
+ ret = 0;
+ break;
+ };
+ return ret;
+ }
+
+ const uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal(
+ TPML_TAGGED_TPM_PROPERTY* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize)
+ {
+
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->count), sizeof(val->count));
+
+ // Now we know the count as well
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->tpmProperty[0]),
+ sizeof(TPMS_TAGGED_PROPERTY) * val->count);
+
+ return i_tpmBuf;
+ }
+
+ const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val,
+ const uint8_t* i_tpmBuf,
+ size_t * io_tpmBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->capability),
+ sizeof(val->capability));
+
+ switch (val->capability)
+ {
+ case TPM_CAP_TPM_PROPERTIES:
+ {
+ return TPML_TAGGED_TPM_PROPERTY_unmarshal(
+ &(val->data.tpmProperties), i_tpmBuf,
+ io_tpmBufSize);
+ }
+ break;
+ default:
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPMS_CAPABILITY_DATA::unmarshal Unknown capability");
+ return NULL;
+ }
+ break;
+ }
+ return NULL;
+ }
+
+ uint8_t* TPMT_HA_marshal(const TPMT_HA* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->algorithmId), sizeof(val->algorithmId));
+ if (getDigestSize((TPM_Alg_Id)val->algorithmId) == 0)
+ {
+ return NULL;
+ }
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->digest),
+ getDigestSize((TPM_Alg_Id)val->algorithmId));
+ return o_tpmBuf;
+ }
+
+ uint8_t* TPML_DIGEST_VALUES_marshal(const TPML_DIGEST_VALUES* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->count), sizeof(val->count));
+ if (NULL != o_tpmBuf && HASH_COUNT < val->count)
+ {
+ o_tpmBuf = NULL;
+ }
+ else
+ {
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ o_tpmBuf = TPMT_HA_marshal(&(val->digests[idx]),
+ o_tpmBuf,
+ i_tpmBufSize,
+ io_cmdSize);
+ if (NULL == o_tpmBuf)
+ {
+ break;
+ }
+ }
+ }
+ return o_tpmBuf;
+ }
+
+ uint8_t* TPM2_BaseIn_marshal(const TPM2_BaseIn* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t* io_cmdSize)
+ {
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ val, sizeof(TPM2_BaseIn));
+ }
+
+ const uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ if (sizeof(TPM2_BaseOut) > i_outBufSize)
+ {
+ return NULL;
+ }
+ return unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ val, sizeof(TPM2_BaseOut));
+ }
+
+ uint8_t* TPM2_2ByteIn_marshal(const TPM2_2ByteIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->param), sizeof(val->param));
+ }
+
+ uint8_t* TPM2_4ByteIn_marshal(const TPM2_4ByteIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->param), sizeof(val->param));
+ }
+
+ uint8_t* TPM2_GetCapabilityIn_marshal(const TPM2_GetCapabilityIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->capability),
+ sizeof(val->capability));
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->property),
+ sizeof(val->property));
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->propertyCount),
+ sizeof(val->propertyCount));
+ return o_tpmBuf;
+ }
+
+ const uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ // Base has already been unmarshaled
+ if (sizeof(TPM2_GetCapabilityOut) > i_outBufSize)
+ {
+ return NULL;
+ }
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->moreData), sizeof(val->moreData));
+
+ // Capability data block
+ return TPMS_CAPABILITY_DATA_unmarshal(&(val->capData), i_tpmBuf,
+ io_tpmBufSize);
+
+ }
+
+ uint8_t* TPM2_ExtendIn_marshalHandle(const TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ // only marshal the pcr handle in this stage
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->pcrHandle), sizeof(val->pcrHandle));
+ }
+
+ uint8_t* TPM2_ExtendIn_marshalParms(const TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base and handle has already been marshaled
+ return (TPML_DIGEST_VALUES_marshal(&(val->digests), o_tpmBuf,
+ i_tpmBufSize, io_cmdSize));
+ }
+
+ uint8_t* TPMS_PCR_SELECTION_marshal(const TPMS_PCR_SELECTION* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->algorithmId), sizeof(val->algorithmId));
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->sizeOfSelect), sizeof(val->sizeOfSelect));
+
+ if (NULL != o_tpmBuf &&
+ PCR_SELECT_MAX < val->sizeOfSelect)
+ {
+ return NULL;
+ }
+
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ val->pcrSelect, val->sizeOfSelect);
+ return o_tpmBuf;
+ }
+
+ const uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->algorithmId),
+ sizeof(val->algorithmId));
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->sizeOfSelect),
+ sizeof(val->sizeOfSelect));
+ if (NULL != i_tpmBuf &&
+ PCR_SELECT_MAX < val->sizeOfSelect)
+ {
+ return NULL;
+ }
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ val->pcrSelect, val->sizeOfSelect);
+
+ return i_tpmBuf;
+ }
+
+ const uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &val->size, sizeof(val->size));
+ if (NULL != i_tpmBuf &&
+ sizeof(TPMU_HA) < val->size)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM2B_DIGEST::unmarshal invalid size");
+ return NULL;
+ }
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ val->buffer, val->size);
+ return i_tpmBuf;
+
+ }
+
+ const uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->count), sizeof(val->count));
+ if (NULL != i_tpmBuf && HASH_COUNT < val->count)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "TPML_DIGEST::unmarshal invalid count %d", val->count);
+ i_tpmBuf = NULL;
+ }
+ else if (NULL != i_tpmBuf)
+ {
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ i_tpmBuf = TPM2B_DIGEST_unmarshal(&(val->digests[idx]),
+ i_tpmBuf,
+ io_tpmBufSize);
+ if (NULL == i_tpmBuf)
+ {
+ break;
+ }
+ }
+ }
+ return i_tpmBuf;
+
+ }
+
+ uint8_t* TPML_PCR_SELECTION_marshal(const TPML_PCR_SELECTION* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->count), sizeof(val->count));
+ if (NULL != o_tpmBuf && HASH_COUNT < val->count)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "TPML_PCR_SELECTION::marshal invalid count");
+ o_tpmBuf = NULL;
+ }
+ else if (NULL != o_tpmBuf)
+ {
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ o_tpmBuf = TPMS_PCR_SELECTION_marshal(
+ &(val->pcrSelections[idx]),
+ o_tpmBuf,
+ i_tpmBufSize,
+ io_cmdSize);
+ if (NULL == o_tpmBuf)
+ {
+ break;
+ }
+ }
+ }
+ return o_tpmBuf;
+ }
+
+ const uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->count), sizeof(val->count));
+ if (NULL != i_tpmBuf && HASH_COUNT < val->count)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "TPML_PCR_SELECTION::unmarshal invalid count");
+ i_tpmBuf = NULL;
+ }
+ else if (NULL != i_tpmBuf)
+ {
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ i_tpmBuf = TPMS_PCR_SELECTION_unmarshal(
+ &(val->pcrSelections[idx]),
+ i_tpmBuf,
+ io_tpmBufSize);
+ if (NULL == i_tpmBuf)
+ {
+ break;
+ }
+ }
+ }
+ return i_tpmBuf;
+
+ }
+
+ uint8_t* TPM2_PcrReadIn_marshal(const TPM2_PcrReadIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base and handle has already been marshaled
+ return (TPML_PCR_SELECTION_marshal(&(val->pcrSelectionIn), o_tpmBuf,
+ i_tpmBufSize, io_cmdSize));
+ }
+
+ const uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ // Base and handle has already been marshaled
+ if (sizeof(TPM2_PcrReadOut) > i_outBufSize) return NULL;
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(val->pcrUpdateCounter),
+ sizeof(val->pcrUpdateCounter));
+
+ i_tpmBuf = TPML_PCR_SELECTION_unmarshal(&(val->pcrSelectionOut),
+ i_tpmBuf, io_tpmBufSize);
+ i_tpmBuf = TPML_DIGEST_unmarshal(&(val->pcrValues), i_tpmBuf,
+ io_tpmBufSize);
+ return i_tpmBuf;
+
+ }
+
+ uint8_t* TPMS_AUTH_COMMAND_marshal(const TPMS_AUTH_COMMAND* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ val, sizeof(TPMS_AUTH_COMMAND));
+ }
+
+
+ uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf)
+ {
+ uint16_t* field16 = (uint16_t*)i_logBuf;
+ *field16 = htole16(val->algorithmId);
+ i_logBuf += sizeof(uint16_t);
+ memcpy(i_logBuf, &(val->digest),
+ getDigestSize((TPM_Alg_Id)val->algorithmId));
+ i_logBuf += getDigestSize((TPM_Alg_Id)val->algorithmId);
+ return i_logBuf;
+ }
+
+ const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val,
+ const uint8_t* i_tpmBuf, bool* o_err)
+ {
+ size_t size = 0;
+ uint16_t* field16 = NULL;
+
+ do {
+ *o_err = false;
+
+ // algorithmId
+ size = sizeof(val->algorithmId);
+ field16 = (uint16_t*)i_tpmBuf;
+ val->algorithmId = le16toh(*field16);
+ // Ensure a valid count
+ if (val->algorithmId >= TPM_ALG_INVALID_ID)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal()"
+ " invalid algorithmId %d",
+ val->algorithmId);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // digest
+ size = getDigestSize((TPM_Alg_Id)val->algorithmId);
+ // Ensure a valid count
+ if (size >= TPM_ALG_INVALID_SIZE)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal() "
+ "invalid algorithm size of %d for algorithm id %d",
+ (int)size, val->algorithmId);
+ break;
+ }
+
+ memcpy(&(val->digest), i_tpmBuf, size);
+ i_tpmBuf += size;
+ } while(0);
+
+ return i_tpmBuf;
+ }
+
+ size_t TPMT_HA_marshalSize(const TPMT_HA* val)
+ {
+ return (sizeof(val->algorithmId) +
+ getDigestSize((TPM_Alg_Id)(val->algorithmId)));
+ }
+
+#ifdef __cplusplus
+ bool TPMT_HA::operator==(const TPMT_HA& i_rhs) const
+ {
+ size_t digestSize = getDigestSize((TPM_Alg_Id)algorithmId);
+ return (algorithmId == i_rhs.algorithmId) &&
+ (memcmp(&(digest), &(i_rhs.digest), digestSize) == 0);
+ }
+#endif
+
+ size_t TPML_DIGEST_VALUES_marshalSize(const TPML_DIGEST_VALUES* val)
+ {
+ size_t ret = sizeof(val->count);
+ for (size_t idx = 0; (idx < val->count && idx < HASH_COUNT); idx++)
+ {
+ ret += TPMT_HA_marshalSize(&(val->digests[idx]));
+ }
+ return ret;
+ }
+
+ uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ if (HASH_COUNT < val->count)
+ {
+ i_logBuf = NULL;
+ }
+ else
+ {
+ *field32 = htole32(val->count);
+ i_logBuf += sizeof(uint32_t);
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ i_logBuf = TPMT_HA_logMarshal(&(val->digests[idx]), i_logBuf);
+ if (NULL == i_logBuf) break;
+ }
+ }
+ return i_logBuf;
+ }
+
+ const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err)
+ {
+ size_t size = 0;
+ uint32_t* field32 = NULL;
+ do {
+ *o_err = false;
+
+ // count
+ size = sizeof(val->count);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->count = le32toh(*field32);
+ // Ensure a valid count
+ if (val->count > HASH_COUNT)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,"ERROR> "
+ "TPML_DIGEST_VALUES:logUnmarshal() "
+ "invalid digest count %d",
+ val->count);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // Iterate all digests
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ i_tpmBuf = TPMT_HA_logUnmarshal(&(val->digests[idx]),
+ i_tpmBuf, o_err);
+ if (NULL == i_tpmBuf)
+ {
+ break;
+ }
+ }
+ } while(0);
+
+ return i_tpmBuf;
+ }
+
+#ifdef __cplusplus
+ bool TPML_DIGEST_VALUES::operator==(const TPML_DIGEST_VALUES& i_rhs) const
+ {
+ bool result = (count == i_rhs.count);
+ // Iterate all digests
+ for (size_t idx = 0; idx < count; idx++)
+ {
+ result = (result && (digests[idx] == i_rhs.digests[idx]));
+ }
+
+ return result;
+ }
+#endif
+
+ const uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val,
+ const uint8_t* i_tpmBuf,
+ size_t i_bufSize,
+ bool* o_err)
+ {
+ size_t size = 0;
+ uint32_t* field32;
+
+ *o_err = false;
+ do {
+ // Ensure enough space for unmarshalled data
+ if (sizeof(TCG_PCR_EVENT) > i_bufSize)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ break;
+ }
+
+ // pcrIndex
+ size = sizeof(val->pcrIndex);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->pcrIndex = le32toh(*field32);
+ // Ensure a valid pcr index
+ if (val->pcrIndex >= IMPLEMENTATION_PCR)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid pcrIndex %d",
+ val->pcrIndex);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // eventType
+ size = sizeof(val->eventType);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventType = le32toh(*field32);
+ // Ensure a valid event type
+ if (val->eventType == 0 || val->eventType >= EV_INVALID)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventType %d",
+ val->eventType);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // digest
+ size = sizeof(val->digest);
+ memcpy(val->digest, i_tpmBuf, size);
+ i_tpmBuf += size;
+
+ // eventSize
+ size = sizeof(val->eventSize);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventSize = le32toh(*field32);
+ // Ensure a valid eventSize
+ if (val->eventSize >= MAX_TPM_LOG_MSG)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventSize %d",
+ val->eventSize);
+ break;
+ }
+ i_tpmBuf += size;
+
+ memcpy(val->event, i_tpmBuf, val->eventSize);
+ i_tpmBuf += val->eventSize;
+
+ } while(0);
+
+ return i_tpmBuf;
+ }
+
+ uint8_t* TCG_PCR_EVENT_logMarshal(const TCG_PCR_EVENT* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->pcrIndex);
+ i_logBuf += sizeof(uint32_t);
+
+ field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->eventType);
+ i_logBuf += sizeof(uint32_t);
+
+ memcpy(i_logBuf, val->digest, sizeof(val->digest));
+ i_logBuf += sizeof(val->digest);
+
+ field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->eventSize);
+ i_logBuf += sizeof(uint32_t);
+
+ if (val->eventSize > 0)
+ {
+ memcpy(i_logBuf, val->event, val->eventSize);
+ i_logBuf += val->eventSize;
+ }
+ return i_logBuf;
+ }
+
+ size_t TCG_PCR_EVENT_marshalSize(const TCG_PCR_EVENT* val)
+ {
+ return (sizeof(TCG_PCR_EVENT) + val->eventSize - MAX_TPM_LOG_MSG);
+ }
+
+ uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ if (MAX_TPM_LOG_MSG < val->eventSize)
+ {
+ i_logBuf = NULL;
+ }
+ else
+ {
+ *field32 = htole32(val->eventSize);
+ i_logBuf += sizeof(uint32_t);
+
+ memcpy(i_logBuf, val->event, val->eventSize);
+ i_logBuf += val->eventSize;
+ }
+ return i_logBuf;
+ }
+
+ const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err)
+ {
+ size_t size = 0;
+ uint32_t* field32 = NULL;
+ do {
+ *o_err = false;
+
+ // Event size
+ size = sizeof(val->eventSize);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventSize = le32toh(*field32);
+ i_tpmBuf += size;
+
+ // Event
+ size = val->eventSize;
+ if (size > MAX_TPM_LOG_MSG)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ break;
+ }
+ memcpy(&val->event, i_tpmBuf, size);
+ i_tpmBuf += size;
+ } while(0);
+
+ return i_tpmBuf;
+ }
+ size_t TPM_EVENT_FIELD_marshalSize(const TPM_EVENT_FIELD* val)
+ {
+ return (sizeof(val->eventSize) + val->eventSize);
+ }
+
+
+#ifdef __cplusplus
+ bool TPM_EVENT_FIELD::operator==(const TPM_EVENT_FIELD& i_rhs) const
+ {
+ return (eventSize == i_rhs.eventSize) &&
+ (memcmp(event, i_rhs.event, eventSize) == 0);
+ }
+#endif
+
+
+ size_t TCG_PCR_EVENT2_marshalSize(const TCG_PCR_EVENT2* val)
+ {
+ return (sizeof(val->pcrIndex) + sizeof(val->eventType) +
+ TPML_DIGEST_VALUES_marshalSize(&(val->digests)) +
+ TPM_EVENT_FIELD_marshalSize(&(val->event)));
+ }
+
+ uint8_t* TCG_PCR_EVENT2_logMarshal(const TCG_PCR_EVENT2* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ *field32 = htole32(val->pcrIndex);
+ i_logBuf += sizeof(uint32_t);
+ field32 = (uint32_t*)i_logBuf;
+ *field32 = htole32(val->eventType);
+ i_logBuf += sizeof(uint32_t);
+
+ i_logBuf = TPML_DIGEST_VALUES_logMarshal(&(val->digests),i_logBuf);
+ if (NULL != i_logBuf)
+ {
+ i_logBuf = TPM_EVENT_FIELD_logMarshal(&(val->event),i_logBuf);
+ }
+ return i_logBuf;
+ }
+
+ const uint8_t* TCG_PCR_EVENT2_logUnmarshal(TCG_PCR_EVENT2* val,
+ const uint8_t* i_tpmBuf,
+ size_t i_bufSize,
+ bool* o_err)
+ {
+ size_t size = 0;
+ uint32_t* field32 = NULL;
+
+ do {
+ *o_err = false;
+
+ // Ensure enough space for unmarshalled data
+ if (sizeof(TCG_PCR_EVENT2) > i_bufSize)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ break;
+ }
+
+ // pcrIndex
+ size = sizeof(val->pcrIndex);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->pcrIndex = le32toh(*field32);
+ // Ensure a valid pcr index
+ if (val->pcrIndex > IMPLEMENTATION_PCR)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACUCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:"
+ "logUnmarshal() invalid pcrIndex %d",
+ val->pcrIndex);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // eventType
+ size = sizeof(val->eventType);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventType = le32toh(*field32);
+ // Ensure a valid event type
+ if (val->eventType == 0 ||
+ val->eventType >= EV_INVALID)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACUCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:"
+ "logUnmarshal() invalid eventType %d",
+ val->eventType);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // TPML_DIGEST_VALUES
+ i_tpmBuf = TPML_DIGEST_VALUES_logUnmarshal(&(val->digests),
+ i_tpmBuf, o_err);
+ if (i_tpmBuf == NULL)
+ {
+ break;
+ }
+
+ // TPM EVENT FIELD
+ i_tpmBuf = TPM_EVENT_FIELD_logUnmarshal(&(val->event),
+ i_tpmBuf, o_err);
+ if (i_tpmBuf == NULL)
+ {
+ break;
+ }
+ } while(0);
+
+ return i_tpmBuf;
+ }
+
+#ifdef __cplusplus
+ bool TCG_PCR_EVENT2::operator==(const TCG_PCR_EVENT2& i_rhs) const
+ {
+ return (pcrIndex == i_rhs.pcrIndex) &&
+ (eventType == i_rhs.eventType) &&
+ (digests == i_rhs.digests) &&
+ (event == i_rhs.event);
+ }
+} // end TRUSTEDBOOT
+#endif
diff --git a/libstb/tss/trustedTypes.H b/libstb/tss/trustedTypes.H
new file mode 100644
index 0000000..dd42cca
--- /dev/null
+++ b/libstb/tss/trustedTypes.H
@@ -0,0 +1,467 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedTypes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedTypes.H
+ *
+ * @brief Trustedboot TPM Types
+ *
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+#ifndef __TRUSTEDTYPES_H
+#define __TRUSTEDTYPES_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#include <stdint.h>
+#ifdef __HOSTBOOT_MODULE
+#include <builtins.h>
+#include <secureboot/trustedbootif.H>
+#else
+#include "trustedboot.H"
+#define PACKED __attribute__((__packed__))
+#endif
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ /// TPM Algorithm defines
+ typedef enum
+ {
+ TPM_ALG_SHA1 = 0x0004, ///< SHA1 Id
+ TPM_ALG_SHA256 = 0x000B, ///< SHA256 Id
+ TPM_ALG_INVALID_ID ///< Used for error checking
+ } TPM_Alg_Id;
+
+ typedef enum
+ {
+ TPM_ALG_NUM_SUPPORTED = 1, ///< Number of algorithms supported
+ TPM_ALG_SHA1_SIZE = 20, ///< SHA1 digest byte size
+ TPM_ALG_SHA256_SIZE = 32, ///< SHA256 digest byte size
+ TPM_ALG_INVALID_SIZE ///< Used for error checking
+ } TPM_Alg_Sizes;
+
+ /// Common static values
+ enum
+ {
+ MAX_TPM_LOG_MSG = 128, ///< Maximum log message size
+
+ HASH_COUNT = 2, ///< Maximum # of digests
+
+ PCR_SELECT_MAX = (IMPLEMENTATION_PCR+7)/8, ///< PCR selection octet max
+ };
+
+ typedef enum
+ {
+ EV_NO_ACTION = 0x3, ///< Event field contains info
+ EV_SEPARATOR = 0x4, ///< Used to indicate an error
+ EV_ACTION = 0x5, ///< Must extend a PCR
+ EV_INVALID ///< Used for error checking
+ } EventTypes;
+
+ /**
+ * @brief Get the digest size of the selected hash algorithm
+ * @param[in] i_algId Algorith ID to query
+ * @returns digest length in bytes, 0 on invalid algorithm
+ */
+ uint32_t getDigestSize(const TPM_Alg_Id i_algId) __attribute__ ((const));
+
+
+ /// Various static values
+ enum
+ {
+ // TPM Spec supported
+ TPM_SPEC_MAJOR = 2,
+ TPM_SPEC_MINOR = 0,
+ TPM_SPEC_ERRATA = 0,
+ TPM_PLATFORM_SERVER = 1,
+
+ // Command structure tags
+ TPM_ST_NO_SESSIONS = 0x8001, ///< A command with no sess/auth
+ TPM_ST_SESSIONS = 0x8002, ///< A command has sessions
+
+ // Command Codes
+ TPM_CC_Startup = 0x00000144,
+ TPM_CC_GetCapability = 0x0000017A,
+ TPM_CC_PCR_Read = 0x0000017E,
+ TPM_CC_PCR_Extend = 0x00000182,
+
+
+ // TPM Startup types
+ TPM_SU_CLEAR = 0x0000,///< TPM perform reset,restart
+ TPM_SU_STATE = 0x0001,///< TPM perform restore saved state
+
+ // Capability
+ MAX_TPM_PROPERTIES = 2,
+ TPM_CAP_TPM_PROPERTIES = 0x00000006, ///< Pull TPM Properties
+
+ // TPM Properties
+ TPM_PT_MANUFACTURER = 0x00000105,
+ TPM_PT_FIRMWARE_VERSION_1 = 0x0000010B,
+ TPM_PT_FIRMWARE_VERSION_2 = 0x0000010C,
+
+
+ // TPM Return Codes
+ TPM_SUCCESS = 0x000,
+
+ TPM_RC_INITIALIZE = 0x100,
+
+
+ // TPM Authorization types
+ TPM_RS_PW = 0x40000009,
+
+ };
+
+
+ // Command structures taken from Trusted Platform Module Library Part 3:
+ // Commands Family "2.0"
+
+ /// TPM capability response structure
+ struct _TPMS_TAGGED_PROPERTY
+ {
+ uint32_t property; ///< TPM_PT_xx identifier
+ uint32_t value; ///< value of the property
+ } PACKED;
+ typedef struct _TPMS_TAGGED_PROPERTY TPMS_TAGGED_PROPERTY;
+
+ struct _TPML_TAGGED_TPM_PROPERTY
+ {
+ uint32_t count; ///< Number of properties
+ TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
+ } PACKED;
+ typedef struct _TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY;
+ const uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal(
+ TPML_TAGGED_TPM_PROPERTY* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize);
+
+ union _TPMU_CAPABILITIES
+ {
+ // Currently only TPM properties supported
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ } PACKED;
+ typedef union _TPMU_CAPABILITIES TPMU_CAPABILITIES;
+
+ struct _TPMS_CAPABILITY_DATA
+ {
+ uint32_t capability; ///< The capability type
+ TPMU_CAPABILITIES data; ///< The capability data
+ } PACKED;
+ typedef struct _TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA;
+ const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val,
+ const uint8_t* i_tpmBuf,
+ size_t * io_tpmBufSize);
+
+
+ /// SHA1 Event log entry format
+ struct _TCG_PCR_EVENT
+ {
+ uint32_t pcrIndex; ///< PCRIndex event extended to
+ uint32_t eventType; ///< Type of event
+ uint8_t digest[20]; ///< Value extended into PCR index
+ uint32_t eventSize; ///< Size of event data
+ uint8_t event[MAX_TPM_LOG_MSG]; ///< The event data
+ } PACKED;
+ typedef struct _TCG_PCR_EVENT TCG_PCR_EVENT;
+ size_t TCG_PCR_EVENT_marshalSize(const TCG_PCR_EVENT* val);
+ const uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val,
+ const uint8_t* i_tpmBuf,
+ size_t i_bufSize, bool* o_err);
+ uint8_t* TCG_PCR_EVENT_logMarshal(const TCG_PCR_EVENT* val,
+ uint8_t* i_logBuf);
+
+ /// Digest union
+ union _TPMU_HA
+ {
+ uint8_t sha1[TPM_ALG_SHA1_SIZE];
+ uint8_t sha256[TPM_ALG_SHA256_SIZE];
+ } PACKED;
+ typedef union _TPMU_HA TPMU_HA;
+
+ /// Crypto agile digest
+ struct _TPMT_HA
+ {
+ uint16_t algorithmId; ///< ID of hashing algorithm
+ TPMU_HA digest; ///< Digest, depends on algorithmid
+#ifdef __cplusplus
+ bool operator==(const _TPMT_HA& i_rhs) const;
+#endif
+ } PACKED;
+ typedef struct _TPMT_HA TPMT_HA;
+ size_t TPMT_HA_marshalSize(const TPMT_HA* val);
+ uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf);
+ const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val,
+ const uint8_t* i_tpmBuf, bool* o_err);
+ uint8_t* TPMT_HA_marshal(const TPMT_HA* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t * io_cmdSize);
+
+
+ /// Crypto agile digests list
+ struct _TPML_DIGEST_VALUES
+ {
+ uint32_t count; ///< Number of digests
+ TPMT_HA digests[HASH_COUNT]; ///< Digests
+#ifdef __cplusplus
+ bool operator==(const _TPML_DIGEST_VALUES& i_rhs) const;
+#endif
+ } PACKED;
+ typedef struct _TPML_DIGEST_VALUES TPML_DIGEST_VALUES;
+ size_t TPML_DIGEST_VALUES_marshalSize(const TPML_DIGEST_VALUES* val);
+ uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val,
+ uint8_t* i_logBuf);
+ const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err);
+ uint8_t* TPML_DIGEST_VALUES_marshal(const TPML_DIGEST_VALUES* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t * io_cmdSize);
+
+ /// Event field structure
+ struct _TPM_EVENT_FIELD
+ {
+ uint32_t eventSize; ///< Size of event data
+ uint8_t event[MAX_TPM_LOG_MSG]; ///< The event data
+#ifdef __cplusplus
+ bool operator==(const _TPM_EVENT_FIELD& i_rhs) const;
+#endif
+ } PACKED;
+ typedef struct _TPM_EVENT_FIELD TPM_EVENT_FIELD;
+ size_t TPM_EVENT_FIELD_marshalSize(const TPM_EVENT_FIELD* val);
+ uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val,
+ uint8_t* i_logBuf);
+ const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err);
+
+ /// Crypto agile log entry format
+ struct _TCG_PCR_EVENT2
+ {
+ uint32_t pcrIndex; ///< PCRIndex event extended to
+ uint32_t eventType; ///< Type of event
+ TPML_DIGEST_VALUES digests; ///< List of digests extended to PCRIndex
+ TPM_EVENT_FIELD event; ///< Event information
+#ifdef __cplusplus
+ bool operator==(const _TCG_PCR_EVENT2& i_rhs) const;
+#endif
+ } PACKED;
+ typedef struct _TCG_PCR_EVENT2 TCG_PCR_EVENT2;
+ uint8_t* TCG_PCR_EVENT2_logMarshal(const TCG_PCR_EVENT2* val,
+ uint8_t* i_logBuf);
+ const uint8_t* TCG_PCR_EVENT2_logUnmarshal(TCG_PCR_EVENT2* val,
+ const uint8_t* i_tpmBuf,
+ size_t i_bufSize, bool* o_err);
+ size_t TCG_PCR_EVENT2_marshalSize(const TCG_PCR_EVENT2* val);
+
+ struct _TPM2_BaseIn
+ {
+ uint16_t tag; ///< Type TPM_ST_xx
+ uint32_t commandSize; ///< Total # output bytes incl cmdSize & tag
+ uint32_t commandCode; ///< Type TPM_CC_xx
+ } PACKED;
+ typedef struct _TPM2_BaseIn TPM2_BaseIn;
+ uint8_t* TPM2_BaseIn_marshal(const TPM2_BaseIn* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t* io_cmdSize);
+
+ /// Base of all outgoing messages
+ struct _TPM2_BaseOut
+ {
+ uint16_t tag; ///< Type TPM_ST_xx
+ uint32_t responseSize; ///< Total # out bytes incl paramSize & tag
+ uint32_t responseCode; ///< The return code of the operation
+ } PACKED;
+ typedef struct _TPM2_BaseOut TPM2_BaseOut;
+ const uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize, size_t i_outBufSize);
+
+ /// Generic TPM Input Command structure with a 2 byte param
+ struct _TPM2_2ByteIn
+ {
+ TPM2_BaseIn base;
+ uint16_t param;
+ } PACKED;
+ typedef struct _TPM2_2ByteIn TPM2_2ByteIn;
+ uint8_t* TPM2_2ByteIn_marshal(const TPM2_2ByteIn* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t* io_cmdSize);
+
+ /// Generic TPM Input Command structure with a 4 byte param
+ struct _TPM2_4ByteIn
+ {
+ TPM2_BaseIn base;
+ uint32_t param;
+ } PACKED;
+ typedef struct _TPM2_4ByteIn TPM2_4ByteIn;
+ uint8_t* TPM2_4ByteIn_marshal(const TPM2_4ByteIn* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t* io_cmdSize);
+
+
+ /// Generic TPM Output Command structure with a 4 byte return data
+ struct _TPM2_4ByteOut
+ {
+ TPM2_BaseOut base;
+ uint32_t resp;
+ } PACKED;
+ typedef struct _TPM2_4ByteOut TPM2_4ByteOut;
+
+ /// Incoming TPM_GetCapability structure
+ struct _TPM2_GetCapabilityIn
+ {
+ TPM2_BaseIn base;
+ uint32_t capability; ///< group selection
+ uint32_t property; ///< Further definition
+ uint32_t propertyCount; ///< Number of properties to return
+ } PACKED;
+ typedef struct _TPM2_GetCapabilityIn TPM2_GetCapabilityIn;
+ uint8_t* TPM2_GetCapabilityIn_marshal(const TPM2_GetCapabilityIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+
+ /// Outgoing TPM_GetCapability structure
+ struct _TPM2_GetCapabilityOut
+ {
+ TPM2_BaseOut base;
+ uint8_t moreData; ///< Flag to indicate if more values available
+ TPMS_CAPABILITY_DATA capData; ///< The capability response
+ } PACKED;
+ typedef struct _TPM2_GetCapabilityOut TPM2_GetCapabilityOut;
+ const uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize,
+ size_t i_outBufSize);
+
+ /// Incoming TPM_EXTEND structure
+ struct _TPM2_ExtendIn
+ {
+ TPM2_BaseIn base;
+ uint32_t pcrHandle; ///< PCR number to extend
+ TPML_DIGEST_VALUES digests; ///< Values to be extended
+ } PACKED;
+ typedef struct _TPM2_ExtendIn TPM2_ExtendIn;
+ uint8_t* TPM2_ExtendIn_marshalHandle(const TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+ uint8_t* TPM2_ExtendIn_marshalParms(const TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+
+ struct _TPMS_PCR_SELECTION
+ {
+ uint16_t algorithmId; ///< ID of hashing algorithm
+ uint8_t sizeOfSelect; ///< Byte size of pcrSelect array
+ uint8_t pcrSelect[PCR_SELECT_MAX];
+ } PACKED;
+ typedef struct _TPMS_PCR_SELECTION TPMS_PCR_SELECTION;
+ uint8_t* TPMS_PCR_SELECTION_marshal(const TPMS_PCR_SELECTION* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+ const uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize);
+
+
+ struct _TPM2B_DIGEST
+ {
+ uint16_t size;
+ uint8_t buffer[sizeof(TPMU_HA)];
+ } PACKED;
+ typedef struct _TPM2B_DIGEST TPM2B_DIGEST;
+ const uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize);
+
+ struct _TPML_DIGEST
+ {
+ uint32_t count;
+ TPM2B_DIGEST digests[HASH_COUNT];
+ } PACKED;
+ typedef struct _TPML_DIGEST TPML_DIGEST;
+ const uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize);
+
+ struct _TPML_PCR_SELECTION
+ {
+ uint32_t count;
+ TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
+ } PACKED;
+ typedef struct _TPML_PCR_SELECTION TPML_PCR_SELECTION;
+ uint8_t* TPML_PCR_SELECTION_marshal(const TPML_PCR_SELECTION* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+ const uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize);
+
+ /// Incoming PCR_Read structure
+ struct _TPM2_PcrReadIn
+ {
+ TPM2_BaseIn base;
+ TPML_PCR_SELECTION pcrSelectionIn;
+ } PACKED;
+ typedef struct _TPM2_PcrReadIn TPM2_PcrReadIn;
+ uint8_t* TPM2_PcrReadIn_marshal(const TPM2_PcrReadIn* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+
+ /// Outgoing Pcr_Read structure
+ struct _TPM2_PcrReadOut
+ {
+ TPM2_BaseOut base;
+ uint32_t pcrUpdateCounter;
+ TPML_PCR_SELECTION pcrSelectionOut;
+ TPML_DIGEST pcrValues;
+ } PACKED;
+ typedef struct _TPM2_PcrReadOut TPM2_PcrReadOut;
+ const uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val,
+ const uint8_t* i_tpmBuf,
+ size_t* io_tpmBufSize,
+ size_t i_outBufSize);
+
+ /// TPM Authorization structure
+ /// This is not the full structure and only works for PW auth with NULL PW
+ struct _TPMS_AUTH_COMMAND
+ {
+ uint32_t sessionHandle;
+ uint16_t nonceSize; ///< Size of nonce structure, currently 0
+ uint8_t sessionAttributes; ///< Session attributes
+ uint16_t hmacSize; ///< Size of hmac structure, currently 0
+ } PACKED;
+ typedef struct _TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND;
+ uint8_t* TPMS_AUTH_COMMAND_marshal(const TPMS_AUTH_COMMAND* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT namespace
+#endif
+
+#endif
+
diff --git a/libstb/tss/trustedbootCmds.C b/libstb/tss/trustedbootCmds.C
new file mode 100644
index 0000000..f454aca
--- /dev/null
+++ b/libstb/tss/trustedbootCmds.C
@@ -0,0 +1,1009 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedbootCmds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedbootCmds.C
+ *
+ * @brief Trusted boot TPM command interfaces
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <stdlib.h>
+#ifdef __HOSTBOOT_MODULE
+#include <secureboot/trustedboot_reasoncodes.H>
+#else
+#include "trustedboot_reasoncodes.H"
+#endif
+#include "trustedbootCmds.H"
+#include "trustedbootUtils.H"
+#include "trustedboot.H"
+#include "trustedTypes.H"
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+errlHndl_t tpmTransmitCommand(TpmTarget * io_target,
+ uint8_t* io_buffer,
+ size_t i_bufsize )
+{
+ errlHndl_t err = TB_SUCCESS;
+ uint8_t* transmitBuf = NULL;
+ size_t cmdSize = 0;
+ size_t dataSize = 0;
+ TPM2_BaseIn* cmd = (TPM2_BaseIn*)io_buffer;
+ TPM2_BaseOut* resp = (TPM2_BaseOut*)io_buffer;
+
+ TRACUCOMP( g_trac_trustedboot,
+ ">>TPM TRANSMIT CMD START : BufLen %d : %016llx",
+ (int)i_bufsize,
+ *((uint64_t*)io_buffer) );
+
+ do
+ {
+ transmitBuf = (uint8_t*)malloc(MAX_TRANSMIT_SIZE);
+
+ // Marshal the data into a byte array for transfer to the TPM
+ err = tpmMarshalCommandData(cmd,
+ transmitBuf,
+ MAX_TRANSMIT_SIZE,
+ &cmdSize);
+ if (TB_SUCCESS != err)
+ {
+ break;
+ }
+
+ // Send to the TPM
+ dataSize = MAX_TRANSMIT_SIZE;
+ err = tpmTransmit(io_target,
+ transmitBuf,
+ cmdSize,
+ dataSize);
+
+ if (TB_SUCCESS != err)
+ {
+ break;
+ }
+
+ // Unmarshal the response
+ err = tpmUnmarshalResponseData(cmd->commandCode,
+ transmitBuf,
+ dataSize,
+ resp,
+ i_bufsize);
+
+
+ } while ( 0 );
+
+
+ free(transmitBuf);
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmTransmitCommand() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t* o_cmdSize)
+{
+ errlHndl_t err = TB_SUCCESS;
+ uint8_t* sBuf = o_outbuf;
+ uint32_t* sSizePtr = NULL;
+ size_t curSize = 0;
+ int stage = 0;
+ TPM2_BaseIn* baseCmd =
+ (TPM2_BaseIn*)o_outbuf;
+ TPMS_AUTH_COMMAND cmdAuth;
+
+ *o_cmdSize = 0;
+
+ TRACDCOMP( g_trac_trustedboot,
+ ">>tpmMarshalCommandData()" );
+ do
+ {
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM MARSHAL START : BufLen %d : %016llx",
+ (int)i_bufsize,
+ *((uint64_t*)i_cmd) );
+
+ // Start with the command header
+ sBuf = TPM2_BaseIn_marshal(i_cmd, sBuf, i_bufsize, o_cmdSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+
+ // Marshal the handles
+ stage = 1;
+ if (TPM_CC_PCR_Extend == i_cmd->commandCode)
+ {
+ TPM2_ExtendIn* cmdPtr = (TPM2_ExtendIn*)i_cmd;
+ sBuf = TPM2_ExtendIn_marshalHandle(cmdPtr,
+ sBuf,
+ i_bufsize,
+ o_cmdSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+ }
+
+ // Marshal the authorizations
+ stage = 2;
+ if (TPM_CC_PCR_Extend == i_cmd->commandCode)
+ {
+ // Insert a password authorization with a null pw
+ // Make room for the 4 byte size field at the beginning
+ sSizePtr = (uint32_t*)sBuf;
+ sBuf += sizeof(uint32_t);
+ *o_cmdSize += sizeof(uint32_t);
+ i_bufsize -= sizeof(uint32_t);
+ curSize = *o_cmdSize;
+
+ cmdAuth.sessionHandle = TPM_RS_PW;
+ cmdAuth.nonceSize = 0;
+ cmdAuth.sessionAttributes = 0;
+ cmdAuth.hmacSize = 0;
+
+ sBuf = TPMS_AUTH_COMMAND_marshal(&cmdAuth, sBuf, i_bufsize,
+ o_cmdSize);
+
+ if (NULL == sBuf)
+ {
+ break;
+ }
+ // Put in the size of the auth area
+ *sSizePtr = (*o_cmdSize - curSize);
+
+ }
+
+ // Marshal the command parameters
+ stage = 3;
+ switch (i_cmd->commandCode)
+ {
+ // Two byte parm fields
+ case TPM_CC_Startup:
+ {
+ TPM2_2ByteIn* cmdPtr =
+ (TPM2_2ByteIn*)i_cmd;
+ sBuf = TPM2_2ByteIn_marshal(cmdPtr, sBuf,
+ i_bufsize, o_cmdSize);
+ }
+ break;
+
+ case TPM_CC_GetCapability:
+ {
+ TPM2_GetCapabilityIn* cmdPtr =
+ (TPM2_GetCapabilityIn*)i_cmd;
+ sBuf = TPM2_GetCapabilityIn_marshal(cmdPtr,sBuf,
+ i_bufsize, o_cmdSize);
+ }
+ break;
+ case TPM_CC_PCR_Read:
+ {
+ TPM2_PcrReadIn* cmdPtr = (TPM2_PcrReadIn*)i_cmd;
+ sBuf = TPM2_PcrReadIn_marshal(cmdPtr, sBuf,
+ i_bufsize - (sBuf - o_outbuf),
+ o_cmdSize);
+ }
+ break;
+
+ case TPM_CC_PCR_Extend:
+ {
+ TPM2_ExtendIn* cmdPtr = (TPM2_ExtendIn*)i_cmd;
+ sBuf = TPM2_ExtendIn_marshalParms(cmdPtr, sBuf,
+ i_bufsize, o_cmdSize);
+ }
+ break;
+
+ default:
+ {
+ // Command code not supported
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL INVALID COMMAND : %X",
+ i_cmd->commandCode );
+ sBuf = NULL;
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_MARSHAL_INVALID_CMD
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_MARSHALCMDDATA
+ * @userdata1 Command Code
+ * @userdata2 0
+ * @devdesc Unsupported command code during marshal
+ */
+ err = tpmCreateErrorLog(MOD_TPM_MARSHALCMDDATA,
+ RC_TPM_MARSHAL_INVALID_CMD,
+ i_cmd->commandCode,
+ 0);
+ }
+ break;
+ };
+
+ if (TB_SUCCESS != err || NULL == sBuf)
+ {
+ break;
+ }
+
+ // Do a verification that the cmdSize equals what we used
+ if (((size_t)(sBuf - o_outbuf)) != *o_cmdSize)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL MARSHAL SIZE MISMATCH : %d %d",
+ (int)(sBuf - o_outbuf), (int)(*o_cmdSize) );
+ sBuf = NULL;
+ }
+
+ // Lastly now that we know the size update the byte stream
+ baseCmd->commandSize = *o_cmdSize;
+
+ } while ( 0 );
+
+ if (NULL == sBuf && TB_SUCCESS == err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL FAILURE : Stage %d", stage);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_MARSHALING_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_MARSHALCMDDATA
+ * @userdata1 stage
+ * @userdata2 0
+ * @devdesc Marshaling error detected
+ */
+ err = tpmCreateErrorLog(MOD_TPM_MARSHALCMDDATA,
+ RC_TPM_MARSHALING_FAIL,
+ stage,
+ 0 );
+
+ }
+
+ TRACUBIN(g_trac_trustedboot, "Marshal Out",
+ o_outbuf, *o_cmdSize);
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM MARSHAL END : CmdSize: %d : %016llx ",
+ (int)(*o_cmdSize),
+ *((uint64_t*)o_outbuf) );
+
+ TRACDCOMP( g_trac_trustedboot,
+ "<<tpmMarshalCommandData()" );
+
+ return err;
+}
+
+errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize)
+{
+ errlHndl_t err = TB_SUCCESS;
+ const uint8_t* sBuf = i_respBuf;
+ int stage = 0;
+
+ TRACDCOMP( g_trac_trustedboot,
+ ">>tpmUnmarshalResponseData()" );
+
+ do {
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL START : RespBufLen %d : OutBufLen %d",
+ (int)i_respBufSize, (int)i_outBufSize);
+ TRACUBIN(g_trac_trustedboot,"Unmarshal In",
+ i_respBuf, i_respBufSize);
+
+
+ // Start with the response header
+ stage = 1;
+ sBuf = TPM2_BaseOut_unmarshal(o_outBuf, sBuf,
+ &i_respBufSize, i_outBufSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+
+ // If the TPM returned a failure it will not send the rest
+ // Let the caller deal with the RC
+ if (TPM_SUCCESS != o_outBuf->responseCode)
+ {
+ break;
+ }
+
+
+ // Unmarshal the parameters
+ stage = 2;
+ switch (i_commandCode)
+ {
+ // Empty response commands
+ case TPM_CC_Startup:
+ case TPM_CC_PCR_Extend:
+ // Nothing to do
+ break;
+
+ case TPM_CC_GetCapability:
+ {
+ TPM2_GetCapabilityOut* respPtr =
+ (TPM2_GetCapabilityOut*)o_outBuf;
+ sBuf = TPM2_GetCapabilityOut_unmarshal(respPtr, sBuf,
+ &i_respBufSize,
+ i_outBufSize);
+
+ }
+ break;
+
+ case TPM_CC_PCR_Read:
+ {
+ TPM2_PcrReadOut* respPtr = (TPM2_PcrReadOut*)o_outBuf;
+ sBuf = TPM2_PcrReadOut_unmarshal(respPtr, sBuf,
+ &i_respBufSize,
+ i_outBufSize);
+ }
+ break;
+
+ default:
+ {
+ // Command code not supported
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL INVALID COMMAND : %X",
+ i_commandCode );
+ sBuf = NULL;
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_UNMARSHAL_INVALID_CMD
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_UNMARSHALRESPDATA
+ * @userdata1 commandcode
+ * @userdata2 stage
+ * @devdesc Unsupported command code during unmarshal
+ */
+ err = tpmCreateErrorLog(MOD_TPM_UNMARSHALRESPDATA,
+ RC_TPM_UNMARSHAL_INVALID_CMD,
+ i_commandCode,
+ stage);
+ }
+ break;
+ }
+
+
+ } while ( 0 );
+
+ if (NULL == sBuf && TB_SUCCESS == err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL FAILURE : Stage %d", stage);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_UNMARSHALING_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_UNMARSHALRESPDATA
+ * @userdata1 Stage
+ * @userdata2 Remaining response buffer size
+ * @devdesc Unmarshaling error detected
+ */
+ err = tpmCreateErrorLog(MOD_TPM_UNMARSHALRESPDATA,
+ RC_TPM_UNMARSHALING_FAIL,
+ stage,
+ i_respBufSize);
+
+
+
+ }
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL END : %016llx ",
+ *((uint64_t*)o_outBuf) );
+
+ TRACDCOMP( g_trac_trustedboot,
+ "<<tpmUnmarshalResponseData()" );
+
+ return err;
+}
+
+errlHndl_t tpmCmdStartup(TpmTarget* io_target)
+{
+ errlHndl_t err = TB_SUCCESS;
+ uint8_t dataBuf[BUFSIZE];
+
+ TPM2_BaseOut* resp =
+ (TPM2_BaseOut*)(dataBuf);
+
+ TPM2_2ByteIn* cmd =
+ (TPM2_2ByteIn*)(dataBuf);
+
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdStartup()" );
+
+ do
+ {
+ // Send the TPM startup command
+ // Build our command block for a startup
+ memset(dataBuf, 0, sizeof(dataBuf));
+
+
+ cmd->base.tag = TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TPM_CC_Startup;
+ cmd->param = TPM_SU_CLEAR;
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM STARTUP transmit Fail");
+ break;
+
+ }
+ else if (TPM_SUCCESS != resp->responseCode)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM STARTUP OP Fail %X : ",
+ resp->responseCode);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_START_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_STARTUP
+ * @userdata1 responseCode
+ * @userdata2 0
+ * @devdesc Invalid operation type.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_STARTUP,
+ RC_TPM_START_FAIL,
+ resp->responseCode,
+ 0);
+
+ break;
+ }
+
+
+ } while ( 0 );
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmCmdStartup() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target)
+{
+ errlHndl_t err = TB_SUCCESS;
+ uint8_t dataBuf[BUFSIZE];
+ size_t dataSize = BUFSIZE;
+ uint16_t fwVersion[4] = {0xFF, 0xFF, 0xFF, 0xFF};
+ TPM2_GetCapabilityOut* resp =
+ (TPM2_GetCapabilityOut*)dataBuf;
+ TPM2_GetCapabilityIn* cmd =
+ (TPM2_GetCapabilityIn*)dataBuf;
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdGetCapFwVersion()" );
+
+ do
+ {
+
+ // Build our command block for a get capability of the FW version
+ memset(dataBuf, 0, dataSize);
+
+ cmd->base.tag = TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TPM_CC_GetCapability;
+ cmd->capability = TPM_CAP_TPM_PROPERTIES;
+ cmd->property = TPM_PT_FIRMWARE_VERSION_1;
+ cmd->propertyCount = 1;
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP Transmit Fail");
+ break;
+
+ }
+
+ if (TPM_SUCCESS != resp->base.responseCode)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP OP Fail %X Size(%d) ",
+ resp->base.responseCode,
+ (int)dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 responseCode
+ * @userdata2 0
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP_FAIL,
+ resp->base.responseCode,
+ 0);
+
+ break;
+ }
+ else
+ {
+ // Walk the reponse data to pull the high order bytes out
+
+ if (resp->capData.capability != TPM_CAP_TPM_PROPERTIES ||
+ resp->capData.data.tpmProperties.count != 1 ||
+ resp->capData.data.tpmProperties.tpmProperty[0].property !=
+ TPM_PT_FIRMWARE_VERSION_1) {
+
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP FW INVALID DATA "
+ "Cap(%X) Cnt(%X) Prop(%X)",
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.count,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP_FW_INVALID_RESP
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 capability
+ * @userdata2 property
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP_FW_INVALID_RESP,
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+
+ break;
+ }
+ else
+ {
+ fwVersion[0] =
+ (resp->capData.data.
+ tpmProperties.tpmProperty[0].value >> 16);
+ fwVersion[1] =
+ (resp->capData.data.
+ tpmProperties.tpmProperty[0].value & 0xFFFF);
+ }
+
+ }
+
+ // Read part 2 of the version
+ dataSize = BUFSIZE;
+ memset(dataBuf, 0, dataSize);
+
+ cmd->base.tag = TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TPM_CC_GetCapability;
+ cmd->capability = TPM_CAP_TPM_PROPERTIES;
+ cmd->property = TPM_PT_FIRMWARE_VERSION_2;
+ cmd->propertyCount = 1;
+
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 Transmit Fail");
+ break;
+
+ }
+
+ if ((sizeof(TPM2_GetCapabilityOut) > dataSize) ||
+ (TPM_SUCCESS != resp->base.responseCode))
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 OP Fail %X Size(%d) ",
+ resp->base.responseCode,
+ (int)dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP2_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 responseCode
+ * @userdata2 0
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP2_FAIL,
+ resp->base.responseCode,
+ 0);
+
+ break;
+ }
+ else
+ {
+ // Walk the reponse data to pull the high order bytes out
+
+ if (resp->capData.capability != TPM_CAP_TPM_PROPERTIES ||
+ resp->capData.data.tpmProperties.count != 1 ||
+ resp->capData.data.tpmProperties.tpmProperty[0].property !=
+ TPM_PT_FIRMWARE_VERSION_2) {
+
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 FW INVALID DATA "
+ "Cap(%X) Cnt(%X) Prop(%X)",
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.count,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP2_FW_INVALID_RESP
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 capability
+ * @userdata2 property
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP2_FW_INVALID_RESP,
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+ break;
+ }
+ else
+ {
+ fwVersion[2] =
+ (resp->capData.data.tpmProperties.
+ tpmProperty[0].value >> 16);
+ fwVersion[3] =
+ (resp->capData.data.tpmProperties.
+ tpmProperty[0].value & 0xFFFF);
+ }
+ // Trace the response
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP FW Level %d.%d.%d.%d",
+ fwVersion[0],fwVersion[1],fwVersion[2],fwVersion[3]
+ );
+ }
+
+
+ } while ( 0 );
+
+
+ TRACDCOMP( g_trac_trustedboot,
+ "<<tpmCmdGetCapFwVersion() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+
+errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ const uint8_t* i_digest,
+ size_t i_digestSize)
+{
+ return tpmCmdPcrExtend2Hash(io_target, i_pcr,
+ i_algId, i_digest, i_digestSize,
+ TPM_ALG_INVALID_ID, NULL, 0);
+}
+
+errlHndl_t tpmCmdPcrExtend2Hash(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId_1,
+ const uint8_t* i_digest_1,
+ size_t i_digestSize_1,
+ TPM_Alg_Id i_algId_2,
+ const uint8_t* i_digest_2,
+ size_t i_digestSize_2)
+{
+ errlHndl_t err = NULL;
+ uint8_t dataBuf[sizeof(TPM2_ExtendIn)];
+ size_t dataSize = sizeof(dataBuf);
+ size_t fullDigestSize_1 = 0;
+ size_t fullDigestSize_2 = 0;
+ TPM2_BaseOut* resp = (TPM2_BaseOut*)dataBuf;
+ TPM2_ExtendIn* cmd = (TPM2_ExtendIn*)dataBuf;
+
+
+ TRACDCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrExtend2Hash()" );
+ if (NULL == i_digest_2)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrExtend2Hash() Pcr(%d) Alg(%X) DS(%d)",
+ i_pcr, i_algId_1, (int)i_digestSize_1);
+ }
+ else
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrExtend2Hash() Pcr(%d) Alg(%X:%X) DS(%d:%d)",
+ i_pcr, i_algId_1, i_algId_2,
+ (int)i_digestSize_1, (int)i_digestSize_2);
+ }
+
+ do
+ {
+
+ fullDigestSize_1 = getDigestSize(i_algId_1);
+ if (NULL != i_digest_2)
+ {
+ fullDigestSize_2 = getDigestSize(i_algId_2);
+ }
+
+ // Build our command block
+ memset(dataBuf, 0, sizeof(dataBuf));
+
+ // Argument verification
+ if (fullDigestSize_1 == 0 ||
+ NULL == i_digest_1 ||
+ IMPLEMENTATION_PCR < i_pcr ||
+ (NULL != i_digest_2 && fullDigestSize_2 == 0)
+ )
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCR EXTEND ARG FAILURE FDS(%d:%d) DS(%d:%d) "
+ "PCR(%d)",
+ (int)fullDigestSize_1, (int)fullDigestSize_2,
+ (int)i_digestSize_1, (int)i_digestSize_2, i_pcr);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_INVALID_ARGS
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCREXTEND
+ * @userdata1 Digest Ptr
+ * @userdata2[0:15] Full Digest Size 1
+ * @userdata2[16:31] Full Digest Size 2
+ * @userdata2[32:63] PCR
+ * @devdesc Unmarshaling error detected
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCREXTEND,
+ RC_TPM_INVALID_ARGS,
+ (uint64_t)i_digest_1,
+ (fullDigestSize_1 << 48) |
+ (fullDigestSize_2 << 32) |
+ i_pcr);
+ break;
+ }
+
+ // Log the input PCR value
+ TRACUBIN(g_trac_trustedboot, "PCR In",
+ i_digest_1, fullDigestSize_1);
+
+ cmd->base.tag = TPM_ST_SESSIONS;
+ cmd->base.commandCode = TPM_CC_PCR_Extend;
+ cmd->pcrHandle = i_pcr;
+ cmd->digests.count = 1;
+ cmd->digests.digests[0].algorithmId = i_algId_1;
+ memcpy(&(cmd->digests.digests[0].digest), i_digest_1,
+ (i_digestSize_1 < fullDigestSize_1 ?
+ i_digestSize_1 : fullDigestSize_1) );
+ if (NULL != i_digest_2)
+ {
+ cmd->digests.count = 2;
+ cmd->digests.digests[1].algorithmId = i_algId_2;
+ memcpy(&(cmd->digests.digests[1].digest), i_digest_2,
+ (i_digestSize_2 < fullDigestSize_2 ?
+ i_digestSize_2 : fullDigestSize_2));
+ }
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRExtend Transmit Fail");
+ break;
+
+ }
+ else if ((sizeof(TPM2_BaseOut) > dataSize)
+ || (TPM_SUCCESS != resp->responseCode))
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRExtend OP Fail Ret(%X) ExSize(%d) Size(%d) ",
+ resp->responseCode,
+ (int)sizeof(TPM2_BaseOut),
+ (int)dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_COMMAND_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCREXTEND
+ * @userdata1 responseCode
+ * @userdata2 dataSize
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCREXTEND,
+ RC_TPM_COMMAND_FAIL,
+ resp->responseCode,
+ dataSize);
+ break;
+
+ }
+
+ } while ( 0 );
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmCmdPcrExtend() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+
+}
+
+errlHndl_t tpmCmdPcrRead(TpmTarget* io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* o_digest,
+ size_t i_digestSize)
+{
+ errlHndl_t err = NULL;
+ uint8_t dataBuf[sizeof(TPM2_PcrReadOut)];
+ size_t dataSize = sizeof(dataBuf);
+ size_t fullDigestSize = 0;
+ TPM2_PcrReadOut* resp = (TPM2_PcrReadOut*)dataBuf;
+ TPM2_PcrReadIn* cmd = (TPM2_PcrReadIn*)dataBuf;
+
+
+ TRACDCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrRead()" );
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrRead() Pcr(%d) DS(%d)",
+ i_pcr, (int)i_digestSize);
+
+ do
+ {
+
+ fullDigestSize = getDigestSize(i_algId);
+
+ // Build our command block
+ memset(dataBuf, 0, sizeof(dataBuf));
+
+ // Argument verification
+ if (fullDigestSize > i_digestSize ||
+ NULL == o_digest ||
+ IMPLEMENTATION_PCR < i_pcr
+ )
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCR READ ARG FAILURE FDS(%d) DS(%d) PCR(%d)",
+ (int)fullDigestSize, (int)i_digestSize, i_pcr);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_INVALID_ARGS
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCRREAD
+ * @userdata1 Digest Ptr
+ * @userdata2[0:31] Full Digest Size
+ * @userdata2[32:63] PCR
+ * @devdesc Unmarshaling error detected
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCRREAD,
+ RC_TPM_INVALID_ARGS,
+ (uint64_t)o_digest,
+ (fullDigestSize << 32) |
+ i_pcr);
+
+ break;
+ }
+
+ cmd->base.tag = TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TPM_CC_PCR_Read;
+ cmd->pcrSelectionIn.count = 1; // One algorithm
+ cmd->pcrSelectionIn.pcrSelections[0].algorithmId = i_algId;
+ cmd->pcrSelectionIn.pcrSelections[0].sizeOfSelect = PCR_SELECT_MAX;
+ memset(cmd->pcrSelectionIn.pcrSelections[0].pcrSelect, 0,
+ sizeof(cmd->pcrSelectionIn.pcrSelections[0].pcrSelect));
+ cmd->pcrSelectionIn.pcrSelections[0].pcrSelect[i_pcr / 8] =
+ 0x01 << (i_pcr % 8);
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRRead Transmit Fail ");
+ break;
+
+ }
+ else if ((sizeof(TPM2_BaseOut) > dataSize) ||
+ (TPM_SUCCESS != resp->base.responseCode) ||
+ (resp->pcrValues.count != 1) ||
+ (resp->pcrValues.digests[0].size != fullDigestSize))
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRRead OP Fail Ret(%X) ExSize(%d) "
+ "Size(%d) Cnt(%d) DSize(%d)",
+ resp->base.responseCode,
+ (int)sizeof(TPM2_BaseOut),
+ (int)dataSize,
+ resp->pcrValues.count,
+ resp->pcrValues.digests[0].size);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_COMMAND_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCRREAD
+ * @userdata1 responseCode
+ * @userdata2 dataSize
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCRREAD,
+ RC_TPM_COMMAND_FAIL,
+ resp->base.responseCode,
+ dataSize);
+ break;
+ }
+ else
+ {
+
+ memcpy(o_digest, resp->pcrValues.digests[0].buffer, fullDigestSize);
+
+ // Log the PCR value
+ TRACUBIN(g_trac_trustedboot, "PCR Out",
+ o_digest, fullDigestSize);
+
+ }
+
+ } while ( 0 );
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmCmdPcrRead() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+
+}
+
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT
+#endif
diff --git a/libstb/tss/trustedbootCmds.H b/libstb/tss/trustedbootCmds.H
new file mode 100644
index 0000000..1f03eeb
--- /dev/null
+++ b/libstb/tss/trustedbootCmds.H
@@ -0,0 +1,174 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedbootCmds.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedbootCmds.H
+ *
+ * @brief Trustedboot TPM command interfaces
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+#ifndef __TRUSTEDBOOTCMDS_H
+#define __TRUSTEDBOOTCMDS_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#ifdef __HOSTBOOT_MODULE
+#include <secureboot/trustedbootif.H>
+#endif
+#include "trustedboot.H"
+#include "trustedTypes.H"
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+enum
+{
+ BUFSIZE = 256,
+ MAX_TRANSMIT_SIZE = 1024, ///< Maximum send/receive transmit size
+};
+
+/**
+ * @brief Transmit the command to the TPM and perform marshaling
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in/out] io_buffer Input the command buffer to send, response on exit
+ * @param[in] i_bufsize Size of io_buffer in bytes
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmTransmitCommand(TpmTarget* io_target,
+ uint8_t* io_buffer,
+ size_t i_bufsize );
+
+/**
+ * @brief Take structure pointed to by cmd and format for input into TPM
+ * @param[in] i_cmd Prefilled command input structure
+ * @param[out] o_outbuf Buffer to place marshalled data
+ * @param[in] i_bufsize Size of o_outbuf in bytes
+ * @param[out] o_cmdSize Byte size of io_outbuf data after marshal
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t* o_cmdSize);
+
+/**
+ * @brief Take structure pointed to by cmd and format for input into TPM
+ * @param[in] i_commandCode Command code that was executed on the TPM
+ * @param[in] i_respBuf Buffer with response data from TPM
+ * @param[in] i_respBufSize Byte size of respBuf buffer from TPM
+ * @param[out] o_outBuf Buffer to place formatted response data
+ * @param[in] i_outBufSize Byte size of o_outBuf buffer
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize);
+/**
+ * @brief Send the TPM_STARTUP command to the targetted TPM
+ * @param[in/out] io_target Current TPM target structure
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t tpmCmdStartup(TpmTarget* io_target);
+
+/**
+ * @brief Send the TPM_GETCAPABILITY command to read FW version from TPM
+ * @param[in/out] io_target Current TPM target structure
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+
+errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target);
+
+/**
+ * @brief Send the TPM_Extend command to the targeted TPM and log
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in] i_pcr PCR to write to
+ * @param[in] i_algId Algorithm to use
+ * @param[in] i_digest Digest value to write to PCR, zeros appended as needed
+ * @param[in] i_digestSize Byte size of i_digest array
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ const uint8_t* i_digest,
+ size_t i_digestSize);
+
+/**
+ * @brief Send the TPM_Extend command to the targeted TPM and log
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in] i_pcr PCR to write to
+ * @param[in] i_algId_1 Algorithm to use
+ * @param[in] i_digest_1 Digest value to write to PCR, zeros appended as needed
+ * @param[in] i_digestSize_1 Byte size of i_digest_1 array
+ * @param[in] i_algId_2 Algorithm to use
+ * @param[in] i_digest_2 Digest value to write to PCR, zeros appended as needed
+ * NULL if second digest not used
+ * @param[in] i_digestSize_2 Byte size of i_digest_2 array
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmCmdPcrExtend2Hash(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId_1,
+ const uint8_t* i_digest_1,
+ size_t i_digestSize_1,
+ TPM_Alg_Id i_algId_2,
+ const uint8_t* i_digest_2,
+ size_t i_digestSize_2);
+
+/**
+ * @brief Send the TPM_Read command to the targeted TPM and log
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in] i_pcr PCR to read from
+ * @param[in] i_algId Algorithm back to read from
+ * @param[out] o_digest Array to store PCR contents
+ * @param[in] i_digestSize Byte size of i_digest array
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmCmdPcrRead(TpmTarget* io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* o_digest,
+ size_t i_digestSize);
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT namespace
+#endif
+
+#endif
diff --git a/libstb/tss/trustedbootUtils.C b/libstb/tss/trustedbootUtils.C
new file mode 100644
index 0000000..9091503
--- /dev/null
+++ b/libstb/tss/trustedbootUtils.C
@@ -0,0 +1,97 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedbootUtils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedbootUtils.C
+ *
+ * @brief Trusted boot utility functions
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <sys/time.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludstring.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/driverif.H>
+#include <i2c/tpmddif.H>
+#include <secureboot/trustedbootif.H>
+#include <i2c/tpmddreasoncodes.H>
+#include <secureboot/trustedboot_reasoncodes.H>
+#include "trustedbootUtils.H"
+#include "trustedbootCmds.H"
+#include "trustedboot.H"
+#include "trustedTypes.H"
+
+
+namespace TRUSTEDBOOT
+{
+
+errlHndl_t tpmTransmit(TpmTarget * io_target,
+ uint8_t* io_buffer,
+ size_t i_cmdSize,
+ size_t i_bufsize )
+{
+ errlHndl_t err = NULL;
+
+ do
+ {
+ // Send to the TPM
+ err = deviceRead(io_target->tpmTarget,
+ io_buffer,
+ i_bufsize,
+ DEVICE_TPM_ADDRESS(TPMDD::TPM_OP_TRANSMIT,
+ i_cmdSize));
+ if (NULL != err)
+ {
+ break;
+ }
+
+
+ } while ( 0 );
+
+ return err;
+}
+
+errlHndl_t tpmCreateErrorLog(const uint8_t i_modId,
+ const uint16_t i_reasonCode,
+ const uint64_t i_user1,
+ const uint64_t i_user2)
+{
+ errlHndl_t err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ i_modId,
+ i_reasonCode,
+ i_user1,
+ i_user2,
+ true /*Add HB SW Callout*/ );
+ err->collectTrace( SECURE_COMP_NAME );
+ return err;
+}
+
+} // end TRUSTEDBOOT
diff --git a/libstb/tss/trustedbootUtils.H b/libstb/tss/trustedbootUtils.H
new file mode 100644
index 0000000..73bc387
--- /dev/null
+++ b/libstb/tss/trustedbootUtils.H
@@ -0,0 +1,85 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedbootUtils.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedbootUtils.H
+ *
+ * @brief Trustedboot TPM utilities that must be implemented for each
+ * unique implementation
+ *
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+#ifndef __TRUSTEDBOOTUTILS_H
+#define __TRUSTEDBOOTUTILS_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#include "trustedTypes.H"
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+/**
+ * @brief Transmit the command to the TPM
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in/out] io_buffer Input the command buffer to send, response on exit
+ * @param[in] i_cmdSize Size of provided command in bytes
+ * @param[in] i_bufsize Size of io_buffer in bytes
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmTransmit(TpmTarget * io_target,
+ uint8_t* io_buffer,
+ size_t i_cmdSize,
+ size_t i_bufsize );
+
+/**
+ * @brief Create an error log entry for potential logging
+ * @param[in] i_modId Code Module ID
+ * @param[in] i_reasonCode Error Reason Code
+ * @param[in] i_user1 User data 1
+ * @param[in] i_user2 User data 2
+ */
+errlHndl_t tpmCreateErrorLog(const uint8_t i_modId,
+ const uint16_t i_reasonCode,
+ const uint64_t i_user1,
+ const uint64_t i_user2);
+
+/**
+ * @brief Mark the TPM as non-functional and take required steps
+ * @param[in/out] io_target Current TPM target structure
+ */
+void tpmMarkFailed(TpmTarget * io_target);
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT namespace
+#endif
+
+#endif
diff --git a/libstb/tss/trustedboot_reasoncodes.H b/libstb/tss/trustedboot_reasoncodes.H
new file mode 100644
index 0000000..bc20310
--- /dev/null
+++ b/libstb/tss/trustedboot_reasoncodes.H
@@ -0,0 +1,95 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/trustedboot_reasoncodes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+#ifndef __TRUSTEDBOOT_REASONCODES_H
+#define __TRUSTEDBOOT_REASONCODES_H
+
+#ifdef __HOSTBOOT_MODULE
+#include <hbotcompid.H>
+#else
+#define SECURE_COMP_ID 0x1E00
+#endif
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ enum TRUSTEDModuleId
+ {
+ MOD_HOST_UPDATE_MASTER_TPM = 0x00,
+ MOD_TPM_INITIALIZE = 0x01,
+ MOD_TPM_CMD_STARTUP = 0x02,
+ MOD_TPM_CMD_GETCAPFWVERSION = 0x03,
+ MOD_TPM_MARSHALCMDDATA = 0x04,
+ MOD_TPM_UNMARSHALRESPDATA = 0x05,
+ MOD_TPM_VERIFYFUNCTIONAL = 0x06,
+ MOD_TPM_CMD_PCREXTEND = 0x07,
+ MOD_TPM_CMD_PCRREAD = 0x08,
+ MOD_TPM_REPLAY_LOG = 0x09,
+ MOD_TPM_PCREXTEND = 0x0A,
+ MOD_TPM_TPMDAEMON = 0x0B,
+ MOD_TPM_SYNCRESPONSE = 0x0C,
+
+ MOD_TPMLOGMGR_INITIALIZE = 0x10,
+ MOD_TPMLOGMGR_ADDEVENT = 0x11,
+ MOD_TPMLOGMGR_INITIALIZEEXISTLOG = 0x012,
+ MOD_TPMLOGMGR_GETDEVTREEINFO = 0x13,
+ };
+
+ enum TRUSTEDReasonCode
+ {
+ // Reason codes 0x00 - 0x9F reserved for secure_reasoncodes.H
+
+ RC_TPM_START_FAIL = SECURE_COMP_ID | 0xA0,
+ RC_TPM_EXISTENCE_FAIL = SECURE_COMP_ID | 0xA1,
+ RC_TPM_GETCAP_FAIL = SECURE_COMP_ID | 0xA2,
+ RC_TPM_GETCAP_FW_INVALID_RESP = SECURE_COMP_ID | 0xA3,
+ RC_TPM_GETCAP2_FAIL = SECURE_COMP_ID | 0xA4,
+ RC_TPM_GETCAP2_FW_INVALID_RESP = SECURE_COMP_ID | 0xA5,
+ RC_TPM_MARSHAL_INVALID_CMD = SECURE_COMP_ID | 0xA6,
+ RC_TPM_MARSHALING_FAIL = SECURE_COMP_ID | 0xA7,
+ RC_TPM_UNMARSHAL_INVALID_CMD = SECURE_COMP_ID | 0xA8,
+ RC_TPM_UNMARSHALING_FAIL = SECURE_COMP_ID | 0xA9,
+ RC_TPMLOGMGR_ADDEVENT_FAIL = SECURE_COMP_ID | 0xAA,
+ RC_TPMLOGMGR_ADDEVENTMARSH_FAIL = SECURE_COMP_ID | 0xAB,
+ RC_TPMLOGMGR_INIT_FAIL = SECURE_COMP_ID | 0xAC,
+ RC_TPM_NOFUNCTIONALTPM_FAIL = SECURE_COMP_ID | 0xAD,
+ RC_TPM_COMMAND_FAIL = SECURE_COMP_ID | 0xAE,
+ RC_TPM_INVALID_ARGS = SECURE_COMP_ID | 0xAF,
+ RC_TPMLOGMGR_LOGWALKFAIL = SECURE_COMP_ID | 0xB0,
+ RC_PCREXTEND_SENDRECV_FAIL = SECURE_COMP_ID | 0xB1,
+ RC_PCREXTEND_SEND_FAIL = SECURE_COMP_ID | 0xB2,
+ RC_MSGRESPOND_FAIL = SECURE_COMP_ID | 0xB3,
+ };
+#ifdef __cplusplus
+}
+#endif
+
+#endif