[Skiboot] [PATCH 09/15] libstb: Add TSS and EventLogMgr for TPM 2.0

Stewart Smith stewart at linux.vnet.ibm.com
Tue Sep 20 17:09:45 AEST 2016


Claudio Carvalho <cclaudio at linux.vnet.ibm.com> writes:
> TSS and EventLogMgr are hostboot implementations, but their source code are
> shared with skiboot and phyp. The files tss/trustedbootUtils.* are not
> from hostboot.
>
> This adds both TSS and EventLogMgr with a few modifications. This initial
> version supports multibank. The PCR extend operation extends measurements
> to both sha1 and sha256 banks in a single operation, and the event recorded
> in the event log includes both sha1 and sha256 measurements.
>
> For more information please refer to 'doc/stb.txt'

So, the odd thing here is #ifdefs doing C/C++ selection, when they
really are two different programming languages.... but I should probably
save such commentary for a bar (or a patch) as we do already have some
of this in libpore that we include in skiboot today.

One question is where this code is maintained, which it looks like it's
home is in Hostboot and skiboot and phyp are downstream consumers?

Why is it in sr/usr/secureboot/trusted/ in Hostboot and libstb/tss in
skiboot? It makes it harder to find the location of "upstream".

The use of a bunch of #ifdefs rather than, say, C++ language facilities
wrapping a core C library is... not what I'd choose to do. Any #ifdef
makes code harder to read, which is certainly not a good property for
any code that's security sensitive.

There's a few general issues that I don't think gate merging, but are
something that'd be good to solve, and indeed *should* be solved in a
reasonable timeframe after merging. (it's unfortunate we weren't
involved earlier in the review of this before it hit hostboot):
1) code is not endian safe. Should use be32/le32 et al so that sparse
   can pick up problems, and cpu_to_be32()/be32_to_cpu() when needed.
   (while we don't do a LE skiboot today, the fewer barriers we have to
   ever doing so the better)
2) #ifdefs and C/C++ duality make things harder to read.
3) trustedTypes.H isn't about only types, and the types themselves
   aren't somewhat trusted.
4) It's hard to tell what is an internal API and what's an external
   one. What exactly is the interface to TSS? What does TSS even
   stand for?
5) Needing "#define g_trac_trustedboot NULL" and "#define g_trac_tpmdd
   NULL" isn't elegant library design, it'd be much better if these
   weren't needed.
6) This library is very hostbooty (which is fine if you're hostboot,
   probably not so much if you're phyp or skiboot) - the big thing is
   how it does error handling and reporting. The only way to get a
   complete picture of what went on is to have TRACFCOMP and
   tpmCreateErrorLog output. IMNSHO what should happen is that
   tmpCreateErrorLog should instead be tpmReportError and have it
   accept everything that currently goes to the two places.
   The skiboot log_simple_error() is a good example.
7) In review, I've looked about eight times at #ifdef __HOSTBOOT_MODULE
   code and then had to stop myself commenting on it. Not a clean
   design for code that's meant to be in 3 (or more) places.
8) It's unclear how we could have FWTS annotations here.
9) It seems taht any unit tests in the hostboot copy are somewhat hard
   coded to how HB unit testing works (if it exists) and can't easily be
   brought into testing for skiboot/phyp to validate any differences.

> Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
> ---
>  libstb/Makefile.inc                  |    4 +-
>  libstb/tpm.h                         |   48 ++
>  libstb/tss/Makefile.inc              |   13 +
>  libstb/tss/tpmLogMgr.C               |  563 +++++++++++++++++++
>  libstb/tss/tpmLogMgr.H               |  248 +++++++++
>  libstb/tss/trustedTypes.C            |  926 +++++++++++++++++++++++++++++++
>  libstb/tss/trustedTypes.H            |  470 ++++++++++++++++
>  libstb/tss/trustedbootCmds.C         | 1016 ++++++++++++++++++++++++++++++++++
>  libstb/tss/trustedbootCmds.H         |  177 ++++++
>  libstb/tss/trustedbootUtils.C        |   22 +
>  libstb/tss/trustedbootUtils.H        |   85 +++
>  libstb/tss/trustedboot_reasoncodes.H |   88 +++
>  12 files changed, 3659 insertions(+), 1 deletion(-)
>  create mode 100644 libstb/tpm.h
>  create mode 100644 libstb/tss/Makefile.inc
>  create mode 100644 libstb/tss/tpmLogMgr.C
>  create mode 100644 libstb/tss/tpmLogMgr.H
>  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/Makefile.inc b/libstb/Makefile.inc
> index 15cdfbe..642269f 100644
> --- a/libstb/Makefile.inc
> +++ b/libstb/Makefile.inc
> @@ -8,4 +8,6 @@ LIBSTB_SRCS = container.c
>  LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o)
>  LIBSTB = $(LIBSTB_DIR)/built-in.o
>  
> -$(LIBSTB): $(LIBSTB_OBJS:%=$(LIBSTB_DIR)/%)
> +include $(SRC)/$(LIBSTB_DIR)/tss/Makefile.inc
> +
> +$(LIBSTB): $(LIBSTB_OBJS:%=$(LIBSTB_DIR)/%) $(TSS)
> diff --git a/libstb/tpm.h b/libstb/tpm.h
> new file mode 100644
> index 0000000..546458e
> --- /dev/null
> +++ b/libstb/tpm.h
> @@ -0,0 +1,48 @@
> +/* Copyright 2013-2016 IBM 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.
> + */
> +
> +#ifndef __TPM_H
> +#define __TPM_H
> +
> +#include <device.h>
> +
> +#include "tss/tpmLogMgr.H"
> +#include "tss/trustedTypes.H"
> +
> +struct tpm_dev {
> +	int bus_id;
> +	int xscom_base;
> +};
> +
> +struct tpm_driver {
> +	const char* name;
> +	int (*transmit)(struct tpm_dev *dev, uint8_t* buf, size_t cmdlen,
> +			size_t *buflen);
> +};
> +
> +struct tpm_chip {
> +	int id;
> +	bool enabled;
> +	struct dt_node *node;
> +	struct _TpmLogMgr logmgr;
> +	struct tpm_dev    *dev;
> +	struct tpm_driver *driver;
> +	struct list_node link;
> +};
> +
> +typedef struct tpm_chip TpmTarget;

