Home | History | Annotate | Line # | Download | only in tcstp
      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
     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
     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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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