Ejemplo n.º 1
0
TSS2_RC LocalTpmSendTpmCommand(
    TSS2_TCTI_CONTEXT *tctiContext,       /* in */
    size_t             command_size,      /* in */
    uint8_t           *command_buffer     /* in */
    )
{
    TSS2_RC rval = TSS2_RC_SUCCESS;
    ssize_t size;

#ifdef DEBUG
    UINT32 commandCode = CHANGE_ENDIAN_DWORD( ( (TPM20_Header_In *)command_buffer )->commandCode );
    UINT32 cnt = CHANGE_ENDIAN_DWORD(((TPM20_Header_In *) command_buffer)->commandSize);

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
        (*tpmLocalTpmPrintf)( rmDebugPrefix, "\n" );
        (*tpmLocalTpmPrintf)(rmDebugPrefix, "Cmd sent: %s\n", commandCodeStrings[ commandCode - TPM_CC_FIRST ]  );
        DEBUG_PRINT_BUFFER( command_buffer, cnt );
    }
#endif

    size = write( ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->devFile, command_buffer, command_size );

    if( size < 0 )
    {
        (*tpmLocalTpmPrintf)(NO_PREFIX, "send failed with error: %d\n", errno );
        rval = TSS2_TCTI_RC_IO_ERROR;
    }
    else if( (size_t)size != command_size )
    {        
        rval = TSS2_TCTI_RC_IO_ERROR;
    }

    return rval;
}
Ejemplo n.º 2
0
//
// Copy session data for commands that require it.
//
// Inputs:
//
//      pointer to pointer to sessionData area of command
//
//      pointer to session data to be copied into command buffer
//
// Outputs:
//
//      sessionDataPtr points to end byte past command buffer.  This allows
//          caller to set the commandSize field for the command.
//
TSS2_RC CopySessionDataIn( void **otherData, TPMS_AUTH_COMMAND const *sessionData, UINT32 *sessionSizePtr )
{
    TSS2_RC rval = TSS2_RC_SUCCESS;
    UINT8 *inBuffPtr = *otherData;
    TPMS_AUTH_COMMAND *sessionDataCopy = (TPMS_AUTH_COMMAND *)sessionData;
    
	if( sessionData == 0 )
	{
		rval = TSS2_SYS_RC_BAD_VALUE;
		goto exitCopySessionDataIn;
	}

    // Size of session data
    *sessionSizePtr += CHANGE_ENDIAN_DWORD(  
            sizeof( TPMI_SH_AUTH_SESSION ) + sizeof( UINT16 ) +
            sessionData->nonce.t.size + sizeof( UINT8 ) +
            sizeof( UINT16 ) + sessionData->hmac.t.size );  

    // copy session handle
    SESSION_MARSHAL_UINT32( inBuffPtr, *sessionSizePtr, (UINT8 **)otherData, sessionDataCopy->sessionHandle, &rval, exitCopySessionDataIn );

    // Copy nonce
    SESSION_MARSHAL_SIMPLE_TPM2B( inBuffPtr, *sessionSizePtr, (UINT8 **)otherData, &( sessionDataCopy->nonce.b ), &rval, exitCopySessionDataIn );

    // Copy attributes
    SESSION_MARSHAL_UINT8( inBuffPtr, *sessionSizePtr, (UINT8 **)otherData, (UINT8)( sessionDataCopy->sessionAttributes.val ), &rval, exitCopySessionDataIn );

    // Copy hmac data.
    SESSION_MARSHAL_SIMPLE_TPM2B( inBuffPtr, *sessionSizePtr, (UINT8 **)otherData, &( sessionDataCopy->hmac.b ), &rval, exitCopySessionDataIn );

exitCopySessionDataIn:
    return rval;
}
Ejemplo n.º 3
0
TSS2_RC Tss2_Sys_ExecuteAsync(
    TSS2_SYS_CONTEXT 		*sysContext
    )
{
    TSS2_RC  rval = TSS2_RC_SUCCESS;

    if( sysContext == 0 )
    {
        rval = TSS2_SYS_RC_BAD_REFERENCE;
    }
    else if( SYS_CONTEXT->previousStage != CMD_STAGE_PREPARE )
    {
        rval = TSS2_SYS_RC_BAD_SEQUENCE;
    }
    else
    {
        rval = (*( TCTI_CONTEXT )->transmit)( SYS_CONTEXT->tctiContext,
            CHANGE_ENDIAN_DWORD( ((TPM20_Header_In *)SYS_CONTEXT->tpmInBuffPtr )->commandSize),
            SYS_CONTEXT->tpmInBuffPtr );
    }

    if( rval == TSS2_RC_SUCCESS )
    {
        SYS_CONTEXT->previousStage = CMD_STAGE_SEND_COMMAND;    
    }
    return rval;
}
Ejemplo n.º 4
0
void CopyCommandHeader( _TSS2_SYS_CONTEXT_BLOB *sysContext, TPM_CC commandCode )
{
   SYS_CONTEXT->rval = TSS2_RC_SUCCESS;
  
  ((TPM20_Header_In *) sysContext->tpmInBuffPtr)->tag = CHANGE_ENDIAN_WORD( TPM_ST_NO_SESSIONS );

  ((TPM20_Header_In *) sysContext->tpmInBuffPtr)->commandCode = CHANGE_ENDIAN_DWORD( commandCode );

  SYS_CONTEXT->rval = TSS2_RC_SUCCESS;

  SYS_CONTEXT->nextData = SYS_CONTEXT->tpmInBuffPtr + sizeof( TPM20_Header_In );
}
UINT32 TpmHandleToName( TPM_HANDLE handle, TPM2B_NAME *name )
{
    TPM_RC rval;
    TPM2B_NAME qualifiedName;
    TPM2B_PUBLIC public;
    TPM2B_NV_PUBLIC nvPublic;
    TSS2_SYS_CONTEXT *sysContext;
    UINT8 *namePtr = &( name->t.name[0] );
    
    // Initialize name to zero length in case of failure.
    qualifiedName.b.size = sizeof( TPM2B_NAME ) - 2;
    name->b.size = sizeof( TPM2B_NAME ) - 2;

    if( handle == ( TPM_HT_NO_HANDLE ) )
    {
        name->b.size = 0;
        rval = TPM_RC_SUCCESS;
    }
    else
    {
        switch( handle >> HR_SHIFT )
        {
            case TPM_HT_NV_INDEX:
                sysContext = InitSysContext( 1000, resMgrTctiContext, &abiVersion );
                if( sysContext == 0 )
                    return TSS2_APP_RC_INIT_SYS_CONTEXT_FAILED;

                nvPublic.t.size = 0;
                rval = Tss2_Sys_NV_ReadPublic( sysContext, handle, 0, &nvPublic, name, 0 );
                TeardownSysContext( &sysContext );
                break;  

            case TPM_HT_TRANSIENT:
            case TPM_HT_PERSISTENT:
                sysContext = InitSysContext( 1000, resMgrTctiContext, &abiVersion );
                if( sysContext == 0 )
                    return TSS2_APP_RC_INIT_SYS_CONTEXT_FAILED;

                public.t.size = 0;
				rval = Tss2_Sys_ReadPublic( sysContext, handle, 0, &public, name, &qualifiedName, 0 );
                TeardownSysContext( &sysContext );
                break;
                    
            default:
                rval = TPM_RC_SUCCESS;
                name->b.size = sizeof( TPM_HANDLE );
                *(TPM_HANDLE *)namePtr = CHANGE_ENDIAN_DWORD( handle );
        }
    }
Ejemplo n.º 6
0
void Marshal_UINT32( UINT8 *inBuffPtr, UINT32 maxCommandSize, UINT8 **nextData, UINT32 value, TSS2_RC *rval )
{
    if( *rval != TSS2_RC_SUCCESS )
        return;

    *rval = CheckDataPointers( inBuffPtr, nextData );
    if( *rval != TSS2_RC_SUCCESS )
        return;

    *rval = CheckOverflow( inBuffPtr, maxCommandSize, *nextData, sizeof(UINT32) );
    if( *rval != TSS2_RC_SUCCESS )
        return;

    *( (UINT32 *)*nextData ) = CHANGE_ENDIAN_DWORD( value );
    *nextData = *nextData + sizeof( UINT32 );
}
Ejemplo n.º 7
0
// Common to all _Prepare
TSS2_RC CommonPrepareEpilogue(
    TSS2_SYS_CONTEXT *sysContext
)
{
   if( SYS_CONTEXT->rval != TSS2_RC_SUCCESS )
   {
       return SYS_CONTEXT->rval;
   }
   SYS_CONTEXT->cpBufferUsedSize = SYS_CONTEXT->nextData - SYS_CONTEXT->cpBuffer;

   // Set current command size.
   ((TPM20_Header_In *) SYS_CONTEXT->tpmInBuffPtr)->commandSize =
           CHANGE_ENDIAN_DWORD( SYS_CONTEXT->nextData - SYS_CONTEXT->tpmInBuffPtr );

   SYS_CONTEXT->previousStage = CMD_STAGE_PREPARE;

   return SYS_CONTEXT->rval;
}
Ejemplo n.º 8
0
TSS2_RC SocketSendSessionEnd(
    TSS2_TCTI_CONTEXT *tctiContext,       /* in */
    UINT8 tpmCmdServer )
{
    UINT32 tpmSendCommand = TPM_SESSION_END;  // Value for "send command" to MS simulator.
    SOCKET sock;

    if( tpmCmdServer )
    {
        sock = TCTI_CONTEXT_INTEL->tpmSock;
    }
    else
    {
        sock = TCTI_CONTEXT_INTEL->otherSock;
    }
        
    tpmSendCommand = CHANGE_ENDIAN_DWORD(tpmSendCommand);
    sendBytes( sock, (char *)&tpmSendCommand, 4 );

    return( TSS2_RC_SUCCESS );
}
Ejemplo n.º 9
0
// Common to all _Prepare
TSS2_RC CommonPreparePrologue(
    TSS2_SYS_CONTEXT *sysContext,
    TPM_CC commandCode 
)
{
	int numCommandHandles;

    if( sysContext == NULL )
    {
        return SYS_CONTEXT->rval = TSS2_SYS_RC_BAD_REFERENCE;
    }

    InitSysContextFields( sysContext );

    // Need to check stage here.
    if( SYS_CONTEXT->previousStage != CMD_STAGE_INITIALIZE &&
            SYS_CONTEXT->previousStage != CMD_STAGE_RECEIVE_RESPONSE &&
            SYS_CONTEXT->previousStage != CMD_STAGE_PREPARE  )
    {
        SYS_CONTEXT->rval = TSS2_SYS_RC_BAD_SEQUENCE;
    }
    else
    {
        CopyCommandHeader( SYS_CONTEXT, commandCode );

        SYS_CONTEXT->numResponseHandles = GetNumResponseHandles( commandCode );

        SYS_CONTEXT->commandCodeSwapped = CHANGE_ENDIAN_DWORD( commandCode );

        SYS_CONTEXT->paramsSize = (UINT32 *)&(((TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->otherData ) +
                GetNumResponseHandles( commandCode );

        numCommandHandles = GetNumCommandHandles( commandCode );
        SYS_CONTEXT->cpBuffer = SYS_CONTEXT->nextData + numCommandHandles * sizeof(UINT32);
    }

    return SYS_CONTEXT->rval;
}
Ejemplo n.º 10
0
TSS2_RC LocalTpmReceiveTpmResponse(
    TSS2_TCTI_CONTEXT *tctiContext,     /* in */
    size_t          *response_size,     /* out */
    unsigned char   *response_buffer,    /* in */
    int32_t         timeout
    )
{
    TSS2_RC rval = TSS2_RC_SUCCESS;
    ssize_t  size;

    size = read( ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->devFile, response_buffer, *response_size );

    if( size < 0 )
    {
        (*tpmLocalTpmPrintf)(NO_PREFIX, "send failed with error: %d\n", errno );
        rval = TSS2_TCTI_RC_IO_ERROR;
        *response_size = 0;
    }
    else
    {
#ifdef DEBUG
        UINT32 cnt = CHANGE_ENDIAN_DWORD(((TPM20_Header_Out *) response_buffer)->responseSize);

        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
        {
            (*tpmLocalTpmPrintf)( rmDebugPrefix, "\n" );
            (*tpmLocalTpmPrintf)( rmDebugPrefix, "Response Received: " );
            DEBUG_PRINT_BUFFER( response_buffer, cnt );
        }
#endif
    
        *response_size = size;
    }

    return rval;
}
Ejemplo n.º 11
0
TSS2_RC Tss2_Sys_SetCmdAuths(
    TSS2_SYS_CONTEXT            *sysContext,
    const TSS2_SYS_CMD_AUTHS 	*cmdAuthsArray
    )
{
    TSS2_RC rval = TSS2_RC_SUCCESS;
    
    if( sysContext == NULL || cmdAuthsArray == 0 )
    {
        rval = TSS2_SYS_RC_BAD_REFERENCE;
    }
    else
    {
        SYS_CONTEXT->authsCount = 0;

        if( cmdAuthsArray->cmdAuthsCount > MAX_SESSION_NUM )
        {
            rval = TSS2_SYS_RC_BAD_VALUE;
        }
        else if( SYS_CONTEXT->previousStage != CMD_STAGE_PREPARE )
        {
            rval = TSS2_SYS_RC_BAD_SEQUENCE;
        }
        else if( SYS_CONTEXT->authAllowed != 1 )
        {
            // Don't do anything.  Let the TPM return an error code.
        }
        else
        {
            uint8_t i;
            UINT32 authSize = 0;
            UINT64 newCmdSize = 0;

            if( cmdAuthsArray->cmdAuthsCount > 0 )
            {
                // Change command tag.
                ( (TPM20_Header_In *)( SYS_CONTEXT->tpmInBuffPtr ) )->tag = CHANGE_ENDIAN_WORD( TPM_ST_SESSIONS );

                // Calculate size needed for authorization area
                // and check for any null pointers.
                // Also check for decrypt/encrypt sessions.
                for( i = 0; i < cmdAuthsArray->cmdAuthsCount; i++ )
                {
                    // Check for null pointer.
                    if( cmdAuthsArray->cmdAuths[i] == 0 )
                    {
                        rval = TSS2_SYS_RC_BAD_VALUE;
                        break;
                    }
                    authSize += sizeof( TPMI_SH_AUTH_SESSION ); // Handle
                    authSize += sizeof( UINT16 ) + cmdAuthsArray->cmdAuths[i]->nonce.t.size; // nonce
                    authSize += sizeof( UINT8 ); // sessionAttribues
                    authSize += sizeof( UINT16 ) + cmdAuthsArray->cmdAuths[i]->hmac.t.size; // hmac

                    // Check for decrypt/encrypt sessions and set flags.   This is
                    // done to support the one-call function.
                    if( cmdAuthsArray->cmdAuths[i]->sessionAttributes.decrypt )
                        SYS_CONTEXT->decryptSession = 1;

                    if( cmdAuthsArray->cmdAuths[i]->sessionAttributes.encrypt )
                        SYS_CONTEXT->encryptSession = 1;
                }

                if( rval == TSS2_RC_SUCCESS )
                {
                    authSize += sizeof( UINT32 ); // authorization size field
                    newCmdSize = (UINT64)authSize + (UINT64)CHANGE_ENDIAN_DWORD( ( (TPM20_Header_In *)( SYS_CONTEXT->tpmInBuffPtr ) )->commandSize );

                    if( newCmdSize > (UINT64)( SYS_CONTEXT->maxCommandSize ) )
                    {
                        rval = TSS2_SYS_RC_INSUFFICIENT_BUFFER;
                    }
                    else
                    {
                        void *otherData;

                        // We're going to have to move stuff around.
                        // First move current cpBuffer down.
                        rval = CopyMemReverse( SYS_CONTEXT->cpBuffer + authSize, SYS_CONTEXT->cpBuffer, SYS_CONTEXT->cpBufferUsedSize, SYS_CONTEXT->tpmInBuffPtr + SYS_CONTEXT->maxCommandSize );

                        if( rval == TSS2_RC_SUCCESS )
                        {
                            // Now copy in the authorization area.
                            otherData = SYS_CONTEXT->cpBuffer;
                            rval = CopySessionsDataIn( &otherData, cmdAuthsArray );

                            // Update cpBuffer        
                            SYS_CONTEXT->cpBuffer += authSize;

                            // Now update the command size.
                            ( (TPM20_Header_In *)( SYS_CONTEXT->tpmInBuffPtr ) )->commandSize = CHANGE_ENDIAN_DWORD( (UINT32)newCmdSize );

                            SYS_CONTEXT->authsCount = cmdAuthsArray->cmdAuthsCount;
                        }
                    }
                }
            }
        }
    }
    return rval;
}
Ejemplo n.º 12
0
TSS2_RC SocketReceiveTpmResponse(
    TSS2_TCTI_CONTEXT *tctiContext,     /* in */
    size_t          *response_size,     /* out */
    unsigned char   *response_buffer,    /* in */
    int32_t         timeout
    )
{
    UINT32 trash;
    size_t responseSize = 0;
    TSS2_RC rval = TSS2_RC_SUCCESS;
    fd_set readFds;
    struct timeval tv, *tvPtr;
    int32_t timeoutMsecs = timeout % 1000;
    int iResult;
    
    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
#ifdef DEBUG
        (*printfFunction)( rmDebugPrefix, "Response Received: " );
#endif
#ifdef DEBUG_SOCKETS
         (*printfFunction)( rmDebugPrefix, "from socket #0x%x:\n", TCTI_CONTEXT_INTEL->tpmSock );
#endif
    }

    if( *response_size > 0 )
    {
        if( timeout == TSS2_TCTI_TIMEOUT_BLOCK )
        {
            tvPtr = 0;
        }
        else
        {
            tv.tv_sec = timeout / 1000;
            tv.tv_usec = timeoutMsecs * 1000;
            tvPtr = &tv;
        }

        FD_ZERO( &readFds );
        FD_SET( TCTI_CONTEXT_INTEL->tpmSock, &readFds );

        iResult = select( TCTI_CONTEXT_INTEL->tpmSock+1, &readFds, 0, 0, tvPtr );
        if( iResult == 0 )
        {
            (*printfFunction)(NO_PREFIX, "select failed due to timeout, socket #: 0x%x\n", TCTI_CONTEXT_INTEL->tpmSock );
            rval = TSS2_TCTI_RC_TRY_AGAIN;
            goto retSocketReceiveTpmResponse;
        }
        else if( iResult == SOCKET_ERROR )
        {
            (*printfFunction)(NO_PREFIX, "select failed with socket error: %d\n", WSAGetLastError() );
            rval = TSS2_TCTI_RC_IO_ERROR;
            goto retSocketReceiveTpmResponse;
        }
        else if ( iResult != 1 )
        {
            (*printfFunction)(NO_PREFIX, "select failed, read the wrong # of bytes: %d\n", iResult );
            rval = TSS2_TCTI_RC_IO_ERROR;
            goto retSocketReceiveTpmResponse;
        }

        // Receive the size of the response.
        recvBytes( TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&responseSize, 4 );
        
		responseSize = CHANGE_ENDIAN_DWORD( responseSize );
                
        // Receive the TPM response.
        recvBytes( TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)response_buffer, responseSize );

#ifdef DEBUG
        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
        {
            DEBUG_PRINT_BUFFER( response_buffer, responseSize );
        }
#endif    

        // Receive the appended four bytes of 0's
        recvBytes( TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&trash, 4 );
    }

    if( responseSize < *response_size )
    {
        *response_size = responseSize;
    }
    
    ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent = 0;

    // Turn cancel off.
    rval = (TSS2_RC)PlatformCommand( tctiContext, MS_SIM_CANCEL_OFF );

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
//        (*printfFunction)(NO_PREFIX,  "%s sent cancel OFF command:\n", interfaceName );
    }

retSocketReceiveTpmResponse:
    return rval;
}
Ejemplo n.º 13
0
TSS2_RC SocketSendTpmCommand(
    TSS2_TCTI_CONTEXT *tctiContext,       /* in */
    size_t             command_size,      /* in */
    uint8_t           *command_buffer     /* in */
    )
{
    UINT32 tpmSendCommand = MS_SIM_TPM_SEND_COMMAND;  // Value for "send command" to MS simulator.
    UINT32 cnt, cnt1;
    UINT8 locality;
#ifdef SAPI_CLIENT    
    UINT8 debugMsgLevel, statusBits;
#endif

    UINT32 commandCode = CHANGE_ENDIAN_DWORD( ( (TPM20_Header_In *)command_buffer )->commandCode );

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
#ifdef DEBUG
        (*printfFunction)(NO_PREFIX, "\n" );
        if( commandCode >= TPM_CC_NV_UndefineSpaceSpecial && commandCode <= TPM_CC_PolicyNvWritten )     
            (*printfFunction)(rmDebugPrefix, "Cmd sent: %s\n", commandCodeStrings[ commandCode - TPM_CC_FIRST ] );            
        else
            (*printfFunction)(rmDebugPrefix, "Cmd sent: 0x%4.4x\n", CHANGE_ENDIAN_DWORD(commandCode ) );
#endif
#ifdef DEBUG_SOCKETS
        (*printfFunction)(rmDebugPrefix, "Command sent on socket #0x%x: %s\n", TCTI_CONTEXT_INTEL->tpmSock, commandCodeStrings[ commandCode - TPM_CC_FIRST ]  );
#endif        
    }
    // Size TPM 1.2 and TPM 2.0 headers overlap exactly, we can use
    // either 1.2 or 2.0 header to get the size.
    cnt = CHANGE_ENDIAN_DWORD(((TPM20_Header_In *) command_buffer)->commandSize);

    // Send TPM_SEND_COMMAND
    tpmSendCommand = CHANGE_ENDIAN_DWORD(tpmSendCommand);
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)&tpmSendCommand, 4 );
        
    // Send the locality
    locality = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.locality;
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)&locality, 1 );

