diff options
Diffstat (limited to 'libstb/tss')
-rw-r--r-- | libstb/tss/trustedTypes.C | 927 | ||||
-rw-r--r-- | libstb/tss/trustedTypes.H | 467 | ||||
-rw-r--r-- | libstb/tss/trustedbootCmds.C | 1009 | ||||
-rw-r--r-- | libstb/tss/trustedbootCmds.H | 174 | ||||
-rw-r--r-- | libstb/tss/trustedbootUtils.C | 97 | ||||
-rw-r--r-- | libstb/tss/trustedbootUtils.H | 85 | ||||
-rw-r--r-- | libstb/tss/trustedboot_reasoncodes.H | 95 |
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 |