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; }
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; }
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; }
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; }
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; }
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; }