This last typedef is just for tss, right?

> +
> +#endif /* __TPM_H */
> diff --git a/libstb/tss/Makefile.inc b/libstb/tss/Makefile.inc
> new file mode 100644
> index 0000000..2b5c3b9
> --- /dev/null
> +++ b/libstb/tss/Makefile.inc
> @@ -0,0 +1,13 @@
> +#-*-Makefile-*-
> +
> +TSS_DIR = libstb/tss
> +
> +SUBDIRS += $(TSS_DIR)
> +
> +TSS_SRCS = trustedbootCmds.C trustedTypes.C trustedbootUtils.C \
> +	   tpmLogMgr.C
> +TSS_OBJS = $(TSS_SRCS:%.C=%.o)
> +TSS = $(TSS_DIR)/built-in.o
> +
> +$(TSS): $(TSS_OBJS:%=$(TSS_DIR)/%)
> +
> diff --git a/libstb/tss/tpmLogMgr.C b/libstb/tss/tpmLogMgr.C
> new file mode 100644
> index 0000000..ed6e399
> --- /dev/null
> +++ b/libstb/tss/tpmLogMgr.C
> @@ -0,0 +1,563 @@
> +/* IBM_PROLOG_BEGIN_TAG                                                   */
> +/* This is an automatically generated prolog.                             */
> +/*                                                                        */
> +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.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 TpmLogMgr.C
> + *
> + * @brief TPM Event log manager
> + */
> +
> +/////////////////////////////////////////////////////////////////
> +// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP  //
> +/////////////////////////////////////////////////////////////////
> +
> +// ----------------------------------------------
> +// Includes
> +// ----------------------------------------------
> +#include <string.h>
> +#include "tpmLogMgr.H"
> +#ifdef __HOSTBOOT_MODULE
> +#include <sys/mm.h>
> +#include <util/align.H>
> +#include <secureboot/trustedboot_reasoncodes.H>
> +#else
> +#include "trustedboot_reasoncodes.H"
> +#endif
> +
> +#ifdef __cplusplus
> +namespace TRUSTEDBOOT
> +{
> +#endif
> +
> +    uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val)
> +    {
> +        return (sizeof(TCG_EfiSpecIdEventStruct) + val->vendorInfoSize);
> +    }
> +
> +#ifdef __HOSTBOOT_MODULE
> +    errlHndl_t TpmLogMgr_initialize(TpmLogMgr* val)
> +    {
> +        errlHndl_t err = TB_SUCCESS;
> +        const char vendorInfo[] = "IBM";
> +        const char eventSignature[] = "Spec ID Event03";
> +        TCG_EfiSpecIdEventStruct* eventData = NULL;
> +
> +        TCG_PCR_EVENT eventLogEntry;
> +
> +        TRACUCOMP( g_trac_trustedboot, ">>initialize()");
> +
> +        if (NULL == val)
> +        {
> +            TRACFCOMP( g_trac_trustedboot,
> +                       "TPM LOG INIT FAIL");
> +
> +                /*@
> +                 * @errortype
> +                 * @reasoncode     RC_TPMLOGMGR_INIT_FAIL
> +                 * @severity       ERRL_SEV_UNRECOVERABLE
> +                 * @moduleid       MOD_TPMLOGMGR_INITIALIZE
> +                 * @userdata1      0
> +                 * @userdata2      0
> +                 * @devdesc        TPM log buffer init failure.
> +                 */
> +                err = tpmCreateErrorLog( MOD_TPMLOGMGR_INITIALIZE,
> +                                         RC_TPMLOGMGR_INIT_FAIL, 0, 0);
> +
> +        }
> +        else
> +        {
> +
> +            memset(val, 0, sizeof(TpmLogMgr));
> +            val->logMaxSize = TPMLOG_BUFFER_SIZE;
> +
> +            mutex_init( &val->logMutex );
> +            mutex_lock( &val->logMutex );
> +
> +            // Assign our new event pointer to the start
> +            val->newEventPtr = val->eventLog;
> +            memset(val->eventLog, 0, TPMLOG_BUFFER_SIZE);
> +
> +            eventData = (TCG_EfiSpecIdEventStruct*) eventLogEntry.event;
> +
> +            // Add the header event log
> +            // Values here come from the PC ClientSpecificPlatformProfile spec
> +            eventLogEntry.eventType = EV_NO_ACTION;
> +            eventLogEntry.pcrIndex = 0;
> +            eventLogEntry.eventSize = sizeof(TCG_EfiSpecIdEventStruct) +
> +                sizeof(vendorInfo);
> +
> +            memcpy(eventData->signature, eventSignature,
> +                   sizeof(eventSignature));
> +            eventData->platformClass = htole32(TPM_PLATFORM_SERVER);
> +            eventData->specVersionMinor = TPM_SPEC_MINOR;
> +            eventData->specVersionMajor = TPM_SPEC_MAJOR;
> +            eventData->specErrata = TPM_SPEC_ERRATA;
> +            eventData->uintnSize = 1;
> +            eventData->numberOfAlgorithms = htole32(HASH_COUNT);
> +            eventData->digestSizes[0].algorithmId = htole16(TPM_ALG_SHA256);
> +            eventData->digestSizes[0].digestSize = htole16(TPM_ALG_SHA256_SIZE);
> +            eventData->digestSizes[1].algorithmId = htole16(TPM_ALG_SHA1);
> +            eventData->digestSizes[1].digestSize = htole16(TPM_ALG_SHA1_SIZE);
> +            eventData->vendorInfoSize = sizeof(vendorInfo);
> +            memcpy(eventData->vendorInfo, vendorInfo, sizeof(vendorInfo));
> +            val->newEventPtr = TCG_PCR_EVENT_logMarshal(&eventLogEntry,
> +                                                        val->newEventPtr);
> +
> +            // Done, move our pointers
> +            val->logSize += TCG_PCR_EVENT_marshalSize(&eventLogEntry);
> +
> +            mutex_unlock( &val->logMutex );
> +
> +            // Debug display of raw data
> +            TRACUBIN(g_trac_trustedboot, "tpmInitialize: Header Entry",
> +                     val->eventLog, val->logSize);
> +
> +            TRACUCOMP( g_trac_trustedboot,
> +                       "<<initialize() LS:%d - %s",
> +                       val->logSize,
> +                       ((TB_SUCCESS == err) ? "No Error" : "With Error") );
> +        }
> +        return err;
> +    }
> +#endif
> +
> +    errlHndl_t TpmLogMgr_initializeUsingExistingLog(TpmLogMgr* val,
> +                                                    uint8_t* eventLogPtr,
> +                                                    uint32_t eventLogSize)
> +    {
> +        errlHndl_t err = TB_SUCCESS;
> +        TRACUCOMP( g_trac_trustedboot,
> +                   ">>initializeUsingExistingLog()");
> +
> +        do
> +        {
> +
> +            mutex_init( &val->logMutex );
> +            mutex_lock( &val->logMutex );
> +
> +            val->logMaxSize = eventLogSize;
> +            val->eventLogInMem = eventLogPtr;
> +
> +            // Ok, walk the log to figure out how big this is
> +            val->logSize = TpmLogMgr_calcLogSize(val);
> +
> +            if (0 == val->logSize)
> +            {
> +                TRACFCOMP( g_trac_trustedboot,
> +                       "TPM LOG INIT WALK FAIL");
> +                /*@
> +                 * @errortype
> +                 * @reasoncode     RC_TPMLOGMGR_LOGWALKFAIL
> +                 * @severity       ERRL_SEV_UNRECOVERABLE
> +                 * @moduleid       MOD_TPMLOGMGR_INITIALIZEEXISTLOG
> +                 * @userdata1      0
> +                 * @userdata2      0
> +                 * @devdesc        TPM log header entry is missing.
> +                 */
> +                err = tpmCreateErrorLog(MOD_TPMLOGMGR_INITIALIZEEXISTLOG,
> +                                        RC_TPMLOGMGR_LOGWALKFAIL,
> +                                        0,
> +                                        0);
> +                break;
> +            }
> +            // We are good, let's move the newEventLogPtr
> +            val->newEventPtr = val->eventLogInMem + val->logSize;
> +
> +        }
> +        while(0);
> +
> +        if (TB_SUCCESS != err)
> +        {
> +            val->eventLogInMem = NULL;
> +            val->newEventPtr = NULL;
> +            val->logMaxSize = 0;
> +            val->logSize = 0;
> +        }
> +
> +        mutex_unlock( &val->logMutex );
> +
> +        return err;
> +    }
> +
> +    errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val,
> +                                  TCG_PCR_EVENT2* logEvent)
> +    {
> +        errlHndl_t err = TB_SUCCESS;
> +        size_t newLogSize = TCG_PCR_EVENT2_marshalSize(logEvent);
> +
> +        TRACUCOMP( g_trac_trustedboot,
> +                   ">>tpmAddEvent() PCR:%d Type:%d Size:%d",
> +                   logEvent->pcrIndex, logEvent->eventType, (int)newLogSize);
> +
> +        mutex_lock( &val->logMutex );
> +
> +        do
> +        {
> +
> +            // Need to ensure we have room for the new event
> +            // We have to leave room for the log full event as well
> +            if (NULL == val->newEventPtr ||
> +                val->logSize + newLogSize > val->logMaxSize)
> +            {
> +                TRACFCOMP( g_trac_trustedboot,
> +                           "TPM LOG ADD FAIL PNULL(%d) LS(%d) New LS(%d)"
> +                           " Max LS(%d)",
> +                           (NULL == val->newEventPtr ? 0 : 1),
> +                           (int)val->logSize, (int)newLogSize,
> +                           (int)val->logMaxSize);
> +
> +                /*@
> +                 * @errortype
> +                 * @reasoncode     RC_TPMLOGMGR_ADDEVENT_FAIL
> +                 * @severity       ERRL_SEV_UNRECOVERABLE
> +                 * @moduleid       MOD_TPMLOGMGR_ADDEVENT
> +                 * @userdata1      Log buffer NULL
> +                 * @userdata2[0:31] Current Log Size
> +                 * @userdata2[32:63] New entry size
> +                 * @devdesc        TPM log buffer add failure.
> +                 */
> +                err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT,
> +                                         RC_TPMLOGMGR_ADDEVENT_FAIL,
> +                                         (NULL == val->newEventPtr ? 0 : 1),
> +                                         (uint64_t)val->logSize << 32 |
> +                                         newLogSize);
> +
> +                break;
> +            }
> +
> +            val->newEventPtr = TCG_PCR_EVENT2_logMarshal(logEvent,
> +                                                         val->newEventPtr);
> +
> +            if (NULL == val->newEventPtr)
> +            {
> +                TRACFCOMP( g_trac_trustedboot,
> +                           "TPM LOG MARSHAL Fail");
> +
> +                /*@
> +                 * @errortype
> +                 * @reasoncode     RC_TPMLOGMGR_ADDEVENTMARSH_FAIL
> +                 * @severity       ERRL_SEV_UNRECOVERABLE
> +                 * @moduleid       MOD_TPMLOGMGR_ADDEVENT
> +                 * @userdata1      0
> +                 * @userdata2      0
> +                 * @devdesc        log buffer malloc failure.
> +                 */
> +                err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT,
> +                                         RC_TPMLOGMGR_ADDEVENTMARSH_FAIL,
> +                                         0,
> +                                         0);
> +                break;
> +            }
> +
> +            val->logSize += newLogSize;
> +
> +
> +        } while ( 0 );
> +
> +        TRACUCOMP( g_trac_trustedboot,
> +                   "<<tpmAddEvent() LS:%d - %s",
> +                   (int)val->logSize,
> +                   ((TB_SUCCESS == err) ? "No Error" : "With Error") );
> +
> +        mutex_unlock( &val->logMutex );
> +        return err;
> +    }
> +
> +    uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val)
> +    {
> +        return val->logSize;
> +    }
> +
> +#ifdef __HOSTBOOT_MODULE
> +    void TpmLogMgr_dumpLog(TpmLogMgr* val)
> +    {
> +
> +        // Debug display of raw data
> +        TRACUCOMP(g_trac_trustedboot, "tpmDumpLog Size : %d",
> +                  (int)val->logSize);
> +
> +        // Debug display of raw data
> +        if (NULL == val->eventLogInMem)
> +        {
> +            TRACUBIN(g_trac_trustedboot, "tpmDumpLog",
> +                     val->eventLog, val->logSize);
> +        }
> +        else
> +        {
> +            TRACUBIN(g_trac_trustedboot, "tpmDumpLog From Memory",
> +                     val->eventLogInMem, val->logSize);
> +        }
> +    }
> +#endif
> +
> +    uint32_t TpmLogMgr_calcLogSize(TpmLogMgr* val)
> +    {
> +        uint32_t logSize = 0;
> +        TCG_PCR_EVENT event;
> +        TCG_PCR_EVENT2 event2;
> +        bool errorFound = false;
> +        const uint8_t* prevLogHandle = NULL;
> +        const uint8_t* nextLogHandle = NULL;
> +
> +        TRACUCOMP( g_trac_trustedboot, ">>calcLogSize");
> +
> +        // Start walking events
> +        prevLogHandle = TpmLogMgr_getLogStartPtr(val);
> +        do
> +        {
> +
> +            // First need to deal with the header entry
> +            nextLogHandle = TCG_PCR_EVENT_logUnmarshal(&event,
> +                                                       prevLogHandle,
> +                                                       sizeof(TCG_PCR_EVENT),
> +                                                       &errorFound);
> +
> +            if (NULL == nextLogHandle || errorFound ||
> +                EV_NO_ACTION != event.eventType ||
> +                0 == event.eventSize)
> +            {
> +                TRACFCOMP( g_trac_trustedboot, "Header Marshal Failure");
> +                prevLogHandle = NULL;
> +                break;
> +            }
> +
> +            if (( nextLogHandle - TpmLogMgr_getLogStartPtr(val)) >
> +                val->logMaxSize)
> +            {
> +                TRACFCOMP( g_trac_trustedboot, "calcLogSize overflow");
> +                prevLogHandle = NULL;
> +                break;
> +            }
> +            prevLogHandle = nextLogHandle;
> +
> +            // Now iterate through all the other events
> +            while (NULL != prevLogHandle)
> +            {
> +                nextLogHandle = TCG_PCR_EVENT2_logUnmarshal(
> +                                               &event2,
> +                                               prevLogHandle,
> +                                               sizeof(TCG_PCR_EVENT2),
> +                                               &errorFound);
> +                if (NULL == nextLogHandle || errorFound)
> +                {
> +                    // Failed parsing so we must have hit the end of log
> +                    break;
> +                }
> +                if (( nextLogHandle - TpmLogMgr_getLogStartPtr(val)) >
> +                    val->logMaxSize)
> +                {
> +                    TRACFCOMP( g_trac_trustedboot, "calcLogSize overflow");
> +                    prevLogHandle = NULL;
> +                    break;
> +                }
> +                prevLogHandle = nextLogHandle;
> +            }
> +        }
> +        while (0);
> +
> +        if (NULL == prevLogHandle)
> +        {
> +            logSize = 0;
> +        }
> +        else
> +        {
> +            logSize = (prevLogHandle - TpmLogMgr_getLogStartPtr(val));
> +        }
> +        TRACUCOMP( g_trac_trustedboot, "<<calcLogSize : %d", logSize);
> +
> +        return logSize;
> +    }
> +
> +    const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val)
> +    {
> +        TCG_PCR_EVENT event;
> +        bool err = false;
> +        const uint8_t* result = NULL;
> +
> +        // Header event in the log is always first, we skip over that
> +        const uint8_t* firstEvent = TpmLogMgr_getLogStartPtr(val);
> +        memset(&event, 0, sizeof(TCG_PCR_EVENT));
> +
> +        firstEvent = TCG_PCR_EVENT_logUnmarshal(&event, firstEvent,
> +                                                sizeof(TCG_PCR_EVENT),
> +                                                &err);
> +        if (NULL != firstEvent && !err &&
> +            firstEvent < val->newEventPtr)
> +        {
> +            result = firstEvent;
> +        }
> +
> +        return result;
> +    }
> +
> +    const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val,
> +                                          const uint8_t* i_handle,
> +                                          TCG_PCR_EVENT2* i_eventLog,
> +                                          bool* o_err)
> +    {
> +        const uint8_t* l_resultPtr = NULL;
> +        if (NULL == i_handle)
> +        {
> +            *o_err = true;
> +        }
> +        else
> +        {
> +            memset(i_eventLog, 0, sizeof(TCG_PCR_EVENT2));
> +            TRACUCOMP( g_trac_trustedboot, "TPM getNextEvent 0x%p", i_handle);
> +            l_resultPtr = TCG_PCR_EVENT2_logUnmarshal(i_eventLog, i_handle,
> +                                                      sizeof(TCG_PCR_EVENT2),
> +                                                      o_err);
> +            if (NULL == l_resultPtr)
> +            {
> +                // An error was detected, ensure o_err is set
> +                *o_err = true;
> +            }
> +            else if (l_resultPtr >= val->newEventPtr)
> +            {
> +                l_resultPtr = NULL;
> +            }
> +        }
> +
> +        return l_resultPtr;
> +    }
> +
> +    TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(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,
> +						  uint32_t i_logType,
> +                                                  const char* i_logMsg)
> +    {
> +        TCG_PCR_EVENT2 eventLog;
> +        size_t fullDigestSize_1 = 0;
> +        size_t fullDigestSize_2 = 0;
> +
> +        fullDigestSize_1 = getDigestSize(i_algId_1);
> +        if (NULL != i_digest_2)
> +        {
> +            fullDigestSize_2 = getDigestSize(i_algId_2);
> +        }
> +
> +        memset(&eventLog, 0, sizeof(eventLog));
> +        eventLog.pcrIndex = i_pcr;
> +        eventLog.eventType = i_logType;
> +
> +        // Update digest information
> +        eventLog.digests.count = 1;
> +        eventLog.digests.digests[0].algorithmId = i_algId_1;
> +        memcpy(&(eventLog.digests.digests[0].digest),
> +               i_digest_1,
> +               (i_digestSize_1 < fullDigestSize_1 ?
> +                i_digestSize_1 : fullDigestSize_1));
> +
> +        if (NULL != i_digest_2)
> +        {
> +            eventLog.digests.count = 2;
> +            eventLog.digests.digests[1].algorithmId = i_algId_2;
> +            memcpy(&(eventLog.digests.digests[1].digest),
> +                   i_digest_2,
> +                   (i_digestSize_2 < fullDigestSize_2 ?
> +                    i_digestSize_2 : fullDigestSize_2));
> +        }
> +        // Event field data
> +        eventLog.event.eventSize = strlen(i_logMsg);
> +        memset(eventLog.event.event, 0, sizeof(eventLog.event.event));
> +        memcpy(eventLog.event.event, i_logMsg,
> +               (strlen(i_logMsg) > MAX_TPM_LOG_MSG ?
> +                MAX_TPM_LOG_MSG - 1 // Leave room for NULL termination
> +                : strlen(i_logMsg)) );
> +
> +        return eventLog;
> +    }
> +
> +
> +    uint8_t* TpmLogMgr_getLogStartPtr(TpmLogMgr* val)
> +    {
> +#ifdef __HOSTBOOT_MODULE
> +        return (val->eventLogInMem == NULL ?
> +           reinterpret_cast<uint8_t*>(&(val->eventLog)) : val->eventLogInMem);
> +#else
> +        return val->eventLogInMem;
> +#endif
> +    }
> +
> +#ifdef __HOSTBOOT_MODULE
> +    errlHndl_t TpmLogMgr_getDevtreeInfo(TpmLogMgr* val,
> +                                        uint64_t & io_logAddr,
> +                                        size_t & o_allocationSize,
> +                                        uint64_t & o_xscomAddr,
> +                                        uint32_t & o_i2cMasterOffset)
> +    {
> +        errlHndl_t err = NULL;
> +
> +        mutex_lock( &val->logMutex );
> +
> +        assert(io_logAddr != 0, "Invalid starting log address");
> +        assert(val->eventLogInMem == NULL,
> +               "getDevtreeInfo can only be called once");
> +
> +        io_logAddr -= ALIGN_PAGE(TPMLOG_DEVTREE_SIZE);
> +        // Align to 64KB for Opal
> +        io_logAddr = ALIGN_DOWN_X(io_logAddr,64*KILOBYTE);
> +
> +        val->inMemlogBaseAddr = io_logAddr;
> +        o_allocationSize = TPMLOG_DEVTREE_SIZE;
> +        o_xscomAddr = val->devtreeXscomAddr;
> +        o_i2cMasterOffset = val->devtreeI2cMasterOffset;
> +
> +        // Copy image.
> +        val->eventLogInMem = (uint8_t*)(mm_block_map(
> +                                 (void*)(io_logAddr),
> +                                 ALIGN_PAGE(TPMLOG_DEVTREE_SIZE)));
> +        // Copy log into new location
> +        memset(val->eventLogInMem, 0, TPMLOG_DEVTREE_SIZE);
> +        memcpy(val->eventLogInMem, val->eventLog, val->logSize);
> +        val->newEventPtr = val->eventLogInMem + val->logSize;
> +
> +        mutex_unlock( &val->logMutex );
> +
> +        TRACUCOMP( g_trac_trustedboot,
> +                   "<<getDevtreeInfo() Addr:%lX - %s",
> +                   io_logAddr,
> +                   ((TB_SUCCESS == err) ? "No Error" : "With Error") );
> +        return err;
> +    }
> +
> +
> +    void TpmLogMgr_setTpmDevtreeInfo(TpmLogMgr* val,
> +                                     uint64_t i_xscomAddr,
> +                                     uint32_t i_i2cMasterOffset)
> +    {
> +        val->devtreeXscomAddr = i_xscomAddr;
> +        val->devtreeI2cMasterOffset = i_i2cMasterOffset;
> +    }
> +
> +#endif
> +
> +#ifdef __cplusplus
> +} // end TRUSTEDBOOT
> +#endif
> diff --git a/libstb/tss/tpmLogMgr.H b/libstb/tss/tpmLogMgr.H
> new file mode 100644
> index 0000000..eb2ef3d
> --- /dev/null
> +++ b/libstb/tss/tpmLogMgr.H
> @@ -0,0 +1,248 @@
> +/* IBM_PROLOG_BEGIN_TAG                                                   */
> +/* This is an automatically generated prolog.                             */
> +/*                                                                        */
> +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.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 tpmLogMgr.H
> + *
> + * @brief Trustedboot TPM Event Log Manager
> + *
> + */
> +
> +/////////////////////////////////////////////////////////////////
> +// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP  //
> +/////////////////////////////////////////////////////////////////
> +
> +#ifndef __TPMLOGMGR_H
> +#define __TPMLOGMGR_H
> +// -----------------------------------------------
> +// Includes
> +// -----------------------------------------------
> +
> +#ifdef __HOSTBOOT_MODULE
> +#include <sys/sync.h>
> +#include "trustedboot.H"
> +#endif
> +#include "trustedbootUtils.H"
> +#include "trustedTypes.H"
> +
> +#ifdef __cplusplus
> +namespace TRUSTEDBOOT
> +{
> +#endif
> +
> +    /// Event log header algorithms
> +    struct _TCG_EfiSpecIdEventAlgorithmSize
> +    {
> +        uint16_t     algorithmId;
> +        uint16_t     digestSize;
> +    } PACKED;
> +    typedef struct _TCG_EfiSpecIdEventAlgorithmSize
> +                    TCG_EfiSpecIdEventAlgorithmSize;
> +
> +    /// Event log header event data
> +    struct _TCG_EfiSpecIdEventStruct
> +    {
> +        char         signature[16];
> +        uint32_t     platformClass;
> +        uint8_t      specVersionMinor;
> +        uint8_t      specVersionMajor;
> +        uint8_t      specErrata;
> +        uint8_t      uintnSize;
> +        uint32_t     numberOfAlgorithms;
> +        TCG_EfiSpecIdEventAlgorithmSize digestSizes[HASH_COUNT];
> +        uint8_t      vendorInfoSize;
> +        char         vendorInfo[0];
> +    } PACKED;
> +    typedef struct _TCG_EfiSpecIdEventStruct TCG_EfiSpecIdEventStruct;
> +    uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val);
> +
> +    enum {
> +        TPMLOG_BUFFER_SIZE   = 2048, ///< Size of event log buffer in bytes
> +        TPMLOG_DEVTREE_SIZE  = 64*1024, ///< Size to allocate for OPAL
> +    };
> +
> +    struct _TpmLogMgr
> +    {
> +        uint32_t logSize;        ///< Current byte size of log
> +        uint32_t logMaxSize;     ///< Space allocated for log entries
> +        uint8_t* newEventPtr;    ///< Pointer to location to add new event
> +        uint8_t* eventLogInMem;  ///< Event log allocated from memory
> +#ifdef __HOSTBOOT_MODULE
> +        uint64_t inMemlogBaseAddr; ///< Base address of log for dev tree
> +        uint64_t devtreeXscomAddr; ///< Devtree Xscom Address
> +        uint32_t devtreeI2cMasterOffset; ///< Devtree I2c Master Offset
> +        uint8_t eventLog[TPMLOG_BUFFER_SIZE]; ///< EventLog Buffer
> +#endif
> +        mutex_t  logMutex;       ///< Log mutex
> +    };
> +    typedef struct _TpmLogMgr TpmLogMgr;
> +
> +#ifdef __HOSTBOOT_MODULE
> +    /**
> +     * @brief Initialize the log manager
> +     * @param[in/out] io_logMgr Return a pointer to the log manager
> +     * @return errlHndl_t NULL if successful, otherwise a pointer to the
> +     *       error log.
> +     */
> +    errlHndl_t TpmLogMgr_initialize(TpmLogMgr * io_logMgr);
> +#endif
> +
> +    /**
> +     * @brief Initialize the log manager to use a pre-existing buffer
> +     * @param[in] val TpmLogMgr structure
> +     * @param[in] eventLogPtr Pointer to event log to use
> +     * @param[in] eventLogSize Allocated log buffer size
> +     * @return errlHndl_t NULL if successful, otherwise a pointer to the
> +     *       error log.
> +     */
> +    errlHndl_t TpmLogMgr_initializeUsingExistingLog(TpmLogMgr* val,
> +                                                    uint8_t* eventLogPtr,
> +                                                    uint32_t eventLogSize);
> +
> +    /**
> +     * @brief Add a new event to the log
> +     * @param[in] val TpmLogMgr structure
> +     * @param[in] logEvent Event log entry to add
> +     * @return errlHndl_t NULL if successful, otherwise a pointer to the
> +     *       error log.
> +     */
> +    errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val, TCG_PCR_EVENT2* logEvent);
> +
> +    /**
> +     * @brief Get current log size in bytes
> +     * @param[in] val TpmLogMgr structure
> +     * @return uint32_t Byte size of log
> +     */
> +    uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val);
> +
> +#ifdef __HOSTBOOT_MODULE
> +    /**
> +     * @brief Retrieve devtree information
> +     * @param[in] val TpmLogMgr structure
> +     * @param[in/out] io_logAddr TPM Log address
> +     * @param[out] o_allocationSize Total memory allocated for log
> +     * @param[out] o_xscomAddr Chip Xscom Address
> +     * @param[out] o_i2cMasterOffset I2c Master Offset
> +     * @return errlHndl_t NULL if successful, otherwise a pointer to the
> +     *       error log.
> +     * Function will allocate a new region in memory to store log
> +     *  for passing to opal
> +     */
> +     errlHndl_t TpmLogMgr_getDevtreeInfo(TpmLogMgr* val,
> +                                         uint64_t & io_logAddr,
> +                                         size_t & o_allocationSize,
> +                                         uint64_t & o_xscomAddr,
> +                                         uint32_t & o_i2cMasterOffset);
> +
> +    /**
> +     * @brief Store TPM devtree node information
> +     * @param[in] val TpmLogMgr structure
> +     * @param[in] i_xscomAddr Chip Xscom Address
> +     * @param[in] i_i2cMasterOffset i2c Master Offset
> +     */
> +    void TpmLogMgr_setTpmDevtreeInfo(TpmLogMgr* val,
> +                                     uint64_t i_xscomAddr,
> +                                     uint32_t i_i2cMasterOffset);
> +#endif
> +
> +
> +    /**
> +     * @brief Calculate the log size in bytes by walking the log
> +     * @param[in] val TpmLogMgr structure
> +     * @return uint32_t Byte size of log
> +     */
> +    uint32_t TpmLogMgr_calcLogSize(TpmLogMgr* val);
> +
> +    /**
> +     * @brief Get pointer to first event in eventLog past the header event
> +     * @param[in] val TpmLogMgr structure
> +     * @return uint8_t First event handle
> +     * @retval NULL On empty log
> +     * @retval !NULL First event handle
> +     */
> +    const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val);
> +
> +    /**
> +     * @brief Get pointer to next event in log and unmarshal log contents
> +     *        into i_eventLog
> +     *
> +     * @param[in] i_handle      Current event to unmarshal
> +     * @param[in] i_eventLog    EVENT2 structure to populate
> +     * @param[in] o_err         Indicates if an error occurred during
> +     *                          LogUnmarshal.
> +     *
> +     * @return uint8_t*     Pointer to the next event after i_handle
> +     * @retval NULL When val contains last entry in log
> +     * @retval !NULL When addition log entries available
> +     */
> +    const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val,
> +                                          const uint8_t* i_handle,
> +                                          TCG_PCR_EVENT2* i_eventLog,
> +                                          bool* o_err);
> +
> +    /**
> +     * @brief Get a TCG_PCR_EVENT2 populated with required data
> +     *
> +     * @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
> +     * @param[in] i_digestSize_1 Byte size of i_digest array
> +     * @param[in] i_algId_2 Algorithm to use
> +     * @param[in] i_digest_2 Digest value to write to PCR, NULL if not used
> +     * @param[in] i_digestSize_2 Byte size of i_digest array
> +     * @param[in] i_logType Event type
> +     * @param[in] i_logMsg Null terminated Log message
> +     *
> +     * @return TCG_PCR_EVENT2   PCR event log
> +     */
> +    TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(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,
> +						  uint32_t i_logType,
> +                                                  const char* i_logMsg);
> +#ifdef __HOSTBOOT_MODULE
> +    /**
> +     * @brief Dump contents of log to a trace
> +     * @param[in] val TpmLogMgr structure
> +     */
> +    void TpmLogMgr_dumpLog(TpmLogMgr* val);
> +#endif
> +
> +    /**
> +     * @brief Return a pointer to the start of the log
> +     * @param[in] val TpmLogMgr structure
> +     * @return uint8_t* Pointer to the start of the TPM log
> +     */
> +    uint8_t* TpmLogMgr_getLogStartPtr(TpmLogMgr* val);
> +
> +
> +#ifdef __cplusplus
> +} // end TRUSTEDBOOT namespace
> +#endif
> +
> +#endif
> diff --git a/libstb/tss/trustedTypes.C b/libstb/tss/trustedTypes.C
> new file mode 100644
> index 0000000..cc8c123
> --- /dev/null
> +++ b/libstb/tss/trustedTypes.C
> @@ -0,0 +1,926 @@
> +/* 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 "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..8269aff
> --- /dev/null
> +++ b/libstb/tss/trustedTypes.H
> @@ -0,0 +1,470 @@
> +/* 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 "trustedbootUtils.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_SYSTEM_TPMS = 2,
> +        TPM_MASTER_INDEX = 0,     ///< Index into tpm array for master chip
> +        TPM_BACKUP_INDEX = 1,     ///< Index for backup TPM
> +        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..796af16
> --- /dev/null
> +++ b/libstb/tss/trustedbootCmds.C
> @@ -0,0 +1,1016 @@
> +/* 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>
> +#include "trustedboot.H"
> +#else
> +#include "trustedboot_reasoncodes.H"
> +#endif
> +#include "trustedbootCmds.H"
> +#include "trustedbootUtils.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;
> +#ifdef __HOSTBOOT_MODULE
> +        err = tpmTransmit(io_target,
> +                          transmitBuf,
> +                          cmdSize,
> +                          dataSize);
> +#else
> +	err = io_target->driver->transmit(io_target->dev,
> +					  transmitBuf,
> +					  cmdSize,
> +					  &dataSize);
> +#endif

Why not just have a tpmTransmit wrapper that just does
io_target->driver->transmit() for skiboot?

> +        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..0a72c19
> --- /dev/null
> +++ b/libstb/tss/trustedbootCmds.H
> @@ -0,0 +1,177 @@
> +/* 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>
> +#include "trustedboot.H"
> +#else
> +#include "trustedbootUtils.H"
> +#include "../tpm.h"
> +#endif
> +#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..24b949f
> --- /dev/null
> +++ b/libstb/tss/trustedbootUtils.C
> @@ -0,0 +1,22 @@
> +/**
> + * @file trustedbootUtils.C
> + *
> + * @brief Trusted boot utility functions for skiboot
> + */

