コード例 #1
0
void Unmarshal_TPMS_ALGORITHM_DETAIL_ECC(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_ALGORITHM_DETAIL_ECC *algorithmDetailEcc
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( algorithmDetailEcc == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &algorithmDetailEcc->curveID, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &algorithmDetailEcc->keySize, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMT_KDF_SCHEME( sysContext, &algorithmDetailEcc->kdf );
	Unmarshal_TPMT_ECC_SCHEME( sysContext, &algorithmDetailEcc->sign );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->p );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->a );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->b );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->gX );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->gY );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->n );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&algorithmDetailEcc->h );

	return;
}
コード例 #2
0
void Unmarshal_Simple_TPM2B_NoSizeCheck( UINT8 *outBuffPtr, UINT32 maxResponseSize, UINT8 **nextData, TPM2B *outTPM2B, TSS2_RC *rval )
{
//deleted for now--spec issues with nested TPM2B's
#if 0
    INT64 callerAllocatedSize;
#endif    
    int i;
    UINT16 length;
    
    if( *rval == TSS2_RC_SUCCESS )
    {
        if( outBuffPtr == 0 || nextData == 0 || *nextData == 0 )
        {
            *rval = TSS2_SYS_RC_BAD_REFERENCE;
        }
        else
        {
            if( *rval == TSS2_RC_SUCCESS )
            {
                length = CHANGE_ENDIAN_WORD( *(UINT16 *)*nextData );

                if( outTPM2B != 0 )
                {
                    Unmarshal_UINT16( outBuffPtr, maxResponseSize, nextData, &( outTPM2B->size ), rval );
                }
                else
                {
                    // Let low level function deal with NULL output pointer.
                    Unmarshal_UINT16( outBuffPtr, maxResponseSize, nextData, 0, rval );
                }

                if( *rval == TSS2_RC_SUCCESS )
                {
                    // Copy to output TPM2B.
                    for( i = 0; i < length; i++ )
                    {
                        if( outTPM2B != 0 )
                        {
                            Unmarshal_UINT8( outBuffPtr, maxResponseSize, nextData,  &( outTPM2B->buffer[i] ), rval );
                        }
                        else
                        {
                            // Let low level function deal with NULL output pointer.
                            Unmarshal_UINT8( outBuffPtr, maxResponseSize, nextData, 0, rval );
                        }

                        if( *rval != TSS2_RC_SUCCESS )
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
}
コード例 #3
0
ファイル: unmarshal-UINT16.c プロジェクト: 01org/TPM2.0-TSS
/**
 * Make a call to Unmarshal_UINT16 function that should succeed.
 * The *_setup function has already copied a UINT16 into a data buffer in
 * network byte order (marshalled form). This function uses the
 * Unmarshal_UINT16 function to get this UINT16 back out of the data buffer
 * and into the host by te order for comparison to the reference value
 * in the 'data_host' field of the marshal_uint16_data_t structure.
 */
void
unmarshal_UINT16_good (void **state)
{
    marshal_uint16_data_t *data;
    uint16_t               data_unmarshalled = 0;

    data = (marshal_uint16_data_t*)*state;
    uint8_t *nextData = data->buffer;

    Unmarshal_UINT16 (data->buffer,
                      data->buffer_size,
                      &nextData,
                      &data_unmarshalled,
                      &data->rc);
    /**
     * uint16_t that was unmarshalled from the data buffer should be equal to
     * the data_host member of the test data structure.
     */
    assert_int_equal (data_unmarshalled, data->data_host);
    /**
     * The Unmarshal_* functions advance the 'nextData' parameter by the size of
     * the marshalled data.
     */
    assert_int_equal (data->buffer, nextData - sizeof (uint16_t));
    /* Finally the return code should indicate success. */
    assert_int_equal (data->rc, TSS2_RC_SUCCESS);
}
コード例 #4
0
void Unmarshal_TPMS_NV_PUBLIC(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_NV_PUBLIC *nvPublic
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( nvPublic == 0 )
		return;

	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &nvPublic->nvIndex, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &nvPublic->nameAlg, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMA_NV( sysContext, &nvPublic->attributes );
	UNMARSHAL_SIMPLE_TPM2B( sysContext, (TPM2B *)&nvPublic->authPolicy );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &nvPublic->dataSize, &( SYS_CONTEXT->rval ) );

	return;
}
コード例 #5
0
void Unmarshal_TPMU_SYM_KEY_BITS(
	TSS2_SYS_CONTEXT *sysContext,
	TPMU_SYM_KEY_BITS *symKeyBits,
	UINT32 selector
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( symKeyBits == 0 )
		return;

	switch( selector )
	{
#ifdef TPM_ALG_AES
	case TPM_ALG_AES:
			Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &symKeyBits->aes, &( SYS_CONTEXT->rval ) );
			break;
#endif
#ifdef TPM_ALG_SM4
	case TPM_ALG_SM4:
			Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &symKeyBits->sm4, &( SYS_CONTEXT->rval ) );
			break;
#endif
#ifdef TPM_ALG_CAMELLIA
	case TPM_ALG_CAMELLIA:
			Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &symKeyBits->camellia, &( SYS_CONTEXT->rval ) );
			break;
#endif
#ifdef TPM_ALG_XOR
	case TPM_ALG_XOR:
			Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &symKeyBits->exclusiveOr, &( SYS_CONTEXT->rval ) );
			break;
#endif
#ifdef TPM_ALG_NULL
	case TPM_ALG_NULL:
					break;
#endif
	}
	return;
}
コード例 #6
0
void Unmarshal_TPMS_SCHEME_HASH(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_SCHEME_HASH *schemeHash
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( schemeHash == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &schemeHash->hashAlg, &( SYS_CONTEXT->rval ) );

	return;
}
コード例 #7
0
void Unmarshal_TPMT_RSA_SCHEME(
	TSS2_SYS_CONTEXT *sysContext,
	TPMT_RSA_SCHEME *rsaScheme
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( rsaScheme == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &rsaScheme->scheme, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMU_ASYM_SCHEME( sysContext, &rsaScheme->details, rsaScheme->scheme );

	return;
}
コード例 #8
0
void Unmarshal_TPMS_ALG_PROPERTY(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_ALG_PROPERTY *algProperty
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( algProperty == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &algProperty->alg, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMA_ALGORITHM( sysContext, &algProperty->algProperties );

	return;
}
コード例 #9
0
void Unmarshal_TPMS_NV_CERTIFY_INFO(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_NV_CERTIFY_INFO *nvCertifyInfo
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( nvCertifyInfo == 0 )
		return;

	UNMARSHAL_SIMPLE_TPM2B( sysContext, (TPM2B *)&nvCertifyInfo->indexName );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &nvCertifyInfo->offset, &( SYS_CONTEXT->rval ) );
	UNMARSHAL_SIMPLE_TPM2B( sysContext, (TPM2B *)&nvCertifyInfo->nvContents );

	return;
}
コード例 #10
0
void Unmarshal_TPMT_TK_HASHCHECK(
	TSS2_SYS_CONTEXT *sysContext,
	TPMT_TK_HASHCHECK *tkHashcheck
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( tkHashcheck == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &tkHashcheck->tag, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &tkHashcheck->hierarchy, &( SYS_CONTEXT->rval ) );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&tkHashcheck->digest );

	return;
}
コード例 #11
0
void Unmarshal_TPMT_TK_AUTH(
	TSS2_SYS_CONTEXT *sysContext,
	TPMT_TK_AUTH *tkAuth
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( tkAuth == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &tkAuth->tag, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &tkAuth->hierarchy, &( SYS_CONTEXT->rval ) );
	UNMARSHAL_SIMPLE_TPM2B( sysContext, (TPM2B *)&tkAuth->digest );

	return;
}
コード例 #12
0
void Unmarshal_TPMS_RSA_PARMS(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_RSA_PARMS *rsaParms
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( rsaParms == 0 )
		return;

	Unmarshal_TPMT_SYM_DEF_OBJECT( sysContext, &rsaParms->symmetric );
	Unmarshal_TPMT_RSA_SCHEME( sysContext, &rsaParms->scheme );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &rsaParms->keyBits, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &rsaParms->exponent, &( SYS_CONTEXT->rval ) );

	return;
}
コード例 #13
0
void Unmarshal_TPMS_COMMAND_AUDIT_INFO(
    TSS2_SYS_CONTEXT *sysContext,
    TPMS_COMMAND_AUDIT_INFO *commandAuditInfo
)
{
    if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
        return;

    if( commandAuditInfo == 0 )
        return;

    Unmarshal_UINT64( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &commandAuditInfo->auditCounter, &( SYS_CONTEXT->rval ) );
    Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &commandAuditInfo->digestAlg, &( SYS_CONTEXT->rval ) );
    UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&commandAuditInfo->auditDigest );
    UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&commandAuditInfo->commandDigest );

    return;
}
コード例 #14
0
void Unmarshal_TPM2B_SENSITIVE(
	TSS2_SYS_CONTEXT *sysContext,
	TPM2B_SENSITIVE *sensitive
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( sensitive == 0 )
		return;

	if( sensitive->t.size != 0 )
		SYS_CONTEXT->rval = TSS2_SYS_RC_BAD_VALUE;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &sensitive->t.size, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMT_SENSITIVE( sysContext, &sensitive->t.sensitiveArea );

	return;
}
コード例 #15
0
void Unmarshal_TPM2B_PUBLIC(
	TSS2_SYS_CONTEXT *sysContext,
	TPM2B_PUBLIC *publicVar
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( publicVar == 0 )
		return;

	if( publicVar->t.size != 0 )
		SYS_CONTEXT->rval = TSS2_SYS_RC_BAD_VALUE;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &publicVar->t.size, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMT_PUBLIC( sysContext, &publicVar->t.publicArea );

	return;
}
コード例 #16
0
void Unmarshal_TPM2B_NV_PUBLIC(
	TSS2_SYS_CONTEXT *sysContext,
	TPM2B_NV_PUBLIC *nvPublic
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( nvPublic == 0 )
		return;

	if( nvPublic->t.size != 0 )
		SYS_CONTEXT->rval = TSS2_SYS_RC_BAD_VALUE;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &nvPublic->t.size, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMS_NV_PUBLIC( sysContext, &nvPublic->t.nvPublic );

	return;
}
コード例 #17
0
TPM_RC Tss2_Sys_EC_Ephemeral_Complete(
    TSS2_SYS_CONTEXT *sysContext,
    TPM2B_ECC_POINT	*Q,
    UINT16	*counter
    )
{
    if( sysContext == NULL )
    {
        return( TSS2_SYS_RC_BAD_REFERENCE );
    }

    CommonComplete( sysContext );

    Unmarshal_TPM2B_ECC_POINT( sysContext, Q );

    Unmarshal_UINT16( SYS_CONTEXT->tpmInBuffPtr, SYS_CONTEXT->maxCommandSize, &(SYS_CONTEXT->nextData), counter, &(SYS_CONTEXT->rval) );

    return SYS_CONTEXT->rval;
}
コード例 #18
0
void Unmarshal_TPMS_ATTEST(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_ATTEST *attest
	)
{
	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( attest == 0 )
		return;

	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &attest->magic, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &attest->type, &( SYS_CONTEXT->rval ) );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&attest->qualifiedSigner );
	UNMARSHAL_SIMPLE_TPM2B_NO_SIZE_CHECK( sysContext, (TPM2B *)&attest->extraData );
	Unmarshal_TPMS_CLOCK_INFO( sysContext, &attest->clockInfo );
	Unmarshal_UINT64( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &attest->firmwareVersion, &( SYS_CONTEXT->rval ) );
	Unmarshal_TPMU_ATTEST( sysContext, &attest->attested, attest->type );

	return;
}
コード例 #19
0
ファイル: Unmarshal_TPML_ALG.c プロジェクト: KunYi/TPM2.0-TSS
void Unmarshal_TPML_ALG(
	TSS2_SYS_CONTEXT *sysContext,
	TPML_ALG *alg
	)
{
	UINT32	i;

	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( alg == 0 )
		return;

	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &alg->count, &( SYS_CONTEXT->rval ) );

	for( i = 0; i < alg->count; i++ )
	{
		Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &alg->algorithms[i], &( SYS_CONTEXT->rval ) );
	}

	return;
}
コード例 #20
0
void Unmarshal_TPML_ECC_CURVE(
	TSS2_SYS_CONTEXT *sysContext,
	TPML_ECC_CURVE *eccCurve
	)
{
	UINT32	i;

	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( eccCurve == 0 )
		return;

	Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &eccCurve->count, &( SYS_CONTEXT->rval ) );

	for( i = 0; i < eccCurve->count; i++ )
	{
		Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &eccCurve->eccCurves[i], &( SYS_CONTEXT->rval ) );
	}

	return;
}
コード例 #21
0
void Unmarshal_TPMS_PCR_SELECTION(
	TSS2_SYS_CONTEXT *sysContext,
	TPMS_PCR_SELECTION *pcrSelection
	)
{
	UINT32	i;

	if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
		return;

	if( pcrSelection == 0 )
		return;

	Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &pcrSelection->hash, &( SYS_CONTEXT->rval ) );
	Unmarshal_UINT8( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &pcrSelection->sizeofSelect, &( SYS_CONTEXT->rval ) );

	for( i = 0; i < pcrSelection->sizeofSelect; i++ )
	{
		Unmarshal_UINT8( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize, &(SYS_CONTEXT->nextData), &pcrSelection->pcrSelect[i], &( SYS_CONTEXT->rval ) );
	}

	return;
}
コード例 #22
0
ファイル: execute.c プロジェクト: dandantx/TPM2.0-TSS
TSS2_RC Tss2_Sys_ExecuteFinish(
    TSS2_SYS_CONTEXT 		*sysContext,
    int32_t                 timeout
    )
{
    TSS2_RC  rval = TSS2_RC_SUCCESS;
    size_t responseSize = 0;
    UINT8 tpmError = 0;
    
    if( sysContext == 0 )
    {
        rval = TSS2_SYS_RC_BAD_REFERENCE;
    }
    else if( SYS_CONTEXT->previousStage != CMD_STAGE_SEND_COMMAND )
    {
        rval = TSS2_SYS_RC_BAD_SEQUENCE;
    }
    else
    {
        responseSize = SYS_CONTEXT->maxResponseSize;
        
        rval = (*( TCTI_CONTEXT )->receive)
                ( SYS_CONTEXT->tctiContext, (size_t *)&responseSize, SYS_CONTEXT->tpmOutBuffPtr, timeout );
    }

    if( rval == TSS2_RC_SUCCESS )
    {
        if( responseSize < sizeof( TPM20_ErrorResponse ) )
        {
            rval = TSS2_SYS_RC_INSUFFICIENT_RESPONSE;
        }
        else
        {
            // Unmarshal the tag, response size, and response code here so that nextData pointer
            // is set up for getting response handles.  This avoids having to put special code
            // in each Part 3 command's Complete function for this.
            SYS_CONTEXT->nextData = SYS_CONTEXT->tpmOutBuffPtr;

            Unmarshal_UINT16( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxCommandSize, &(SYS_CONTEXT->nextData), 0, &(SYS_CONTEXT->rval) ); 
            Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxCommandSize, &(SYS_CONTEXT->nextData), (UINT32 *)&responseSize, &(SYS_CONTEXT->rval) ); 

            if( responseSize < ( sizeof( TPM20_Header_Out ) - 1 ) )
            {
                rval = SYS_CONTEXT->rval = TSS2_SYS_RC_INSUFFICIENT_RESPONSE;
            }
            else
            {
                Unmarshal_UINT32( SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxCommandSize, &(SYS_CONTEXT->nextData), &(SYS_CONTEXT->rval), &rval );

                // Return TPM return code if no other errors have occured.
                if( rval == TSS2_RC_SUCCESS )
                {   
                    if( SYS_CONTEXT->rval != TPM_RC_SUCCESS )
                    {
                        tpmError = 1;
                        SYS_CONTEXT->responseCode = rval = SYS_CONTEXT->rval;
                    }
                }
            }
        }

        // If we received a TPM error other than CANCELED or if we didn't receive enough response bytes,
        // reset SAPI state machine to CMD_STAGE_PREPARE.  There's nothing
        // else we can do for current command.
        if( ( tpmError && rval != TPM_RC_CANCELED ) || ( rval == TSS2_SYS_RC_INSUFFICIENT_RESPONSE ) )
        {
            SYS_CONTEXT->previousStage = CMD_STAGE_PREPARE;
        }
        else
        {
            SYS_CONTEXT->previousStage = CMD_STAGE_RECEIVE_RESPONSE;
            SYS_CONTEXT->responseCode = SYS_CONTEXT->rval;
        }
    }

    return rval;
}