static TSS2_RC tctiSendBytes( TSS2_TCTI_CONTEXT *tctiContext, SOCKET sock, const unsigned char *data, int len ) { TSS2_RC ret = TSS2_RC_SUCCESS; #ifdef DEBUG_SOCKETS TCTI_LOG( tctiContext, NO_PREFIX, "Send Bytes to socket #0x%x: \n", sock ); TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, (UINT8 *)data, len ); #endif ret = sendBytes( sock, data, len); if (ret != TSS2_RC_SUCCESS) TCTI_LOG( tctiContext, NO_PREFIX, "In recvBytes, recv failed (socket: 0x%x) with error: %d\n", sock, WSAGetLastError() ); return ret; }
static TSS2_RC tctiRecvBytes( TSS2_TCTI_CONTEXT *tctiContext, SOCKET sock, unsigned char *data, int len ) { TSS2_RC result = 0; result = recvBytes( sock, data, len); if ( (INT32)result == SOCKET_ERROR) { TCTI_LOG( tctiContext, NO_PREFIX, "In recvBytes, recv failed (socket: 0x%x) with error: %d\n", sock, WSAGetLastError() ); return TSS2_TCTI_RC_IO_ERROR; } #ifdef DEBUG_SOCKETS TCTI_LOG( tctiContext, NO_PREFIX, "Receive Bytes from socket #0x%x: \n", sock ); TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, data, len ); #endif return TSS2_RC_SUCCESS; }
TSS2_RC SocketCancel( TSS2_TCTI_CONTEXT *tctiContext ) { TSS2_RC rval = TSS2_RC_SUCCESS; if( tctiContext == 0 ) { rval = TSS2_TCTI_RC_BAD_REFERENCE; } else if( ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->status.commandSent != 1 ) { rval = TSS2_TCTI_RC_BAD_SEQUENCE; } else { rval = (TSS2_RC)PlatformCommand( tctiContext, MS_SIM_CANCEL_ON ); #if 0 if( rval == TSS2_RC_SUCCESS ) { rval = (TSS2_RC)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 ON command:\n", interfaceName ); } } #endif } return rval; }
TSS2_RC PlatformCommand( TSS2_TCTI_CONTEXT *tctiContext, /* in */ char cmd ) { int iResult = 0; // used to return function results char sendbuf[] = { 0x0,0x0,0x0,0x0 }; char recvbuf[] = { 0x0, 0x0, 0x0, 0x0 }; TSS2_RC rval = TSS2_RC_SUCCESS; sendbuf[3] = cmd; // Send the command iResult = send( TCTI_CONTEXT_INTEL->otherSock, sendbuf, 4, MSG_NOSIGNAL ); if (iResult == SOCKET_ERROR) { TCTI_LOG( tctiContext, NO_PREFIX, "send failed with error: %d\n", WSAGetLastError() ); rval = TSS2_TCTI_RC_IO_ERROR; } else { #ifdef DEBUG_SOCKETS TCTI_LOG( tctiContext, NO_PREFIX, "Send Bytes to socket #0x%x: \n", TCTI_CONTEXT_INTEL->otherSock ); TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, (UINT8 *)sendbuf, 4 ); #endif // Read result iResult = recv( TCTI_CONTEXT_INTEL->otherSock, recvbuf, 4, 0); if (iResult == SOCKET_ERROR) { TCTI_LOG( tctiContext, NO_PREFIX, "In PlatformCommand, recv failed (socket: 0x%x) with error: %d\n", TCTI_CONTEXT_INTEL->otherSock, WSAGetLastError() ); rval = TSS2_TCTI_RC_IO_ERROR; } else if( recvbuf[0] != 0 || recvbuf[1] != 0 || recvbuf[2] != 0 || recvbuf[3] != 0 ) { TCTI_LOG( tctiContext, NO_PREFIX, "PlatformCommand failed with error: %d\n", recvbuf[3] ); rval = TSS2_TCTI_RC_IO_ERROR; } else { #ifdef DEBUG_SOCKETS TCTI_LOG( tctiContext, NO_PREFIX, "Receive bytes from socket #0x%x: \n", TCTI_CONTEXT_INTEL->otherSock ); TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, (UINT8 *)recvbuf, 4 ); #endif } } 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; 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; }