Needs (C) header.

> +
> +// ----------------------------------------------
> +// Includes
> +// ----------------------------------------------

This style of comment doesn't add any information, remove it.

> +#include <stdio.h>
> +#include "trustedbootUtils.H"
> +
> +errlHndl_t tpmCreateErrorLog(const uint8_t i_modId,
> +                             const uint16_t i_reasonCode,
> +                             const uint64_t i_user1,
> +                             const uint64_t i_user2)
> +{
> +    printf("Error Log %d %d %d %d\n", i_modId, i_reasonCode,
> +           (int)i_user1, (int)i_user2);
> +    return (i_modId << 16) | i_reasonCode;
> +}

we can create error logs in skiboot, why not do that?

At the very least, it looks like this shoud be prlog(PR_ERR rather than printf.

> diff --git a/libstb/tss/trustedbootUtils.H b/libstb/tss/trustedbootUtils.H
> new file mode 100644
> index 0000000..78fb0ce
> --- /dev/null
> +++ b/libstb/tss/trustedbootUtils.H
> @@ -0,0 +1,85 @@
> + /* Copyright 2013-2016 IBM 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.
> +  */
> +
> +/***************************************************************
> + * This file redefines some structures and functions so we can
> + * export the Hostboot TSS-Light code to skiboot
> + ***************************************************************/
> +
> +#ifndef __TRUSTEDBOOTUTILS_H
> +#define __TRUSTEDBOOTUTILS_H
> +
> +#include <skiboot.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <lock.h>
> +
> +/* Failure trace routines */
> +#define TRACFCOMP(TB, fmt, ...) prlog(PR_ERR, "STB: " fmt "\n",
> ##__VA_ARGS__);

You can define pr_fmt to get the STB prefix.

> +//#define TRACFCOMP(args...)

Ever disabling this sounds like a bad idea, as then it seems the tss lib
will silently fail at various points. Any reason why this is set up here
as if it's something to toggle?

> +
> +/* Debug trace routines */
> +//#define TRACDCOMP(TB, fmt, ...) prlog(PR_DEBUG, "STB: " fmt "\n", ##__VA_ARGS__)
> +#define TRACDCOMP(args...)
> +
> +//#define TRACUCOMP(TB, fmt, ...) prlog(PR_DEBUG, "STB: " fmt "\n", ##__VA_ARGS__);
> +#define TRACUCOMP(args...)
> +
> +//#define TRACUBIN(TB, fmt, ...) prlog(PR_DEBUG, "STB: " fmt "\n", ##__VA_ARGS__);
> +#define TRACUBIN(args...)
> +
> +/* Define a few routines that are different in skiboot */
> +#define g_trac_trustedboot NULL
> +#define g_trac_tpmdd NULL
> +typedef uint32_t errlHndl_t;
> +#define TB_SUCCESS 0
> +#define htole32 CPU_TO_LE32
> +#define le32toh LE32_TO_CPU
> +#define le16toh LE16_TO_CPU
> +#define htole16 CPU_TO_LE16

Why not cpu_to_le16() and friends? I gather because we then have fun
with types?

> +#define mutex_init(mutex)  init_lock(mutex)
> +#define mutex_lock(mutex) lock(mutex)
> +#define mutex_unlock(mutex) unlock(mutex)
> +#define mutex_t struct lock
> +
> +/* TPM PCR designations */
> +typedef enum
> +{
> +    PCR_0 = 0,
> +    PCR_1 = 1,
> +    PCR_2 = 2,
> +    PCR_3 = 3,
> +    PCR_4 = 4,
> +    PCR_5 = 5,
> +    PCR_6 = 6,
> +    PCR_7 = 7,
> +    IMPLEMENTATION_PCR = 24 // Number of PCRs implemented by TPM

By TPM2.0 spec? Or our specific TPM?

> +} TPM_Pcr;
> +
> +/**
> + * @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);
> +#endif
> +
> diff --git a/libstb/tss/trustedboot_reasoncodes.H b/libstb/tss/trustedboot_reasoncodes.H
> new file mode 100644
> index 0000000..2c63488
> --- /dev/null
> +++ b/libstb/tss/trustedboot_reasoncodes.H
> @@ -0,0 +1,88 @@
> +/* 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

Is this correct? we're having teh same component ID as hostboot here, is
that what we're aiming for?

> +#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_TPMLOGMGR_INITIALIZE        = 0x10,
> +        MOD_TPMLOGMGR_ADDEVENT          = 0x11,
> +        MOD_TPMLOGMGR_INITIALIZEEXISTLOG = 0x012,
> +   };
> +
> +    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,
> +    };
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif

-- 
Stewart Smith
OPAL Architect, IBM.



More information about the Skiboot mailing list