xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tcs/rpc/tcstp/rpc.c (revision 1cebe59da2b9fbff2d2acd9c253d00a9ee60e9eb)
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