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