[Skiboot] [PATCH 14/40] libstb/tss: add hostboot TSS code for TPM 2.0
Stewart Smith
stewart at linux.vnet.ibm.com
Mon Oct 10 19:43:55 AEDT 2016
From: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
Hostboot exports the TCG TPM Software Stack (TSS) implementation for
skiboot/PHYP (downstream consumers). This adds to skiboot the latest
Hostboot TSS code, which supports multibank (it is able to extend multiple
PCR banks at once).
TSS code home and version:
https://github.com/open-power/hostboot/tree/master-p8/src/usr/secureboot/trusted
HEAD: 3ed4df70acbcf3927071ebd626d11e37f3656c38
Skiboot uses the TSS API to extend the same PCR number of both sha1 and
sha256 PCR banks. The PCR number and both sha1 and sha256 measurements are
provided to TSS, which sends a single TPM PCR_EXTEND command to the TPM
device via TPM device driver.
The TSS interface is defined in 'libstb/tss/trustedbootCmds.H'.
Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart at linux.vnet.ibm.com>
---
libstb/tss/trustedTypes.C | 927 +++++++++++++++++++++++++++++++
libstb/tss/trustedTypes.H | 467 ++++++++++++++++
libstb/tss/trustedbootCmds.C | 1009 ++++++++++++++++++++++++++++++++++
libstb/tss/trustedbootCmds.H | 174 ++++++
libstb/tss/trustedbootUtils.C | 97 ++++
libstb/tss/trustedbootUtils.H | 85 +++
libstb/tss/trustedboot_reasoncodes.H | 95 ++++
7 files changed, 2854 insertions(+)
create mode 100644 libstb/tss/trustedTypes.C
create mode 100644 libstb/tss/trustedTypes.H
create mode 100644 libstb/tss/trustedbootCmds.C
create mode 100644 libstb/tss/trustedbootCmds.H
create mode 100644 libstb/tss/trustedbootUtils.C
create mode 100644 libstb/tss/trustedbootUtils.H
create mode 100644 libstb/tss/trustedboot_reasoncodes.H
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
--
2.7.4
More information about the Skiboot
mailing list