#ifdef SAPI_CLIENT    
    // Send the debug level
    debugMsgLevel = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.debugMsgLevel;
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)&debugMsgLevel, 1 );

    // Send status bits
    statusBits = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent;
    statusBits |= ( (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.rmDebugPrefix ) << 1;
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)&statusBits, 1 );
#endif
    
#ifdef DEBUG
    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
        (*printfFunction)(rmDebugPrefix, "Locality = %d", ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.locality );
    }
#endif
    
    // Send number of bytes.
    cnt1 = cnt;
    cnt = CHANGE_ENDIAN_DWORD(cnt);
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)&cnt, 4 );
    
    // Send the TPM command buffer
    sendBytes( TCTI_CONTEXT_INTEL->tpmSock, (char *)command_buffer, cnt1 );
    
#ifdef DEBUG
    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
        DEBUG_PRINT_BUFFER( command_buffer, cnt1 );
    }
#endif
    ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent = 1;

    return TSS2_RC_SUCCESS;
}
Ejemplo n.º 14
0
UINT32 GetCommandSize( TSS2_SYS_CONTEXT *sysContext )
{
    return( CHANGE_ENDIAN_DWORD( ((TPM20_Header_In *) SYS_CONTEXT->tpmInBuffPtr)->commandSize  ) );
}
Ejemplo n.º 15
0
//
// This function is a helper function used to calculate cpHash and rpHash.
//
// NOTE:  for calculating cpHash, set responseCode to TPM_RC_NO_RESPONSE; this
// tells the function to leave it out of the calculation.
//
TPM_RC TpmCalcPHash( TSS2_SYS_CONTEXT *sysContext, TPM_HANDLE handle1, TPM_HANDLE handle2,
    TPMI_ALG_HASH authHash, TPM_RC responseCode, TPM2B_DIGEST *pHash )
{
    TPM_RC rval = TPM_RC_SUCCESS;
    UINT32 i;
    TPM2B_NAME name1;
    TPM2B_NAME name2;
    TPM2B_MAX_BUFFER hashInput; // Byte stream to be hashed to create pHash
    UINT8 *hashInputPtr;
    size_t parametersSize;
    const uint8_t *startParams;
    UINT8 cmdCode[4] = {0,0,0,0};
    UINT8 *cmdCodePtr = &cmdCode[0];
    
    name1.b.size = name2.b.size = 0;
    
    // Calculate pHash
    //

    // Only get names for commands
    if( responseCode == TPM_RC_NO_RESPONSE )
    {
        // Get names for the handles
        rval = TpmHandleToName( handle1, &name1 );
        if( rval != TPM_RC_SUCCESS )
            return rval;
    }

#ifdef DEBUG
    OpenOutFile( &outFp );
    TpmClientPrintf( 0, "\n\nNAME1 = \n" );
    PrintSizedBuffer( &(name1.b) );
    CloseOutFile( &outFp );
#endif
    
    // Only get names for commands
    if( responseCode == TPM_RC_NO_RESPONSE )
    {
        rval = Tss2_Sys_GetCpBuffer( sysContext, &parametersSize, &startParams);
        if( rval != TPM_RC_SUCCESS )
            return rval;

        rval = TpmHandleToName( handle2, &name2 );
        if( rval != TPM_RC_SUCCESS )
            return rval;
    }
    else
    {
        rval = Tss2_Sys_GetRpBuffer( sysContext, &parametersSize, &startParams);
        if( rval != TPM_RC_SUCCESS )
            return rval;
    }
    
#ifdef DEBUG
    OpenOutFile( &outFp );
    TpmClientPrintf( 0, "\n\nNAME2 = \n" );
    PrintSizedBuffer( &(name2.b) );
    CloseOutFile( &outFp );
#endif
    
    // Create pHash input byte stream:  first add response code, if any.
    hashInput.b.size = 0;
    if( responseCode != TPM_RC_NO_RESPONSE )
    {
        hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );
        *(UINT32 *)hashInputPtr = CHANGE_ENDIAN_DWORD( responseCode );
        hashInput.b.size += 4;
        hashInputPtr += 4;
    }

    // Create pHash input byte stream:  now add command code.
    rval = Tss2_Sys_GetCommandCode( sysContext, &cmdCode );
    if( rval != TPM_RC_SUCCESS )
        return rval;

    hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );    
    *(UINT32 *)hashInputPtr = CHANGE_ENDIAN_DWORD( *(UINT32 *)cmdCodePtr );
    hashInput.t.size += 4;

    // Create pHash input byte stream:  now add in names for the handles.
    rval = ConcatSizedByteBuffer( &hashInput, &( name1.b ) );
    if( rval != TPM_RC_SUCCESS )
        return rval;
    
    rval = ConcatSizedByteBuffer( &hashInput, &( name2.b ) );
    if( rval != TPM_RC_SUCCESS )
        return rval;

    if( ( hashInput.t.size + parametersSize ) <= sizeof( hashInput.t.buffer ) )
    {
        // Create pHash input byte stream:  now add in parameters byte stream
        for( i = 0; i < parametersSize; i++ )
            hashInput.t.buffer[hashInput.t.size + i ] = startParams[i];
        hashInput.t.size += (UINT16)parametersSize;
    }
    else
    {
        return( APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER ) );

    }
