blob: 9c6b4780865cf855f7ac0b20fd54e74cfade2263 [file] [log] [blame]
Will Arthur54e04e42015-07-15 11:29:25 -04001//**********************************************************************;
Philip Triccae0a93d12017-06-29 08:42:34 -07002// Copyright (c) 2015, 2016, 2017 Intel Corporation
Will Arthur54e04e42015-07-15 11:29:25 -04003// All rights reserved.
Philip Tricca1ea84a52015-11-19 18:07:06 -08004//
5// Redistribution and use in source and binary forms, with or without
Will Arthur54e04e42015-07-15 11:29:25 -04006// modification, are permitted provided that the following conditions are met:
Philip Tricca1ea84a52015-11-19 18:07:06 -08007//
8// 1. Redistributions of source code must retain the above copyright notice,
Will Arthur54e04e42015-07-15 11:29:25 -04009// this list of conditions and the following disclaimer.
Philip Tricca1ea84a52015-11-19 18:07:06 -080010//
11// 2. Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
Will Arthur54e04e42015-07-15 11:29:25 -040013// and/or other materials provided with the distribution.
Philip Tricca1ea84a52015-11-19 18:07:06 -080014//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
Will Arthur54e04e42015-07-15 11:29:25 -040025// THE POSSIBILITY OF SUCH DAMAGE.
26//**********************************************************************;
27
Will Arthur54e04e42015-07-15 11:29:25 -040028#include <stdio.h>
29#include <stdlib.h> // Needed for _wtoi
Armin Kusterace89dd2017-04-01 14:49:06 -070030#include <sys/time.h>
Will Arthur54e04e42015-07-15 11:29:25 -040031
Philip Triccadd3b03c2017-03-05 11:38:08 -080032#include "sapi/tpm20.h"
Tadeusz Strukb21f9f92017-10-09 13:51:19 -070033#include "sapi/tss2_mu.h"
Philip Triccadd3b03c2017-03-05 11:38:08 -080034#include "tcti/tcti_socket.h"
Philip Triccac3dedc22016-01-15 13:47:22 -080035#include "sysapi_util.h"
Philip Triccadd3b03c2017-03-05 11:38:08 -080036#include "common/debug.h"
Philip Tricca473aebe2017-10-17 13:04:17 -070037#include "tcti.h"
Philip Triccabcc73032016-03-30 19:50:54 -070038#include "logging.h"
Philip Tricca330d3c72017-07-02 13:49:32 -070039#include "sockets.h"
Tadeusz Struk8203a372017-06-26 15:15:18 -070040#include "tss2_endian.h"
Will Arthur54e04e42015-07-15 11:29:25 -040041
Philip Triccabcc73032016-03-30 19:50:54 -070042static TSS2_RC tctiRecvBytes( TSS2_TCTI_CONTEXT *tctiContext, SOCKET sock, unsigned char *data, int len )
Philip Triccaa06f2372016-03-30 17:13:11 -070043{
44 TSS2_RC result = 0;
45 result = recvBytes( sock, data, len);
wcarthur1e2e04182016-04-11 07:37:55 -070046 if ( (INT32)result == SOCKET_ERROR) {
Philip Triccabcc73032016-03-30 19:50:54 -070047 TCTI_LOG( tctiContext, NO_PREFIX, "In recvBytes, recv failed (socket: 0x%x) with error: %d\n", sock, WSAGetLastError() );
Philip Triccaa06f2372016-03-30 17:13:11 -070048 return TSS2_TCTI_RC_IO_ERROR;
49 }
50#ifdef DEBUG_SOCKETS
Philip Triccabcc73032016-03-30 19:50:54 -070051 TCTI_LOG( tctiContext, NO_PREFIX, "Receive Bytes from socket #0x%x: \n", sock );
Philip Tricca4eb2f352016-03-31 05:55:35 -070052 TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, data, len );
Philip Triccaa06f2372016-03-30 17:13:11 -070053#endif
54
55 return TSS2_RC_SUCCESS;
56}
57
Philip Triccabcc73032016-03-30 19:50:54 -070058static TSS2_RC tctiSendBytes( TSS2_TCTI_CONTEXT *tctiContext, SOCKET sock, const unsigned char *data, int len )
Philip Tricca4ee284b2016-03-30 17:40:39 -070059{
60 TSS2_RC ret = TSS2_RC_SUCCESS;
61
62#ifdef DEBUG_SOCKETS
Philip Triccabcc73032016-03-30 19:50:54 -070063 TCTI_LOG( tctiContext, NO_PREFIX, "Send Bytes to socket #0x%x: \n", sock );
Philip Tricca4eb2f352016-03-31 05:55:35 -070064 TCTI_LOG_BUFFER( tctiContext, NO_PREFIX, (UINT8 *)data, len );
Philip Tricca4ee284b2016-03-30 17:40:39 -070065#endif
66
67 ret = sendBytes( sock, data, len);
68 if (ret != TSS2_RC_SUCCESS)
Philip Triccabcc73032016-03-30 19:50:54 -070069 TCTI_LOG( tctiContext, NO_PREFIX, "In recvBytes, recv failed (socket: 0x%x) with error: %d\n", sock, WSAGetLastError() );
Philip Tricca4ee284b2016-03-30 17:40:39 -070070 return ret;
71}
72
Philip Triccad1bbedb2016-02-14 20:39:59 -080073TSS2_RC SendSessionEndSocketTcti(
Will Arthur54e04e42015-07-15 11:29:25 -040074 TSS2_TCTI_CONTEXT *tctiContext, /* in */
75 UINT8 tpmCmdServer )
76{
Philip Tricca24f555c2017-10-13 17:51:53 -070077 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Philip Tricca6c45af32017-03-09 19:26:35 -080078 // Value for "send command" to MS simulator
79 uint8_t buffer [4] = { 0, };
Will Arthur54e04e42015-07-15 11:29:25 -040080 SOCKET sock;
wcarthureedecd62015-11-20 16:59:45 -050081 TSS2_RC rval = TSS2_RC_SUCCESS;
Philip Triccadfa41a52016-07-20 17:43:57 -070082
Will Arthur54e04e42015-07-15 11:29:25 -040083 if( tpmCmdServer )
84 {
Philip Tricca24f555c2017-10-13 17:51:53 -070085 sock = tcti_intel->tpmSock;
Will Arthur54e04e42015-07-15 11:29:25 -040086 }
87 else
88 {
Philip Tricca24f555c2017-10-13 17:51:53 -070089 sock = tcti_intel->otherSock;
Will Arthur54e04e42015-07-15 11:29:25 -040090 }
Philip Triccadfa41a52016-07-20 17:43:57 -070091
Tadeusz Strukb21f9f92017-10-09 13:51:19 -070092 rval = Tss2_MU_UINT32_Marshal (TPM_SESSION_END, buffer, sizeof (buffer), NULL);
Philip Tricca6c45af32017-03-09 19:26:35 -080093 if (rval == TSS2_RC_SUCCESS) {
94 return rval;
95 }
96 rval = tctiSendBytes( tctiContext, sock, (char unsigned *)buffer, 4 );
Will Arthur54e04e42015-07-15 11:29:25 -040097
wcarthureedecd62015-11-20 16:59:45 -050098 return( rval );
Will Arthur54e04e42015-07-15 11:29:25 -040099}
100
Will Arthur54e04e42015-07-15 11:29:25 -0400101TSS2_RC SocketSendTpmCommand(
102 TSS2_TCTI_CONTEXT *tctiContext, /* in */
103 size_t command_size, /* in */
104 uint8_t *command_buffer /* in */
105 )
106{
Philip Tricca24f555c2017-10-13 17:51:53 -0700107 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Philip Tricca6c45af32017-03-09 19:26:35 -0800108 UINT32 tpmSendCommand;
Will Arthur54e04e42015-07-15 11:29:25 -0400109 UINT32 cnt, cnt1;
110 UINT8 locality;
wcarthureedecd62015-11-20 16:59:45 -0500111 TSS2_RC rval = TSS2_RC_SUCCESS;
Philip Tricca6c45af32017-03-09 19:26:35 -0800112 size_t offset;
Philip Triccadfa41a52016-07-20 17:43:57 -0700113
114#ifdef DEBUG
wcarthur1c827592016-04-27 11:07:51 -0400115 UINT32 commandCode;
116 printf_type rmPrefix;
wcarthur1aee953e2016-04-01 15:13:24 -0700117#endif
wcarthureedecd62015-11-20 16:59:45 -0500118 rval = CommonSendChecks( tctiContext, command_buffer );
119 if( rval != TSS2_RC_SUCCESS )
120 {
121 goto returnFromSocketSendTpmCommand;
122 }
Will-nuc3ebfeb92015-10-29 15:53:27 -0400123
Will Arthur54e04e42015-07-15 11:29:25 -0400124#ifdef DEBUG
Philip Tricca24f555c2017-10-13 17:51:53 -0700125 if (tcti_intel->status.rmDebugPrefix == 1)
wcarthur1c827592016-04-27 11:07:51 -0400126 rmPrefix = RM_PREFIX;
127 else
128 rmPrefix = NO_PREFIX;
129
Philip Tricca24f555c2017-10-13 17:51:53 -0700130 if (tcti_intel->status.debugMsgEnabled == 1)
wcarthur1c827592016-04-27 11:07:51 -0400131 {
132 TCTI_LOG( tctiContext, rmPrefix, "" );
Philip Tricca6c45af32017-03-09 19:26:35 -0800133 offset = sizeof (TPM_ST) + sizeof (UINT32);
Tadeusz Strukb21f9f92017-10-09 13:51:19 -0700134 rval = Tss2_MU_TPM_CC_Unmarshal (command_buffer,
Philip Tricca6c45af32017-03-09 19:26:35 -0800135 command_size,
136 &offset,
137 &commandCode);
Will Arthur54e04e42015-07-15 11:29:25 -0400138#ifdef DEBUG_SOCKETS
Philip Tricca24f555c2017-10-13 17:51:53 -0700139 TCTI_LOG(tctiContext, NO_PREFIX, "Command sent on socket #0x%x: %s\n", tcti_intel->tpmSock, strTpmCommandCode(commandCode));
wcarthur1a10b0c92016-04-14 04:25:03 -0700140#else
Tadeusz Struk83d12be2017-10-05 14:58:30 -0700141 TCTI_LOG(tctiContext, NO_PREFIX, "Cmd sent: %s\n", strTpmCommandCode(commandCode));
wcarthur1a10b0c92016-04-14 04:25:03 -0700142#endif
Will Arthur54e04e42015-07-15 11:29:25 -0400143 }
wcarthur1c827592016-04-27 11:07:51 -0400144#endif
Will Arthur54e04e42015-07-15 11:29:25 -0400145 // Size TPM 1.2 and TPM 2.0 headers overlap exactly, we can use
146 // either 1.2 or 2.0 header to get the size.
Philip Tricca6c45af32017-03-09 19:26:35 -0800147 offset = sizeof (TPM_ST);
Tadeusz Strukb21f9f92017-10-09 13:51:19 -0700148 rval = Tss2_MU_UINT32_Unmarshal (command_buffer, command_size, &offset, &cnt);
Will Arthur54e04e42015-07-15 11:29:25 -0400149
150 // Send TPM_SEND_COMMAND
Tadeusz Strukb21f9f92017-10-09 13:51:19 -0700151 rval = Tss2_MU_UINT32_Marshal (MS_SIM_TPM_SEND_COMMAND,
Philip Tricca6c45af32017-03-09 19:26:35 -0800152 (uint8_t*)&tpmSendCommand,
153 sizeof (tpmSendCommand),
154 NULL); // Value for "send command" to MS simulator.
Philip Tricca24f555c2017-10-13 17:51:53 -0700155 rval = tctiSendBytes( tctiContext, tcti_intel->tpmSock, (unsigned char *)&tpmSendCommand, 4 );
wcarthureedecd62015-11-20 16:59:45 -0500156 if( rval != TSS2_RC_SUCCESS )
157 goto returnFromSocketSendTpmCommand;
Philip Triccadfa41a52016-07-20 17:43:57 -0700158
Will Arthur54e04e42015-07-15 11:29:25 -0400159 // Send the locality
Philip Tricca24f555c2017-10-13 17:51:53 -0700160 locality = (UINT8)tcti_intel->status.locality;
161 rval = tctiSendBytes( tctiContext, tcti_intel->tpmSock, (unsigned char *)&locality, 1 );
wcarthureedecd62015-11-20 16:59:45 -0500162 if( rval != TSS2_RC_SUCCESS )
163 goto returnFromSocketSendTpmCommand;
Will Arthur54e04e42015-07-15 11:29:25 -0400164
Will Arthur54e04e42015-07-15 11:29:25 -0400165#ifdef DEBUG
Philip Tricca24f555c2017-10-13 17:51:53 -0700166 if (tcti_intel->status.debugMsgEnabled == 1)
Will Arthur54e04e42015-07-15 11:29:25 -0400167 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700168 TCTI_LOG( tctiContext, rmPrefix, "Locality = %d", tcti_intel->status.locality);
Will Arthur54e04e42015-07-15 11:29:25 -0400169 }
170#endif
Philip Triccadfa41a52016-07-20 17:43:57 -0700171
Will Arthur54e04e42015-07-15 11:29:25 -0400172 // Send number of bytes.
173 cnt1 = cnt;
Philip Tricca6c45af32017-03-09 19:26:35 -0800174 cnt = HOST_TO_BE_32(cnt);
Philip Tricca24f555c2017-10-13 17:51:53 -0700175 rval = tctiSendBytes( tctiContext, tcti_intel->tpmSock, (unsigned char *)&cnt, 4 );
wcarthureedecd62015-11-20 16:59:45 -0500176 if( rval != TSS2_RC_SUCCESS )
177 goto returnFromSocketSendTpmCommand;
Philip Triccadfa41a52016-07-20 17:43:57 -0700178
Will Arthur54e04e42015-07-15 11:29:25 -0400179 // Send the TPM command buffer
Philip Tricca24f555c2017-10-13 17:51:53 -0700180 rval = tctiSendBytes( tctiContext, tcti_intel->tpmSock, (unsigned char *)command_buffer, cnt1 );
wcarthureedecd62015-11-20 16:59:45 -0500181 if( rval != TSS2_RC_SUCCESS )
182 goto returnFromSocketSendTpmCommand;
Philip Triccadfa41a52016-07-20 17:43:57 -0700183
Will Arthur54e04e42015-07-15 11:29:25 -0400184#ifdef DEBUG
Philip Tricca24f555c2017-10-13 17:51:53 -0700185 if (tcti_intel->status.debugMsgEnabled == 1)
Will Arthur54e04e42015-07-15 11:29:25 -0400186 {
wcarthur1c827592016-04-27 11:07:51 -0400187 DEBUG_PRINT_BUFFER( rmPrefix, command_buffer, cnt1 );
Will Arthur54e04e42015-07-15 11:29:25 -0400188 }
189#endif
Philip Tricca24f555c2017-10-13 17:51:53 -0700190 tcti_intel->status.commandSent = 1;
Will Arthur54e04e42015-07-15 11:29:25 -0400191
wcarthureedecd62015-11-20 16:59:45 -0500192returnFromSocketSendTpmCommand:
193
194 if( rval == TSS2_RC_SUCCESS )
195 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700196 tcti_intel->previousStage = TCTI_STAGE_SEND_COMMAND;
197 tcti_intel->status.tagReceived = 0;
198 tcti_intel->status.responseSizeReceived = 0;
199 tcti_intel->status.protocolResponseSizeReceived = 0;
wcarthureedecd62015-11-20 16:59:45 -0500200 }
201
202 return rval;
Will Arthur54e04e42015-07-15 11:29:25 -0400203}
204
205TSS2_RC SocketCancel(
206 TSS2_TCTI_CONTEXT *tctiContext
207 )
208{
Philip Tricca24f555c2017-10-13 17:51:53 -0700209 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Will Arthur54e04e42015-07-15 11:29:25 -0400210 TSS2_RC rval = TSS2_RC_SUCCESS;
211
212 if( tctiContext == 0 )
213 {
214 rval = TSS2_TCTI_RC_BAD_REFERENCE;
215 }
Philip Tricca24f555c2017-10-13 17:51:53 -0700216 else if (tcti_intel->status.commandSent != 1)
Will Arthur54e04e42015-07-15 11:29:25 -0400217 {
218 rval = TSS2_TCTI_RC_BAD_SEQUENCE;
219 }
220 else
221 {
222 rval = (TSS2_RC)PlatformCommand( tctiContext, MS_SIM_CANCEL_ON );
Will Arthur54e04e42015-07-15 11:29:25 -0400223 }
224
225 return rval;
226}
227
228TSS2_RC SocketSetLocality(
229 TSS2_TCTI_CONTEXT *tctiContext, /* in */
230 uint8_t locality /* in */
231 )
232{
Philip Tricca24f555c2017-10-13 17:51:53 -0700233 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Will Arthur54e04e42015-07-15 11:29:25 -0400234 TSS2_RC rval = TSS2_RC_SUCCESS;
235
236 if( tctiContext == 0 )
237 {
238 rval = TSS2_TCTI_RC_BAD_REFERENCE;
239 }
Philip Tricca24f555c2017-10-13 17:51:53 -0700240 else if (tcti_intel->status.locality != locality)
Will Arthur54e04e42015-07-15 11:29:25 -0400241 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700242 if (tcti_intel->status.commandSent == 1)
Will Arthur54e04e42015-07-15 11:29:25 -0400243 {
244 rval = TSS2_TCTI_RC_BAD_SEQUENCE;
245 }
246 else
247 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700248 tcti_intel->status.locality = locality;
Will Arthur54e04e42015-07-15 11:29:25 -0400249 }
250 }
251
252 return rval;
253}
254
Philip Tricca5917fbf2017-06-29 08:24:09 -0700255TSS2_RC SocketGetPollHandles(
256 TSS2_TCTI_CONTEXT *tctiContext,
257 TSS2_TCTI_POLL_HANDLE *handles,
258 size_t *num_handles)
259{
260 return TSS2_TCTI_RC_NOT_IMPLEMENTED;
261}
262
wcarthur35aa5392016-03-22 16:52:44 -0400263void SocketFinalize(
Will Arthur54e04e42015-07-15 11:29:25 -0400264 TSS2_TCTI_CONTEXT *tctiContext /* in */
265 )
266{
Philip Tricca24f555c2017-10-13 17:51:53 -0700267 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
268
wcarthur35aa5392016-03-22 16:52:44 -0400269 if( tctiContext != NULL )
wcarthurf979e352015-11-24 17:34:44 -0500270 {
271 // Send session end messages to servers.
Philip Triccad1bbedb2016-02-14 20:39:59 -0800272 SendSessionEndSocketTcti( tctiContext, 1 );
273 SendSessionEndSocketTcti( tctiContext, 0 );
Will Arthur54e04e42015-07-15 11:29:25 -0400274
Philip Tricca24f555c2017-10-13 17:51:53 -0700275 CloseSockets(tcti_intel->otherSock, tcti_intel->tpmSock);
wcarthurf979e352015-11-24 17:34:44 -0500276 }
Will Arthur54e04e42015-07-15 11:29:25 -0400277}
278
Will Arthur54e04e42015-07-15 11:29:25 -0400279TSS2_RC SocketReceiveTpmResponse(
280 TSS2_TCTI_CONTEXT *tctiContext, /* in */
281 size_t *response_size, /* out */
282 unsigned char *response_buffer, /* in */
283 int32_t timeout
284 )
285{
Philip Tricca24f555c2017-10-13 17:51:53 -0700286 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Will Arthur54e04e42015-07-15 11:29:25 -0400287 UINT32 trash;
Will Arthur54e04e42015-07-15 11:29:25 -0400288 TSS2_RC rval = TSS2_RC_SUCCESS;
289 fd_set readFds;
290 struct timeval tv, *tvPtr;
291 int32_t timeoutMsecs = timeout % 1000;
292 int iResult;
wcarthura05cdcc2015-12-04 18:07:16 -0500293 unsigned char responseSizeDelta = 0;
wcarthur1c827592016-04-27 11:07:51 -0400294 printf_type rmPrefix;
wcarthureedecd62015-11-20 16:59:45 -0500295
296 rval = CommonReceiveChecks( tctiContext, response_size, response_buffer );
297 if( rval != TSS2_RC_SUCCESS )
298 {
299 goto retSocketReceiveTpmResponse;
Philip Triccadfa41a52016-07-20 17:43:57 -0700300 }
301
Philip Tricca24f555c2017-10-13 17:51:53 -0700302 if (tcti_intel->status.rmDebugPrefix == 1)
wcarthur1c827592016-04-27 11:07:51 -0400303 rmPrefix = RM_PREFIX;
304 else
305 rmPrefix = NO_PREFIX;
306
wcarthur74a92a42015-12-07 16:02:12 -0500307 if( timeout == TSS2_TCTI_TIMEOUT_BLOCK )
Will Arthur54e04e42015-07-15 11:29:25 -0400308 {
wcarthur74a92a42015-12-07 16:02:12 -0500309 tvPtr = 0;
310 }
311 else
312 {
313 tv.tv_sec = timeout / 1000;
314 tv.tv_usec = timeoutMsecs * 1000;
315 tvPtr = &tv;
Will Arthur54e04e42015-07-15 11:29:25 -0400316 }
317
wcarthur74a92a42015-12-07 16:02:12 -0500318 FD_ZERO( &readFds );
Philip Tricca24f555c2017-10-13 17:51:53 -0700319 FD_SET(tcti_intel->tpmSock, &readFds);
Will Arthur54e04e42015-07-15 11:29:25 -0400320
Philip Tricca24f555c2017-10-13 17:51:53 -0700321 iResult = select(tcti_intel->tpmSock + 1, &readFds, 0, 0, tvPtr);
wcarthur74a92a42015-12-07 16:02:12 -0500322 if( iResult == 0 )
Will Arthur54e04e42015-07-15 11:29:25 -0400323 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700324 TCTI_LOG(tctiContext, rmPrefix, "select failed due to timeout, socket #: 0x%x\n", tcti_intel->tpmSock);
wcarthur74a92a42015-12-07 16:02:12 -0500325 rval = TSS2_TCTI_RC_TRY_AGAIN;
326 goto retSocketReceiveTpmResponse;
327 }
328 else if( iResult == SOCKET_ERROR )
329 {
wcarthur1c827592016-04-27 11:07:51 -0400330 TCTI_LOG( tctiContext, rmPrefix, "select failed with socket error: %d\n", WSAGetLastError() );
wcarthur74a92a42015-12-07 16:02:12 -0500331 rval = TSS2_TCTI_RC_IO_ERROR;
332 goto retSocketReceiveTpmResponse;
333 }
334 else if ( iResult != 1 )
335 {
wcarthur1c827592016-04-27 11:07:51 -0400336 TCTI_LOG( tctiContext, rmPrefix, "select failed, read the wrong # of bytes: %d\n", iResult );
wcarthur74a92a42015-12-07 16:02:12 -0500337 rval = TSS2_TCTI_RC_IO_ERROR;
338 goto retSocketReceiveTpmResponse;
339 }
Will Arthur54e04e42015-07-15 11:29:25 -0400340
Philip Tricca24f555c2017-10-13 17:51:53 -0700341 if (tcti_intel->status.protocolResponseSizeReceived != 1)
Philip Triccadfa41a52016-07-20 17:43:57 -0700342 {
Will Arthur54e04e42015-07-15 11:29:25 -0400343 // Receive the size of the response.
Philip Tricca24f555c2017-10-13 17:51:53 -0700344 rval = tctiRecvBytes(tctiContext, tcti_intel->tpmSock, (unsigned char *)&tcti_intel->responseSize, 4);
wcarthureedecd62015-11-20 16:59:45 -0500345 if( rval != TSS2_RC_SUCCESS )
346 goto retSocketReceiveTpmResponse;
347
Philip Tricca24f555c2017-10-13 17:51:53 -0700348 tcti_intel->responseSize = BE_TO_HOST_32(tcti_intel->responseSize);
349 tcti_intel->status.protocolResponseSizeReceived = 1;
Will Arthur54e04e42015-07-15 11:29:25 -0400350 }
351
wcarthur74a92a42015-12-07 16:02:12 -0500352 if( response_buffer == NULL )
Will Arthur54e04e42015-07-15 11:29:25 -0400353 {
wcarthur74a92a42015-12-07 16:02:12 -0500354 // In this case, just return the size
Philip Tricca24f555c2017-10-13 17:51:53 -0700355 *response_size = tcti_intel->responseSize;
356 tcti_intel->status.protocolResponseSizeReceived = 1;
wcarthur74a92a42015-12-07 16:02:12 -0500357 goto retSocketReceiveTpmResponse;
358 }
359
Philip Tricca24f555c2017-10-13 17:51:53 -0700360 if (*response_size < tcti_intel->responseSize)
wcarthur74a92a42015-12-07 16:02:12 -0500361 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700362 *response_size = tcti_intel->responseSize;
Philip Triccadfa41a52016-07-20 17:43:57 -0700363 rval = TSS2_TCTI_RC_INSUFFICIENT_BUFFER;
wcarthur74a92a42015-12-07 16:02:12 -0500364
365
366 // If possible, receive tag from TPM.
Philip Tricca24f555c2017-10-13 17:51:53 -0700367 if (*response_size >= sizeof( TPM_ST ) && tcti_intel->status.tagReceived == 0)
Will Arthur54e04e42015-07-15 11:29:25 -0400368 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700369 if(TSS2_RC_SUCCESS != tctiRecvBytes(tctiContext, tcti_intel->tpmSock, (unsigned char *)&tcti_intel->tag, 2))
wcarthur74a92a42015-12-07 16:02:12 -0500370 {
wcarthura05cdcc2015-12-04 18:07:16 -0500371 goto retSocketReceiveTpmResponse;
wcarthur2efe2912015-11-16 11:19:42 -0500372 }
wcarthur74a92a42015-12-07 16:02:12 -0500373 else
wcarthura05cdcc2015-12-04 18:07:16 -0500374 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700375 tcti_intel->status.tagReceived = 1;
wcarthura05cdcc2015-12-04 18:07:16 -0500376 }
Will Arthur54e04e42015-07-15 11:29:25 -0400377 }
wcarthura05cdcc2015-12-04 18:07:16 -0500378
wcarthur74a92a42015-12-07 16:02:12 -0500379 // If possible, receive response size from TPM
Philip Tricca24f555c2017-10-13 17:51:53 -0700380 if (*response_size >= (sizeof(TPM_ST) + sizeof(TPM_RC)) && tcti_intel->status.responseSizeReceived == 0)
wcarthur74a92a42015-12-07 16:02:12 -0500381 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700382 if(TSS2_RC_SUCCESS != tctiRecvBytes(tctiContext, tcti_intel->tpmSock, (unsigned char *)&tcti_intel->responseSize, 4))
wcarthura05cdcc2015-12-04 18:07:16 -0500383 {
wcarthureedecd62015-11-20 16:59:45 -0500384 goto retSocketReceiveTpmResponse;
wcarthur74a92a42015-12-07 16:02:12 -0500385 }
386 else
387 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700388 tcti_intel->responseSize = BE_TO_HOST_32 (tcti_intel->responseSize);
389 tcti_intel->status.responseSizeReceived = 1;
wcarthur74a92a42015-12-07 16:02:12 -0500390 }
391 }
392 }
393 else
394 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700395 if (tcti_intel->status.debugMsgEnabled == 1 &&
396 tcti_intel->responseSize > 0)
Will-nuce0d3ec22015-12-09 15:09:49 -0500397 {
398#ifdef DEBUG
wcarthur1c827592016-04-27 11:07:51 -0400399 TCTI_LOG( tctiContext, rmPrefix, "Response Received: " );
Will-nuce0d3ec22015-12-09 15:09:49 -0500400#endif
401#ifdef DEBUG_SOCKETS
Philip Tricca24f555c2017-10-13 17:51:53 -0700402 TCTI_LOG(tctiContext, rmPrefix, "from socket #0x%x:\n", tcti_intel->tpmSock);
Will-nuce0d3ec22015-12-09 15:09:49 -0500403#endif
404 }
Philip Triccadfa41a52016-07-20 17:43:57 -0700405
Philip Tricca24f555c2017-10-13 17:51:53 -0700406 if (tcti_intel->status.tagReceived == 1)
wcarthur74a92a42015-12-07 16:02:12 -0500407 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700408 *(TPM_ST *)response_buffer = tcti_intel->tag;
Tadeusz Struk83d12be2017-10-05 14:58:30 -0700409 responseSizeDelta += sizeof(TPM_ST);
410 response_buffer += sizeof(TPM_ST);
wcarthur74a92a42015-12-07 16:02:12 -0500411 }
412
Philip Tricca24f555c2017-10-13 17:51:53 -0700413 if (tcti_intel->status.responseSizeReceived == 1)
wcarthur74a92a42015-12-07 16:02:12 -0500414 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700415 *(TPM_RC *)response_buffer = HOST_TO_BE_32(tcti_intel->responseSize);
Tadeusz Struk83d12be2017-10-05 14:58:30 -0700416 responseSizeDelta += sizeof(TPM_RC);
417 response_buffer += sizeof(TPM_RC);
wcarthur74a92a42015-12-07 16:02:12 -0500418 }
419
420 // Receive the TPM response.
Philip Tricca24f555c2017-10-13 17:51:53 -0700421 rval = tctiRecvBytes(tctiContext, tcti_intel->tpmSock, (unsigned char *)response_buffer, tcti_intel->responseSize - responseSizeDelta );
wcarthur74a92a42015-12-07 16:02:12 -0500422 if( rval != TSS2_RC_SUCCESS )
423 goto retSocketReceiveTpmResponse;
wcarthureedecd62015-11-20 16:59:45 -0500424
wcarthur2efe2912015-11-16 11:19:42 -0500425#ifdef DEBUG
Philip Tricca24f555c2017-10-13 17:51:53 -0700426 if (tcti_intel->status.debugMsgEnabled == 1)
wcarthur74a92a42015-12-07 16:02:12 -0500427 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700428 DEBUG_PRINT_BUFFER(rmPrefix, response_buffer, tcti_intel->responseSize);
wcarthur0651af22015-11-25 15:01:22 -0500429 }
wcarthur74a92a42015-12-07 16:02:12 -0500430#endif
wcarthur0651af22015-11-25 15:01:22 -0500431
wcarthur74a92a42015-12-07 16:02:12 -0500432 // Receive the appended four bytes of 0's
Philip Tricca24f555c2017-10-13 17:51:53 -0700433 rval = tctiRecvBytes(tctiContext, tcti_intel->tpmSock, (unsigned char *)&trash, 4);
wcarthur74a92a42015-12-07 16:02:12 -0500434 if( rval != TSS2_RC_SUCCESS )
435 goto retSocketReceiveTpmResponse;
Will Arthur54e04e42015-07-15 11:29:25 -0400436 }
437
Philip Tricca24f555c2017-10-13 17:51:53 -0700438 if (tcti_intel->responseSize < *response_size)
Will Arthur54e04e42015-07-15 11:29:25 -0400439 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700440 *response_size = tcti_intel->responseSize;
Will Arthur54e04e42015-07-15 11:29:25 -0400441 }
Philip Triccadfa41a52016-07-20 17:43:57 -0700442
Philip Tricca24f555c2017-10-13 17:51:53 -0700443 tcti_intel->status.commandSent = 0;
Will Arthur54e04e42015-07-15 11:29:25 -0400444
445 // Turn cancel off.
wcarthur2efe2912015-11-16 11:19:42 -0500446 if( rval == TSS2_RC_SUCCESS )
447 {
448 rval = (TSS2_RC)PlatformCommand( tctiContext, MS_SIM_CANCEL_OFF );
449 }
450 else
451 {
452 // Ignore return value so earlier error code is preserved.
453 PlatformCommand( tctiContext, MS_SIM_CANCEL_OFF );
454 }
Will Arthur54e04e42015-07-15 11:29:25 -0400455
Will Arthur54e04e42015-07-15 11:29:25 -0400456retSocketReceiveTpmResponse:
Tadeusz Struk83d12be2017-10-05 14:58:30 -0700457 if (rval == TSS2_RC_SUCCESS && response_buffer != NULL)
wcarthureedecd62015-11-20 16:59:45 -0500458 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700459 tcti_intel->previousStage = TCTI_STAGE_RECEIVE_RESPONSE;
wcarthureedecd62015-11-20 16:59:45 -0500460 }
Philip Triccadfa41a52016-07-20 17:43:57 -0700461
Will Arthur54e04e42015-07-15 11:29:25 -0400462 return rval;
463}
464
Will Arthur54e04e42015-07-15 11:29:25 -0400465#define HOSTNAME_LENGTH 200
466#define PORT_LENGTH 4
467
Philip Tricca40e926d2016-09-22 20:37:28 -0700468/**
469 * This function sends the Microsoft simulator the MS_SIM_POWER_ON and
470 * MS_SIM_NV_ON commands using the PlatformCommand mechanism. Without
471 * these the simulator will respond with zero sized buffer which causes
472 * the TSS to freak out. Sending this command more than once is harmelss
473 * so it's advisable to call this function as part of the TCTI context
474 * initialization just to be sure.
475 *
476 * NOTE: The caller will still need to call Tss2_Sys_Startup. If they
477 * don't, an error will be returned from each call till they do but
478 * the error will at least be meaningful (TPM_RC_INITIALIZE).
479 */
480static TSS2_RC InitializeMsTpm2Simulator(
481 TSS2_TCTI_CONTEXT *tctiContext
482 )
483{
Philip Tricca24f555c2017-10-13 17:51:53 -0700484 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Philip Tricca40e926d2016-09-22 20:37:28 -0700485 TSS2_RC rval;
486
Philip Tricca40e926d2016-09-22 20:37:28 -0700487 rval = PlatformCommand( tctiContext ,MS_SIM_POWER_ON );
488 if( rval != TSS2_RC_SUCCESS ) {
Philip Tricca24f555c2017-10-13 17:51:53 -0700489 CloseSockets( tcti_intel->otherSock, tcti_intel->tpmSock );
Philip Tricca40e926d2016-09-22 20:37:28 -0700490 return rval;
491 }
492 rval = PlatformCommand( tctiContext, MS_SIM_NV_ON );
493 if( rval != TSS2_RC_SUCCESS )
Philip Tricca24f555c2017-10-13 17:51:53 -0700494 CloseSockets( tcti_intel->otherSock, tcti_intel->tpmSock );
Philip Tricca40e926d2016-09-22 20:37:28 -0700495
496 return rval;
497}
498
Philip Triccad1bbedb2016-02-14 20:39:59 -0800499TSS2_RC InitSocketTcti (
Will Arthur54e04e42015-07-15 11:29:25 -0400500 TSS2_TCTI_CONTEXT *tctiContext, // OUT
501 size_t *contextSize, // IN/OUT
Philip Tricca6feb9762016-02-23 10:44:09 -0800502 const TCTI_SOCKET_CONF *conf, // IN
Will Arthur54e04e42015-07-15 11:29:25 -0400503 const uint8_t serverSockets
504 )
505{
Philip Tricca24f555c2017-10-13 17:51:53 -0700506 TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (tctiContext);
Will Arthur54e04e42015-07-15 11:29:25 -0400507 TSS2_RC rval = TSS2_RC_SUCCESS;
Will Arthur54e04e42015-07-15 11:29:25 -0400508 SOCKET otherSock;
509 SOCKET tpmSock;
510
Philip Tricca4ccb5322017-06-29 08:07:17 -0700511 if( tctiContext == NULL && contextSize == NULL )
512 {
513 return TSS2_TCTI_RC_BAD_VALUE;
514 }
515 else if( tctiContext == NULL )
Will Arthur54e04e42015-07-15 11:29:25 -0400516 {
517 *contextSize = sizeof( TSS2_TCTI_CONTEXT_INTEL );
518 return TSS2_RC_SUCCESS;
519 }
Philip Tricca4ccb5322017-06-29 08:07:17 -0700520 else if( conf == NULL )
521 {
522 return TSS2_TCTI_RC_BAD_VALUE;
523 }
Will Arthur54e04e42015-07-15 11:29:25 -0400524 else
525 {
Will Arthur54e04e42015-07-15 11:29:25 -0400526 // Init TCTI context.
Philip Tricca7b4948e2016-04-18 20:43:59 -0700527 TSS2_TCTI_MAGIC( tctiContext ) = TCTI_MAGIC;
528 TSS2_TCTI_VERSION( tctiContext ) = TCTI_VERSION;
529 TSS2_TCTI_TRANSMIT( tctiContext ) = SocketSendTpmCommand;
530 TSS2_TCTI_RECEIVE( tctiContext ) = SocketReceiveTpmResponse;
531 TSS2_TCTI_FINALIZE( tctiContext ) = SocketFinalize;
532 TSS2_TCTI_CANCEL( tctiContext ) = SocketCancel;
Philip Tricca5917fbf2017-06-29 08:24:09 -0700533 TSS2_TCTI_GET_POLL_HANDLES( tctiContext ) = SocketGetPollHandles;
Philip Tricca7b4948e2016-04-18 20:43:59 -0700534 TSS2_TCTI_SET_LOCALITY( tctiContext ) = SocketSetLocality;
Philip Tricca24f555c2017-10-13 17:51:53 -0700535 tcti_intel->status.debugMsgEnabled = 0;
536 tcti_intel->status.locality = 3;
537 tcti_intel->status.commandSent = 0;
538 tcti_intel->status.rmDebugPrefix = 0;
539 tcti_intel->status.tagReceived = 0;
540 tcti_intel->status.responseSizeReceived = 0;
541 tcti_intel->status.protocolResponseSizeReceived = 0;
542 tcti_intel->currentTctiContext = 0;
543 tcti_intel->previousStage = TCTI_STAGE_INITIALIZE;
Philip Triccabcc73032016-03-30 19:50:54 -0700544 TCTI_LOG_CALLBACK( tctiContext ) = conf->logCallback;
Philip Tricca4eb2f352016-03-31 05:55:35 -0700545 TCTI_LOG_BUFFER_CALLBACK( tctiContext ) = conf->logBufferCallback;
Philip Triccabcc73032016-03-30 19:50:54 -0700546 TCTI_LOG_DATA( tctiContext ) = conf->logData;
Will Arthur54e04e42015-07-15 11:29:25 -0400547
Philip Tricca14d9fbc2017-07-04 10:52:14 -0700548 rval = (TSS2_RC) InitSockets( conf->hostname, conf->port, &otherSock, &tpmSock, TCTI_LOG_CALLBACK( tctiContext ), TCTI_LOG_DATA( tctiContext) );
Will Arthur54e04e42015-07-15 11:29:25 -0400549 if( rval == TSS2_RC_SUCCESS )
550 {
Philip Tricca24f555c2017-10-13 17:51:53 -0700551 tcti_intel->otherSock = otherSock;
552 tcti_intel->tpmSock = tpmSock;
Tadeusz Struk83d12be2017-10-05 14:58:30 -0700553 rval = InitializeMsTpm2Simulator(tctiContext);
Will Arthur54e04e42015-07-15 11:29:25 -0400554 }
555 else
556 {
Will Arthurca8e7f32015-08-03 15:35:19 -0400557 CloseSockets( otherSock, tpmSock);
Philip Triccadfa41a52016-07-20 17:43:57 -0700558 }
Will Arthur54e04e42015-07-15 11:29:25 -0400559 }
560
561 return rval;
562}