1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2004-2007
8  *
9  */
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <syslog.h>
14 #include <string.h>
15 #include <netdb.h>
16 #if (defined (__OpenBSD__) || defined (__FreeBSD__) || defined(__NetBSD__))
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #endif
21 #include <errno.h>
22 
23 #include "trousers/tss.h"
24 #include "trousers_types.h"
25 #include "tcs_tsp.h"
26 #include "tcs_utils.h"
27 #include "tcs_int_literals.h"
28 #include "capabilities.h"
29 #include "tcslog.h"
30 #include "tcsd_wrap.h"
31 #include "tcsd.h"
32 #include "rpc_tcstp_tcs.h"
33 
34 
35 /* Lock is not static because we need to reference it in the auth manager */
36 MUTEX_DECLARE_INIT(tcsp_lock);
37 
38 
39 void
LoadBlob_Auth_Special(UINT64 * offset,BYTE * blob,TPM_AUTH * auth)40 LoadBlob_Auth_Special(UINT64 *offset, BYTE *blob, TPM_AUTH *auth)
41 {
42           LoadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, auth->NonceEven.nonce);
43           LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob);
44           LoadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, (BYTE *)&auth->HMAC);
45 }
46 
47 void
UnloadBlob_Auth_Special(UINT64 * offset,BYTE * blob,TPM_AUTH * auth)48 UnloadBlob_Auth_Special(UINT64 *offset, BYTE *blob, TPM_AUTH *auth)
49 {
50           UnloadBlob_UINT32(offset, &auth->AuthHandle, blob);
51           UnloadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, auth->NonceOdd.nonce);
52           UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob);
53           UnloadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, (BYTE *)&auth->HMAC);
54 }
55 
56 int
recv_from_socket(int sock,void * buffer,int size)57 recv_from_socket(int sock, void *buffer, int size)
58 {
59         int recv_size = 0, recv_total = 0;
60 
61           while (recv_total < size) {
62                     errno = 0;
63                     if ((recv_size = recv(sock, buffer+recv_total, size-recv_total, 0)) <= 0) {
64                               if (recv_size < 0) {
65                                         if (errno == EINTR)
66                                                   continue;
67                                         LogError("Socket receive connection error: %s.", strerror(errno));
68                               } else {
69                                         LogDebug("Socket connection closed.");
70                               }
71 
72                               return -1;
73                     }
74                     recv_total += recv_size;
75           }
76 
77           return recv_total;
78 }
79 
80 int
send_to_socket(int sock,void * buffer,int size)81 send_to_socket(int sock, void *buffer, int size)
82 {
83           int send_size = 0, send_total = 0;
84 
85           while (send_total < size) {
86                     if ((send_size = send(sock, buffer+send_total, size-send_total, 0)) < 0) {
87                               LogError("Socket send connection error: %s.", strerror(errno));
88                               return -1;
89                     }
90                     send_total += send_size;
91           }
92 
93           return send_total;
94 }
95 
96 
97 void
initData(struct tcsd_comm_data * comm,int parm_count)98 initData(struct tcsd_comm_data *comm, int parm_count)
99 {
100           /* min packet size should be the size of the header */
101           memset(&comm->hdr, 0, sizeof(struct tcsd_packet_hdr));
102           comm->hdr.packet_size = sizeof(struct tcsd_packet_hdr);
103           if (parm_count > 0) {
104                     comm->hdr.type_offset = sizeof(struct tcsd_packet_hdr);
105                     comm->hdr.parm_offset = comm->hdr.type_offset +
106                               (sizeof(TCSD_PACKET_TYPE) * parm_count);
107                     comm->hdr.packet_size = comm->hdr.parm_offset;
108           }
109 
110           memset(comm->buf, 0, comm->buf_size);
111 }
112 
113 int
loadData(UINT64 * offset,TCSD_PACKET_TYPE data_type,void * data,int data_size,BYTE * blob)114 loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob)
115 {
116           switch (data_type) {
117                     case TCSD_PACKET_TYPE_BYTE:
118                               LoadBlob_BYTE(offset, *((BYTE *) (data)), blob);
119                               break;
120                     case TCSD_PACKET_TYPE_BOOL:
121                               LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob);
122                               break;
123                     case TCSD_PACKET_TYPE_UINT16:
124                               LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob);
125                               break;
126                     case TCSD_PACKET_TYPE_UINT32:
127                               LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob);
128                               break;
129                     case TCSD_PACKET_TYPE_UINT64:
130                               LoadBlob_UINT64(offset, *((UINT64 *) (data)), blob);
131                               break;
132                     case TCSD_PACKET_TYPE_PBYTE:
133                               LoadBlob(offset, data_size, blob, data);
134                               break;
135                     case TCSD_PACKET_TYPE_NONCE:
136                               LoadBlob(offset, sizeof(TCPA_NONCE), blob, ((TCPA_NONCE *)data)->nonce);
137                               break;
138                     case TCSD_PACKET_TYPE_DIGEST:
139                               LoadBlob(offset, sizeof(TCPA_DIGEST), blob, ((TCPA_DIGEST *)data)->digest);
140                               break;
141                     case TCSD_PACKET_TYPE_AUTH:
142                               LoadBlob_Auth_Special(offset, blob, ((TPM_AUTH *)data));
143                               break;
144 #ifdef TSS_BUILD_PS
145                     case TCSD_PACKET_TYPE_UUID:
146                               LoadBlob_UUID(offset, blob, *((TSS_UUID *)data));
147                               break;
148                     case TCSD_PACKET_TYPE_KM_KEYINFO:
149                               LoadBlob_KM_KEYINFO(offset, blob, ((TSS_KM_KEYINFO *)data));
150                               break;
151                     case TCSD_PACKET_TYPE_KM_KEYINFO2:
152                               LoadBlob_KM_KEYINFO2(offset, blob, ((TSS_KM_KEYINFO2 *)data));
153                               break;
154                     case TCSD_PACKET_TYPE_LOADKEY_INFO:
155                               LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data));
156                               break;
157 #endif
158                     case TCSD_PACKET_TYPE_ENCAUTH:
159                               LoadBlob(offset, sizeof(TCPA_ENCAUTH), blob,
160                                          ((TCPA_ENCAUTH *)data)->authdata);
161                               break;
162                     case TCSD_PACKET_TYPE_VERSION:
163                               LoadBlob_VERSION(offset, blob, ((TPM_VERSION *)data));
164                               break;
165 #ifdef TSS_BUILD_PCR_EVENTS
166                     case TCSD_PACKET_TYPE_PCR_EVENT:
167                               LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data));
168                               break;
169 #endif
170                     case TCSD_PACKET_TYPE_SECRET:
171                               LoadBlob(offset, sizeof(TCPA_SECRET), blob,
172                                          ((TCPA_SECRET *)data)->authdata);
173                               break;
174                     default:
175                               LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff);
176                               return TCSERR(TSS_E_INTERNAL_ERROR);
177           }
178 
179           return TSS_SUCCESS;
180 }
181 
182 
183 int
setData(TCSD_PACKET_TYPE dataType,unsigned int index,void * theData,int theDataSize,struct tcsd_comm_data * comm)184 setData(TCSD_PACKET_TYPE dataType,
185           unsigned int index,
186           void *theData,
187           int theDataSize,
188           struct tcsd_comm_data *comm)
189 {
190           UINT64 old_offset, offset;
191           TSS_RESULT result;
192           TCSD_PACKET_TYPE *type;
193 
194           /* Calculate the size of the area needed (use NULL for blob address) */
195           offset = 0;
196           if ((result = loadData(&offset, dataType, theData, theDataSize, NULL)) != TSS_SUCCESS)
197                     return result;
198 
199           if ((comm->hdr.packet_size + offset) > comm->buf_size) {
200                     /* reallocate the buffer */
201                     BYTE *buffer;
202                     int buffer_size = comm->hdr.packet_size + offset;
203 
204                     LogDebug("Increasing communication buffer to %d bytes.", buffer_size);
205                     buffer = realloc(comm->buf, buffer_size);
206                     if (buffer == NULL) {
207                               LogError("realloc of %d bytes failed.", buffer_size);
208                               return TCSERR(TSS_E_INTERNAL_ERROR);
209                     }
210                     comm->buf_size = buffer_size;
211                     comm->buf = buffer;
212           }
213 
214           offset = old_offset = comm->hdr.parm_offset + comm->hdr.parm_size;
215           if ((result = loadData(&offset, dataType, theData, theDataSize, comm->buf)) != TSS_SUCCESS)
216                     return result;
217           type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index;
218           *type = dataType;
219           comm->hdr.type_size += sizeof(TCSD_PACKET_TYPE);
220           comm->hdr.parm_size += (offset - old_offset);
221 
222           comm->hdr.packet_size = offset;
223           comm->hdr.num_parms++;
224 
225           return TSS_SUCCESS;
226 }
227 
228 UINT32
getData(TCSD_PACKET_TYPE dataType,unsigned int index,void * theData,int theDataSize,struct tcsd_comm_data * comm)229 getData(TCSD_PACKET_TYPE dataType,
230           unsigned int index,
231           void *theData,
232           int theDataSize,
233           struct tcsd_comm_data *comm)
234 {
235           UINT64 old_offset, offset;
236           TCSD_PACKET_TYPE *type;
237 
238           if ((comm->hdr.type_offset + index) > comm->buf_size)
239                     return TSS_TCP_RPC_BAD_PACKET_TYPE;
240 
241           type = (comm->buf + comm->hdr.type_offset) + index;
242 
243           if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) {
244                     LogDebug("Data type of TCS packet element %d doesn't match.", index);
245                     return TSS_TCP_RPC_BAD_PACKET_TYPE;
246           }
247           old_offset = offset = comm->hdr.parm_offset;
248           switch (dataType) {
249                     case TCSD_PACKET_TYPE_BYTE:
250                               if (old_offset + sizeof(BYTE) > comm->hdr.packet_size)
251                                         return TCSERR(TSS_E_INTERNAL_ERROR);
252 
253                               UnloadBlob_BYTE(&offset, (BYTE *) (theData), comm->buf);
254                               break;
255                     case TCSD_PACKET_TYPE_BOOL:
256                               if (old_offset + sizeof(TSS_BOOL) > comm->hdr.packet_size)
257                                         return TCSERR(TSS_E_INTERNAL_ERROR);
258 
259                               UnloadBlob_BOOL(&offset, (TSS_BOOL *) (theData), comm->buf);
260                               break;
261                     case TCSD_PACKET_TYPE_UINT16:
262                               if (old_offset + sizeof(UINT16) > comm->hdr.packet_size)
263                                         return TCSERR(TSS_E_INTERNAL_ERROR);
264 
265                               UnloadBlob_UINT16(&offset, (UINT16 *) (theData), comm->buf);
266                               break;
267                     case TCSD_PACKET_TYPE_UINT32:
268                               if (old_offset + sizeof(UINT32) > comm->hdr.packet_size)
269                                         return TCSERR(TSS_E_INTERNAL_ERROR);
270 
271                               UnloadBlob_UINT32(&offset, (UINT32 *) (theData), comm->buf);
272                               break;
273                     case TCSD_PACKET_TYPE_PBYTE:
274                               if (old_offset + theDataSize > comm->hdr.packet_size)
275                                         return TCSERR(TSS_E_INTERNAL_ERROR);
276 
277                               UnloadBlob(&offset, theDataSize, comm->buf, theData);
278                               break;
279                     case TCSD_PACKET_TYPE_NONCE:
280                               if (old_offset + sizeof(TPM_NONCE) > comm->hdr.packet_size)
281                                         return TCSERR(TSS_E_INTERNAL_ERROR);
282 
283                               UnloadBlob(&offset, sizeof(TCPA_NONCE), comm->buf,
284                                                   ((TCPA_NONCE *) (theData))->nonce);
285                               break;
286                     case TCSD_PACKET_TYPE_DIGEST:
287                               if (old_offset + sizeof(TPM_DIGEST) > comm->hdr.packet_size)
288                                         return TCSERR(TSS_E_INTERNAL_ERROR);
289 
290                               UnloadBlob(&offset, sizeof(TCPA_DIGEST), comm->buf,
291                                                   ((TCPA_DIGEST *) (theData))->digest);
292                               break;
293                     case TCSD_PACKET_TYPE_AUTH:
294                               if ((old_offset + sizeof(TCS_AUTHHANDLE)
295                                                   + sizeof(TPM_BOOL)
296                                                   + (2 * sizeof(TPM_NONCE))) > comm->hdr.packet_size)
297                                         return TCSERR(TSS_E_INTERNAL_ERROR);
298 
299                               UnloadBlob_Auth_Special(&offset, comm->buf, ((TPM_AUTH *) theData));
300                               break;
301                     case TCSD_PACKET_TYPE_ENCAUTH:
302                               if (old_offset + sizeof(TPM_ENCAUTH) > comm->hdr.packet_size)
303                                         return TCSERR(TSS_E_INTERNAL_ERROR);
304 
305                               UnloadBlob(&offset, sizeof(TCPA_ENCAUTH), comm->buf,
306                                                   ((TCPA_ENCAUTH *) theData)->authdata);
307                               break;
308                     case TCSD_PACKET_TYPE_VERSION:
309                               if (old_offset + sizeof(TPM_VERSION) > comm->hdr.packet_size)
310                                         return TCSERR(TSS_E_INTERNAL_ERROR);
311 
312                               UnloadBlob_VERSION(&offset, comm->buf, ((TPM_VERSION *) theData));
313                               break;
314 #ifdef TSS_BUILD_PS
315                     case TCSD_PACKET_TYPE_KM_KEYINFO:
316                               UnloadBlob_KM_KEYINFO(&old_offset, comm->buf, NULL);
317 
318                               if (old_offset > comm->hdr.packet_size)
319                                         return TCSERR(TSS_E_INTERNAL_ERROR);
320 
321                               old_offset = offset;
322                               UnloadBlob_KM_KEYINFO(&offset, comm->buf, ((TSS_KM_KEYINFO *)theData));
323                               break;
324                     case TCSD_PACKET_TYPE_LOADKEY_INFO:
325                               UnloadBlob_LOADKEY_INFO(&old_offset, comm->buf, NULL);
326 
327                               if (old_offset > comm->hdr.packet_size)
328                                         return TCSERR(TSS_E_INTERNAL_ERROR);
329 
330                               old_offset = offset;
331                               UnloadBlob_LOADKEY_INFO(&offset, comm->buf, ((TCS_LOADKEY_INFO *)theData));
332                               break;
333                     case TCSD_PACKET_TYPE_UUID:
334                               if (old_offset + sizeof(TSS_UUID) > comm->hdr.packet_size)
335                                         return TCSERR(TSS_E_INTERNAL_ERROR);
336 
337                               UnloadBlob_UUID(&offset, comm->buf, (TSS_UUID *) theData);
338                               break;
339 #endif
340 #ifdef TSS_BUILD_PCR_EVENTS
341                     case TCSD_PACKET_TYPE_PCR_EVENT:
342                     {
343                               TSS_RESULT result;
344 
345                               (void)UnloadBlob_PCR_EVENT(&old_offset, comm->buf, NULL);
346 
347                               if (old_offset > comm->hdr.packet_size)
348                                         return TCSERR(TSS_E_INTERNAL_ERROR);
349 
350                               old_offset = offset;
351                               if ((result = UnloadBlob_PCR_EVENT(&offset, comm->buf,
352                                                                          ((TSS_PCR_EVENT *)theData))))
353                                         return result;
354                               break;
355                     }
356 #endif
357                     case TCSD_PACKET_TYPE_SECRET:
358                               if (old_offset + sizeof(TPM_SECRET) > comm->hdr.packet_size)
359                                         return TCSERR(TSS_E_INTERNAL_ERROR);
360 
361                               UnloadBlob(&offset, sizeof(TCPA_SECRET), comm->buf,
362                                                   ((TCPA_SECRET *) theData)->authdata);
363                               break;
364                     default:
365                               LogError("TCSD packet type unknown! (0x%x)", dataType & 0xff);
366                               return TCSERR(TSS_E_INTERNAL_ERROR);
367           }
368           comm->hdr.parm_offset = offset;
369           comm->hdr.parm_size -= (offset - old_offset);
370 
371           return TSS_SUCCESS;
372 }
373 
374 TSS_RESULT
tcs_wrap_Error(struct tcsd_thread_data * data)375 tcs_wrap_Error(struct tcsd_thread_data *data)
376 {
377           LogError("%s reached.", __FUNCTION__);
378 
379           initData(&data->comm, 0);
380 
381           data->comm.hdr.u.result = TCSERR(TSS_E_FAIL);
382 
383           return TSS_SUCCESS;
384 
385 }
386 
387 /* Dispatch */
388 typedef struct tdDispatchTable {
389           TSS_RESULT (*Func) (struct tcsd_thread_data *);
390           const char *name;
391 } DispatchTable;
392 
393 DispatchTable tcs_func_table[TCSD_MAX_NUM_ORDS] = {
394           {tcs_wrap_Error,"Error"},   /* 0 */
395           {tcs_wrap_OpenContext,"OpenContext"},
396           {tcs_wrap_CloseContext,"CloseContext"},
397           {tcs_wrap_Error,"Error"},
398           {tcs_wrap_TCSGetCapability,"TCSGetCapability"},
399           {tcs_wrap_RegisterKey,"RegisterKey"}, /* 5 */
400           {tcs_wrap_UnregisterKey,"UnregisterKey"},
401           {tcs_wrap_EnumRegisteredKeys,"EnumRegisteredKeys"},
402           {tcs_wrap_Error,"Error"},
403           {tcs_wrap_GetRegisteredKeyBlob,"GetRegisteredKeyBlob"},
404           {tcs_wrap_GetRegisteredKeyByPublicInfo,"GetRegisteredKeyByPublicInfo"}, /* 10 */
405           {tcs_wrap_LoadKeyByBlob,"LoadKeyByBlob"},
406           {tcs_wrap_LoadKeyByUUID,"LoadKeyByUUID"},
407           {tcs_wrap_EvictKey,"EvictKey"},
408           {tcs_wrap_CreateWrapKey,"CreateWrapKey"},
409           {tcs_wrap_GetPubkey,"GetPubkey"}, /* 15 */
410           {tcs_wrap_MakeIdentity,"MakeIdentity"},
411           {tcs_wrap_LogPcrEvent,"LogPcrEvent"},
412           {tcs_wrap_GetPcrEvent,"GetPcrEvent"},
413           {tcs_wrap_GetPcrEventsByPcr,"GetPcrEventsByPcr"},
414           {tcs_wrap_GetPcrEventLog,"GetPcrEventLog"}, /* 20 */
415           {tcs_wrap_SetOwnerInstall,"SetOwnerInstall"},
416           {tcs_wrap_TakeOwnership,"TakeOwnership"},
417           {tcs_wrap_OIAP,"OIAP"},
418           {tcs_wrap_OSAP,"OSAP"},
419           {tcs_wrap_ChangeAuth,"ChangeAuth"}, /* 25 */
420           {tcs_wrap_ChangeAuthOwner,"ChangeAuthOwner"},
421           {tcs_wrap_Error,"Error"},
422           {tcs_wrap_Error,"Error"},
423           {tcs_wrap_TerminateHandle,"TerminateHandle"},
424           {tcs_wrap_ActivateIdentity,"ActivateIdentity"}, /* 30 */
425           {tcs_wrap_Extend,"Extend"},
426           {tcs_wrap_PcrRead,"PcrRead"},
427           {tcs_wrap_Quote,"Quote"},
428           {tcs_wrap_DirWriteAuth,"DirWriteAuth"},
429           {tcs_wrap_DirRead,"DirRead"}, /* 35 */
430           {tcs_wrap_Seal,"Seal"},
431           {tcs_wrap_UnSeal,"UnSeal"},
432           {tcs_wrap_UnBind,"UnBind"},
433           {tcs_wrap_CreateMigrationBlob,"CreateMigrationBlob"},
434           {tcs_wrap_ConvertMigrationBlob,"ConvertMigrationBlob"}, /* 40 */
435           {tcs_wrap_AuthorizeMigrationKey,"AuthorizeMigrationKey"},
436           {tcs_wrap_CertifyKey,"CertifyKey"},
437           {tcs_wrap_Sign,"Sign"},
438           {tcs_wrap_GetRandom,"GetRandom"},
439           {tcs_wrap_StirRandom,"StirRandom"}, /* 45 */
440           {tcs_wrap_GetCapability,"GetCapability"},
441           {tcs_wrap_Error,"Error"},
442           {tcs_wrap_GetCapabilityOwner,"GetCapabilityOwner"},
443           {tcs_wrap_CreateEndorsementKeyPair,"CreateEndorsementKeyPair"},
444           {tcs_wrap_ReadPubek,"ReadPubek"}, /* 50 */
445           {tcs_wrap_DisablePubekRead,"DisablePubekRead"},
446           {tcs_wrap_OwnerReadPubek,"OwnerReadPubek"},
447           {tcs_wrap_SelfTestFull,"SelfTestFull"},
448           {tcs_wrap_CertifySelfTest,"CertifySelfTest"},
449           {tcs_wrap_Error,"Error"}, /* 55 */
450           {tcs_wrap_GetTestResult,"GetTestResult"},
451           {tcs_wrap_OwnerSetDisable,"OwnerSetDisable"},
452           {tcs_wrap_OwnerClear,"OwnerClear"},
453           {tcs_wrap_DisableOwnerClear,"DisableOwnerClear"},
454           {tcs_wrap_ForceClear,"ForceClear"}, /* 60 */
455           {tcs_wrap_DisableForceClear,"DisableForceClear"},
456           {tcs_wrap_PhysicalDisable,"PhysicalDisable"},
457           {tcs_wrap_PhysicalEnable,"PhysicalEnable"},
458           {tcs_wrap_PhysicalSetDeactivated,"PhysicalSetDeactivated"},
459           {tcs_wrap_SetTempDeactivated,"SetTempDeactivated"}, /* 65 */
460           {tcs_wrap_PhysicalPresence,"PhysicalPresence"},
461           {tcs_wrap_Error,"Error"},
462           {tcs_wrap_Error,"Error"},
463           {tcs_wrap_CreateMaintenanceArchive,"CreateMaintenanceArchive"},
464           {tcs_wrap_LoadMaintenanceArchive,"LoadMaintenanceArchive"}, /* 70 */
465           {tcs_wrap_KillMaintenanceFeature,"KillMaintenanceFeature"},
466           {tcs_wrap_LoadManuMaintPub,"LoadManuMaintPub"},
467           {tcs_wrap_ReadManuMaintPub,"ReadManuMaintPub"},
468           {tcs_wrap_DaaJoin,"DaaJoin"},
469           {tcs_wrap_DaaSign,"DaaSign"}, /* 75 */
470           {tcs_wrap_SetCapability,"SetCapability"},
471           {tcs_wrap_ResetLockValue,"ResetLockValue"},
472           {tcs_wrap_PcrReset,"PcrReset"},
473           {tcs_wrap_ReadCounter,"ReadCounter"},
474           {tcs_wrap_CreateCounter,"CreateCounter"}, /* 80 */
475           {tcs_wrap_IncrementCounter,"IncrementCounter"},
476           {tcs_wrap_ReleaseCounter,"ReleaseCounter"},
477           {tcs_wrap_ReleaseCounterOwner,"ReleaseCounterOwner"},
478           {tcs_wrap_ReadCurrentTicks,"ReadCurrentTicks"},
479           {tcs_wrap_TickStampBlob,"TicksStampBlob"}, /* 85 */
480           {tcs_wrap_GetCredential,"GetCredential"},
481           {tcs_wrap_NV_DefineOrReleaseSpace,"NVDefineOrReleaseSpace"},
482           {tcs_wrap_NV_WriteValue,"NVWriteValue"},
483           {tcs_wrap_NV_WriteValueAuth,"NVWriteValueAuth"},
484           {tcs_wrap_NV_ReadValue,"NVReadValue"}, /* 90 */
485           {tcs_wrap_NV_ReadValueAuth,"NVReadValueAuth"},
486           {tcs_wrap_EstablishTransport,"EstablishTransport"},
487           {tcs_wrap_ExecuteTransport,"ExecuteTransport"},
488           {tcs_wrap_ReleaseTransportSigned,"ReleaseTransportSigned"},
489           {tcs_wrap_SetOrdinalAuditStatus,"SetOrdinalAuditStatus"}, /* 95 */
490           {tcs_wrap_GetAuditDigest,"GetAuditDigest"},
491           {tcs_wrap_GetAuditDigestSigned,"GetAuditDigestSigned"},
492           {tcs_wrap_Sealx,"Sealx"},
493           {tcs_wrap_SetOperatorAuth,"SetOperatorAuth"},
494           {tcs_wrap_OwnerReadInternalPub,"OwnerReadInternalPub"}, /* 100 */
495           {tcs_wrap_EnumRegisteredKeys2,"EnumRegisteredKeys2"},
496           {tcs_wrap_SetTempDeactivated2,"SetTempDeactivated2"},
497           {tcs_wrap_Delegate_Manage,"Delegate_Manage"},
498           {tcs_wrap_Delegate_CreateKeyDelegation,"Delegate_CreateKeyDelegation"},
499           {tcs_wrap_Delegate_CreateOwnerDelegation,"Delegate_CreateOwnerDelegation"}, /* 105 */
500           {tcs_wrap_Delegate_LoadOwnerDelegation,"Delegate_LoadOwnerDelegation"},
501           {tcs_wrap_Delegate_ReadTable,"Delegate_ReadTable"},
502           {tcs_wrap_Delegate_UpdateVerificationCount,"Delegate_UpdateVerificationCount"},
503           {tcs_wrap_Delegate_VerifyDelegation,"Delegate_VerifyDelegation"},
504           {tcs_wrap_CreateRevocableEndorsementKeyPair,"CreateRevocableEndorsementKeyPair"}, /* 110 */
505           {tcs_wrap_RevokeEndorsementKeyPair,"RevokeEndorsementKeyPair"},
506           {tcs_wrap_Error,"Error - was MakeIdentity2"},
507           {tcs_wrap_Quote2,"Quote2"},
508           {tcs_wrap_CMK_SetRestrictions,"CMK_SetRestrictions"},
509           {tcs_wrap_CMK_ApproveMA,"CMK_ApproveMA"}, /* 115 */
510           {tcs_wrap_CMK_CreateKey,"CMK_CreateKey"},
511           {tcs_wrap_CMK_CreateTicket,"CMK_CreateTicket"},
512           {tcs_wrap_CMK_CreateBlob,"CMK_CreateBlob"},
513           {tcs_wrap_CMK_ConvertMigration,"CMK_ConvertMigration"},
514           {tcs_wrap_FlushSpecific,"FlushSpecific"}, /* 120 */
515           {tcs_wrap_KeyControlOwner, "KeyControlOwner"},
516           {tcs_wrap_DSAP, "DSAP"}
517 };
518 
519 int
access_control(struct tcsd_thread_data * thread_data)520 access_control(struct tcsd_thread_data *thread_data)
521 {
522           int i = 0;
523           int is_localhost;
524           struct sockaddr_storage sas;
525           struct sockaddr *sa;
526           socklen_t sas_len = sizeof(sas);
527 
528           if (getpeername(thread_data->sock, (struct sockaddr *)&sas,
529                               &sas_len) == -1) {
530                     LogError("Error retrieving local socket address: %s", strerror(errno));
531                     return 1;
532           }
533 
534           sa = (struct sockaddr *)&sas;
535 
536           is_localhost = 0;
537           // Check if it's localhost for both inet protocols
538           if (sa->sa_family == AF_INET) {
539                     struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
540                     in_addr_t nloopaddr = htonl(INADDR_LOOPBACK);
541                     if (memcmp(&sa_in->sin_addr.s_addr, &nloopaddr,
542                                                   sizeof(in_addr_t)) == 0)
543                               is_localhost = 1;
544         }
545           else if (sa->sa_family == AF_INET6) {
546                     struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
547                     if (memcmp(&sa_in6->sin6_addr.s6_addr, &in6addr_loopback,
548                                                   sizeof(struct in6_addr)) == 0)
549                               is_localhost = 1;
550           }
551 
552           /* if the request comes from localhost, or is in the accepted ops list,
553            * approve it */
554           if (is_localhost)
555                     return 0;
556           else {
557                     while (tcsd_options.remote_ops[i]) {
558                               if ((UINT32)tcsd_options.remote_ops[i] == thread_data->comm.hdr.u.ordinal) {
559                                         LogInfo("Accepted %s operation from %s",
560                                                   tcs_func_table[thread_data->comm.hdr.u.ordinal].name,
561                                                   thread_data->hostname);
562                                         return 0;
563                               }
564                               i++;
565                     }
566           }
567 
568           return 1;
569 }
570 
571 TSS_RESULT
dispatchCommand(struct tcsd_thread_data * data)572 dispatchCommand(struct tcsd_thread_data *data)
573 {
574           UINT64 offset;
575           TSS_RESULT result;
576 
577           /* First, check the ordinal bounds */
578           if (data->comm.hdr.u.ordinal >= TCSD_MAX_NUM_ORDS) {
579                     LogError("Illegal TCSD Ordinal");
580                     return TCSERR(TSS_E_FAIL);
581           }
582 
583           LogDebug("Dispatching ordinal %u (%s)", data->comm.hdr.u.ordinal,
584                      tcs_func_table[data->comm.hdr.u.ordinal].name);
585           /* We only need to check access_control if there are remote operations that are defined
586            * in the config file, which means we allow remote connections */
587           if (tcsd_options.remote_ops[0] && access_control(data)) {
588                     LogWarn("Denied %s operation from %s",
589                               tcs_func_table[data->comm.hdr.u.ordinal].name, data->hostname);
590 
591                     /* set platform header */
592                     memset(&data->comm.hdr, 0, sizeof(data->comm.hdr));
593                     data->comm.hdr.packet_size = sizeof(struct tcsd_packet_hdr);
594                     data->comm.hdr.u.result = TCSERR(TSS_E_FAIL);
595 
596                     /* set the comm buffer */
597                     memset(data->comm.buf, 0, data->comm.buf_size);
598                     offset = 0;
599                     LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf);
600                     LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf);
601 
602                     return TSS_SUCCESS;
603           }
604 
605           /* Now, dispatch */
606           if ((result = tcs_func_table[data->comm.hdr.u.ordinal].Func(data)) == TSS_SUCCESS) {
607                     /* set the comm buffer */
608                     offset = 0;
609                     LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf);
610                     LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf);
611                     LoadBlob_UINT32(&offset, data->comm.hdr.num_parms, data->comm.buf);
612                     LoadBlob_UINT32(&offset, data->comm.hdr.type_size, data->comm.buf);
613                     LoadBlob_UINT32(&offset, data->comm.hdr.type_offset, data->comm.buf);
614                     LoadBlob_UINT32(&offset, data->comm.hdr.parm_size, data->comm.buf);
615                     LoadBlob_UINT32(&offset, data->comm.hdr.parm_offset, data->comm.buf);
616           }
617 
618           return result;
619 
620 }
621 
622 TSS_RESULT
getTCSDPacket(struct tcsd_thread_data * data)623 getTCSDPacket(struct tcsd_thread_data *data)
624 {
625           if (data->comm.hdr.packet_size !=
626               (UINT32)(data->comm.hdr.parm_offset + data->comm.hdr.parm_size)) {
627                     LogError("Invalid packet received by TCSD");
628                     return TCSERR(TSS_E_INTERNAL_ERROR);
629           }
630 
631           /* dispatch the command to the TCS */
632           return dispatchCommand(data);
633 }
634