#ifdef DEBUG
    OpenOutFile( &outFp );
    TpmClientPrintf( 0, "\n\nPHASH input bytes= \n" );
    PrintSizedBuffer( &(hashInput.b) );
    CloseOutFile( &outFp );
#endif
    
    // Now hash the whole mess.
    if( hashInput.t.size > sizeof( hashInput.t.buffer ) )
    {
        rval = APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER );
    }
    else
    {
        rval = TpmHash( authHash, hashInput.t.size, &( hashInput.t.buffer[0] ), pHash );
        if( rval != TPM_RC_SUCCESS )
            return rval;
#ifdef DEBUG
        OpenOutFile( &outFp );
        TpmClientPrintf( 0, "\n\nPHASH = " );
        PrintSizedBuffer( &(pHash->b) );
        CloseOutFile( &outFp );
#endif
    }
    
    return rval;
 }
Ejemplo n.º 16
0
TSS2_RC Tss2_Sys_GetRspAuths(
    TSS2_SYS_CONTEXT 		*sysContext,
    TSS2_SYS_RSP_AUTHS 		*rspAuthsArray
    )
{
    TSS2_RC rval = TSS2_RC_SUCCESS;
    void *otherData, *otherDataSaved;

    if( sysContext == NULL || rspAuthsArray == NULL )
    {
        rval = TSS2_SYS_RC_BAD_REFERENCE;
    }
    else if( SYS_CONTEXT->previousStage != CMD_STAGE_RECEIVE_RESPONSE ||
            CHANGE_ENDIAN_DWORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->responseCode ) != TPM_RC_SUCCESS ||
            SYS_CONTEXT->authAllowed == 0 )
    {
        rval = TSS2_SYS_RC_BAD_SEQUENCE;
    }
    else
    {
        int i = 0;

        if( rspAuthsArray->rspAuthsCount == 0 )
        {
            rval = TSS2_SYS_RC_BAD_VALUE;
        }
        else
        {
            if( rspAuthsArray->rspAuthsCount != SYS_CONTEXT->authsCount )
            {
                rval = TSS2_SYS_RC_INVALID_SESSIONS;
            }
            else
            {
                // Get start of authorization area.
                otherData = SYS_CONTEXT->tpmOutBuffPtr;
                otherData = (UINT8 *)otherData + sizeof( TPM20_Header_Out ) - 1;
                otherData = (UINT8 *)otherData + SYS_CONTEXT->numResponseHandles * sizeof( TPM_HANDLE );
                otherData = (UINT8 *)otherData + CHANGE_ENDIAN_DWORD( *( SYS_CONTEXT->paramsSize ) ); 
                otherData = (UINT8 *)otherData + sizeof( UINT32 );

                otherDataSaved = otherData;

                if( TPM_ST_SESSIONS == CHANGE_ENDIAN_WORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->tag ) )
                {
                    for( i = 0; i < rspAuthsArray->rspAuthsCount; i++ )
                    {
                        // Before copying, make sure that we aren't going to go past the output buffer + the response size.
                        if( (UINT8 *)otherData > ( SYS_CONTEXT->tpmOutBuffPtr + CHANGE_ENDIAN_DWORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->responseSize ) ) )
                        {
                            rval = TSS2_SYS_RC_MALFORMED_RESPONSE;
                            break;
                        }

                        otherData = (UINT8 *)otherData + sizeof( UINT16 ) + CHANGE_ENDIAN_WORD( *(UINT16 *)otherData ); // Nonce
                        if( (UINT8 *)otherData > ( SYS_CONTEXT->tpmOutBuffPtr + CHANGE_ENDIAN_DWORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->responseSize ) ) )
                        {
                            rval = TSS2_SYS_RC_MALFORMED_RESPONSE;
                            break;
                        }

                        otherData = (UINT8 *)otherData + 1;  // session attributes.
                        if( (UINT8 *)otherData > ( SYS_CONTEXT->tpmOutBuffPtr + CHANGE_ENDIAN_DWORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->responseSize ) ) )
                        {
                            rval = TSS2_SYS_RC_MALFORMED_RESPONSE;
                            break;
                        }

                        otherData = (UINT8 *)otherData + sizeof( UINT16 ) + CHANGE_ENDIAN_WORD( *(UINT16 *)otherData ); // hmac
                        if( (UINT8 *)otherData > ( SYS_CONTEXT->tpmOutBuffPtr + CHANGE_ENDIAN_DWORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->responseSize ) ) )
                        {
                            rval = TSS2_SYS_RC_MALFORMED_RESPONSE;
                            break;
                        }

                        // Make sure that we don't run past the valid authorizations.
                        if( ( i + 1 ) > rspAuthsArray->rspAuthsCount )
                        {
                            rval = TSS2_SYS_RC_INVALID_SESSIONS;
                            break;
                        }
                    }
                    if( rval == TSS2_RC_SUCCESS )
                    {
                        // Check that number of auths is equal to the number asked for.
                        // Can't see how this would actually happen, but left it in as a failsafe against
                        // future code modifications.
                        if( i != rspAuthsArray->rspAuthsCount )
                        {
                            rval = TSS2_SYS_RC_INVALID_SESSIONS;
                        }
                        else
                        {
                            // Get start of authorization area.
                            otherData = otherDataSaved;
                            rval = CopySessionsDataOut( rspAuthsArray, otherData,
                                    CHANGE_ENDIAN_WORD( ( (TPM20_Header_Out *)( SYS_CONTEXT->tpmOutBuffPtr ) )->tag ),
                                    SYS_CONTEXT->tpmOutBuffPtr, SYS_CONTEXT->maxResponseSize );
                        }
                    }
                }
            }
        }
    }
    return rval;
}
Ejemplo n.º 17
0
TSS2_RC SocketReceiveTpmResponse(
    TSS2_TCTI_CONTEXT *tctiContext,     /* in */
    size_t          *response_size,     /* out */
    unsigned char   *response_buffer,    /* in */
    int32_t         timeout
    )
{
    UINT32 trash;
    TSS2_RC rval = TSS2_RC_SUCCESS;
    fd_set readFds;
    struct timeval tv, *tvPtr;
    int32_t timeoutMsecs = timeout % 1000;
    int iResult;
    unsigned char responseSizeDelta = 0;

    rval = CommonReceiveChecks( tctiContext, response_size, response_buffer );
    if( rval != TSS2_RC_SUCCESS )
    {
        goto retSocketReceiveTpmResponse;
    }        
    
    if( timeout == TSS2_TCTI_TIMEOUT_BLOCK )
    {
        tvPtr = 0;
    }
    else
    {
        tv.tv_sec = timeout / 1000;
        tv.tv_usec = timeoutMsecs * 1000;
        tvPtr = &tv;
    }

    FD_ZERO( &readFds );
    FD_SET( TCTI_CONTEXT_INTEL->tpmSock, &readFds );

    iResult = select( TCTI_CONTEXT_INTEL->tpmSock+1, &readFds, 0, 0, tvPtr );
    if( iResult == 0 )
    {
        TCTI_LOG( tctiContext, NO_PREFIX, "select failed due to timeout, socket #: 0x%x\n", TCTI_CONTEXT_INTEL->tpmSock );
        rval = TSS2_TCTI_RC_TRY_AGAIN;
        goto retSocketReceiveTpmResponse;
    }
    else if( iResult == SOCKET_ERROR )
    {
        TCTI_LOG( tctiContext, NO_PREFIX, "select failed with socket error: %d\n", WSAGetLastError() );
        rval = TSS2_TCTI_RC_IO_ERROR;
        goto retSocketReceiveTpmResponse;
    }
    else if ( iResult != 1 )
    {
        TCTI_LOG( tctiContext, NO_PREFIX, "select failed, read the wrong # of bytes: %d\n", iResult );
        rval = TSS2_TCTI_RC_IO_ERROR;
        goto retSocketReceiveTpmResponse;
    }

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.protocolResponseSizeReceived != 1 )
    {        
        // Receive the size of the response.
        rval = tctiRecvBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)& (((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize ), 4 );
        if( rval != TSS2_RC_SUCCESS )
            goto retSocketReceiveTpmResponse;

        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize = CHANGE_ENDIAN_DWORD( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize );
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.protocolResponseSizeReceived = 1;
    }

    if( response_buffer == NULL )
    {
        // In this case, just return the size
        *response_size = ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize;
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.protocolResponseSizeReceived = 1;
        goto retSocketReceiveTpmResponse;
    }

    if( *response_size < ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize )
    {
        *response_size = ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize;
        rval = TSS2_TCTI_RC_INSUFFICIENT_BUFFER; 


        // If possible, receive tag from TPM.
        if( *response_size >= sizeof( TPM_ST ) && ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.tagReceived == 0 )
        {
            if( TSS2_RC_SUCCESS != tctiRecvBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&( ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->tag ), 2 ) )
            {
                goto retSocketReceiveTpmResponse;
            }
            else
            {
                ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.tagReceived = 1;
            }
        }

        // If possible, receive response size from TPM
        if( *response_size >= ( sizeof( TPM_ST ) + sizeof( TPM_RC ) ) && ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.responseSizeReceived == 0 )
        {
            if( TSS2_RC_SUCCESS != tctiRecvBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&( ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->responseSize ), 4 ) )
            {
                goto retSocketReceiveTpmResponse;
            }
            else
            {
                ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize = CHANGE_ENDIAN_DWORD( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize );
                ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.responseSizeReceived = 1;
            }
        }
    }
    else
    {
        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED &&
                ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize > 0 )
        {
#ifdef DEBUG
            TCTI_LOG( tctiContext, NO_PREFIX, "Response Received: " );
#endif
#ifdef DEBUG_SOCKETS
            TCTI_LOG( tctiContext, NO_PREFIX, "from socket #0x%x:\n", TCTI_CONTEXT_INTEL->tpmSock );
#endif
        }
        
        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.tagReceived == 1 )
        {
            *(TPM_ST *)response_buffer = ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->tag;
            responseSizeDelta += sizeof( TPM_ST );
            response_buffer += sizeof( TPM_ST );
        }

        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.responseSizeReceived == 1 )
        {
            *(TPM_RC *)response_buffer = CHANGE_ENDIAN_DWORD( ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->responseSize );
            responseSizeDelta += sizeof( TPM_RC );
            response_buffer += sizeof( TPM_RC );
        }

        // Receive the TPM response.
        rval = tctiRecvBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)response_buffer, ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize - responseSizeDelta );
        if( rval != TSS2_RC_SUCCESS )
            goto retSocketReceiveTpmResponse;

#ifdef DEBUG
        if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
        {
            DEBUG_PRINT_BUFFER( NO_PREFIX, response_buffer, ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize );
        }
#endif

        // Receive the appended four bytes of 0's
        rval = tctiRecvBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&trash, 4 );
        if( rval != TSS2_RC_SUCCESS )
            goto retSocketReceiveTpmResponse;
    }

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize < *response_size )
    {
        *response_size = ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->responseSize;
    }
    
    ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent = 0;

    // Turn cancel off.
    if( rval == TSS2_RC_SUCCESS )
    {
        rval = (TSS2_RC)PlatformCommand( tctiContext, MS_SIM_CANCEL_OFF );
    }
    else
    {
        // Ignore return value so earlier error code is preserved.
        PlatformCommand( tctiContext, MS_SIM_CANCEL_OFF );
    }

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
//        TCTI_LOG( tctiContext, NO_PREFIX,  "%s sent cancel OFF command:\n", interfaceName );
    }

retSocketReceiveTpmResponse:
    if( rval == TSS2_RC_SUCCESS && 
		response_buffer != NULL )
    {
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->previousStage = TCTI_STAGE_RECEIVE_RESPONSE;
    }
    
    return rval;
}
Ejemplo n.º 18
0
TSS2_RC SocketSendTpmCommand(
    TSS2_TCTI_CONTEXT *tctiContext,       /* in */
    size_t             command_size,      /* in */
    uint8_t           *command_buffer     /* in */
    )
{
    UINT32 tpmSendCommand = MS_SIM_TPM_SEND_COMMAND;  // Value for "send command" to MS simulator.
    UINT32 cnt, cnt1;
    UINT8 locality;
    TSS2_RC rval = TSS2_RC_SUCCESS;
    
#ifdef DEBUG    
    UINT32 commandCode    ;
#endif
    
#ifdef SAPI_CLIENT    
    UINT8 debugMsgLevel, statusBits;
#endif

    rval = CommonSendChecks( tctiContext, command_buffer );
    if( rval != TSS2_RC_SUCCESS )
    {
        goto returnFromSocketSendTpmCommand;
    }

    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
#ifdef DEBUG
        TCTI_LOG( tctiContext, NO_PREFIX, "\n" );
		commandCode = CHANGE_ENDIAN_DWORD( ( (TPM20_Header_In *)command_buffer )->commandCode );
        if( commandCode >= TPM_CC_NV_UndefineSpaceSpecial && commandCode <= TPM_CC_PolicyNvWritten )     
            TCTI_LOG( tctiContext, NO_PREFIX, "Cmd sent: %s\n", strTpmCommandCode( commandCode ) );
        else
            TCTI_LOG( tctiContext, NO_PREFIX, "Cmd sent: 0x%4.4x\n", CHANGE_ENDIAN_DWORD(commandCode ) );
#endif
#ifdef DEBUG_SOCKETS
        TCTI_LOG( tctiContext, NO_PREFIX, "Command sent on socket #0x%x: %s\n", TCTI_CONTEXT_INTEL->tpmSock, strTpmCommandCode( commandCode ) );
#endif        
    }
    // Size TPM 1.2 and TPM 2.0 headers overlap exactly, we can use
    // either 1.2 or 2.0 header to get the size.
    cnt = CHANGE_ENDIAN_DWORD(((TPM20_Header_In *) command_buffer)->commandSize);

    // Send TPM_SEND_COMMAND
    tpmSendCommand = CHANGE_ENDIAN_DWORD(tpmSendCommand);
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&tpmSendCommand, 4 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;
                
    // Send the locality
    locality = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.locality;
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&locality, 1 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;

#ifdef SAPI_CLIENT    
    // Send the debug level
    debugMsgLevel = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.debugMsgLevel;
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&debugMsgLevel, 1 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;

    // Send status bits
    statusBits = (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent;
    statusBits |= ( (UINT8)( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.rmDebugPrefix ) << 1;
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&statusBits, 1 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;
#endif
    
#ifdef DEBUG
    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
        TCTI_LOG( tctiContext, NO_PREFIX, "Locality = %d", ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.locality );
    }
#endif
    
    // Send number of bytes.
    cnt1 = cnt;
    cnt = CHANGE_ENDIAN_DWORD(cnt);
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)&cnt, 4 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;
    
    // Send the TPM command buffer
    rval = tctiSendBytes( tctiContext, TCTI_CONTEXT_INTEL->tpmSock, (unsigned char *)command_buffer, cnt1 );
    if( rval != TSS2_RC_SUCCESS )
        goto returnFromSocketSendTpmCommand;
    
#ifdef DEBUG
    if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext )->status.debugMsgLevel == TSS2_TCTI_DEBUG_MSG_ENABLED )
    {
        DEBUG_PRINT_BUFFER( NO_PREFIX, command_buffer, cnt1 );
    }
#endif
    ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent = 1;

returnFromSocketSendTpmCommand:

    if( rval == TSS2_RC_SUCCESS )
    {
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->previousStage = TCTI_STAGE_SEND_COMMAND;
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.tagReceived = 0;
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.responseSizeReceived = 0;
        ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.protocolResponseSizeReceived = 0;
    }

    return rval;
}