Exemple #1
0
TSS_RESULT
dispatchCommand(struct tcsd_thread_data *data)
{
	UINT64 offset;
	TSS_RESULT result;

	/* First, check the ordinal bounds */
	if (data->comm.hdr.u.ordinal >= TCSD_MAX_NUM_ORDS) {
		LogError("Illegal TCSD Ordinal");
		return TCSERR(TSS_E_FAIL);
	}

	LogDebug("Dispatching ordinal %u (%s)", data->comm.hdr.u.ordinal,
		 tcs_func_table[data->comm.hdr.u.ordinal].name);
	/* We only need to check access_control if there are remote operations that are defined
	 * in the config file, which means we allow remote connections */
	if (tcsd_options.remote_ops[0] && access_control(data)) {
		LogWarn("Denied %s operation from %s",
			tcs_func_table[data->comm.hdr.u.ordinal].name, data->hostname);

		/* set platform header */
		memset(&data->comm.hdr, 0, sizeof(data->comm.hdr));
		data->comm.hdr.packet_size = sizeof(struct tcsd_packet_hdr);
		data->comm.hdr.u.result = TCSERR(TSS_E_FAIL);

		/* set the comm buffer */
		memset(data->comm.buf, 0, data->comm.buf_size);
		offset = 0;
		LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf);

		return TSS_SUCCESS;
	}

	/* Now, dispatch */
	if ((result = tcs_func_table[data->comm.hdr.u.ordinal].Func(data)) == TSS_SUCCESS) {
		/* set the comm buffer */
		offset = 0;
		LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.num_parms, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.type_size, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.type_offset, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.parm_size, data->comm.buf);
		LoadBlob_UINT32(&offset, data->comm.hdr.parm_offset, data->comm.buf);
	}

	return result;

}
Exemple #2
0
void
LoadBlob_SYMMETRIC_KEY(UINT64 *offset, BYTE *blob, TCPA_SYMMETRIC_KEY *key)
{
	LoadBlob_UINT32(offset, key->algId, blob);
	LoadBlob_UINT16(offset, key->encScheme, blob);
	LoadBlob_UINT16(offset, key->size, blob);

	if (key->size > 0) {
		LoadBlob(offset, key->size, blob, key->data);
	} else {
		key->data = NULL;
	}
}
Exemple #3
0
TSS_RESULT
TCSP_DaaJoin_internal(TCS_CONTEXT_HANDLE hContext, /* in */
		      TPM_HANDLE handle, /* in */
		      BYTE stage,               /* in */
		      UINT32 inputSize0,   /* in */
		      BYTE *inputData0,   /* in */
		      UINT32 inputSize1, /* in */
		      BYTE *inputData1, /* in */
		      TPM_AUTH * ownerAuth,	/* in, out */
		      UINT32 *outputSize, /* out */
		      BYTE **outputData)  /* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");
	if ( (result = ctx_verify_context(hContext)) != TSS_SUCCESS)
		return result;
	if( (result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)) != TSS_SUCCESS)
		goto done;

#if 0
	offset = 10;
	LoadBlob_UINT32( &offset, handle, txBlob);
	LogDebug("load BYTE: stage: %x", stage);
	LoadBlob( &offset, sizeof(BYTE), txBlob, &stage);

	LogDebug("load UNIT32: inputSize0: %x  (oldOffset=%" PRIu64 ")", inputSize0, offset);
	LoadBlob_UINT32(&offset, inputSize0, txBlob);
	LogDebug("load Data: inputData0: %X   (oldOffset=%" PRIu64 ")", (int)inputData0, offset);
	LoadBlob(&offset, inputSize0, txBlob, inputData0);
	LogDebug("load UINT32: inputSize1:%x  (oldOffset=%" PRIu64 ")", inputSize1, offset);
	LoadBlob_UINT32(&offset, inputSize1, txBlob);
	if( inputSize1>0) {
		LogDebug("load Data: inputData1: %X  (oldOffset=%" PRIu64 ")", (int)inputData1, offset);
		LoadBlob(&offset, inputSize1, txBlob, inputData1);
	}
	LogDebug("load Auth: ownerAuth: %X  (oldOffset=%" PRIu64 ")", (int)ownerAuth, offset);
	LoadBlob_Auth(&offset, txBlob, ownerAuth);

	LogDebug("load Header: ordinal: %X  (oldOffset=%" PRIu64 ")", TPM_ORD_DAA_Join, offset);
	LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_DAA_Join, txBlob);
#else
	if ((result = tpm_rqu_build(TPM_ORD_DAA_Join, &offset, txBlob, handle, stage, inputSize0,
				    inputData0, inputSize1, inputData1, ownerAuth)))
		goto done;
#endif

	LogDebug("req_mgr_submit_req  (oldOffset=%" PRIu64 ")", offset);
	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogDebug("UnloadBlob  (paramSize=%d) result=%d", paramSize, result);
	if (!result) {
#if 0
		offset = 10;
		UnloadBlob_UINT32( &offset, outputSize, txBlob);
		LogDebug("Unload outputSize=%d", *outputSize);
		*outputData = malloc(*outputSize);
		if( *outputData == NULL) {
			LogError("malloc of %u bytes failed.", *outputSize);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		LogDebug("Unload outputData");
		UnloadBlob( &offset, *outputSize, txBlob, *outputData);
		LogDebug("Unload Auth");
		UnloadBlob_Auth(&offset, txBlob, ownerAuth);
#else
		result = tpm_rsp_parse(TPM_ORD_DAA_Join, txBlob, paramSize, outputSize, outputData,
				       ownerAuth);
#endif
	}
done:
	LogDebug("Leaving DaaJoin with result:%d", result);
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}
Exemple #4
0
int
loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob)
{
	switch (data_type) {
		case TCSD_PACKET_TYPE_BYTE:
			LoadBlob_BYTE(offset, *((BYTE *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_BOOL:
			LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT16:
			LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT32:
			LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT64:
			LoadBlob_UINT64(offset, *((UINT64 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_PBYTE:
			LoadBlob(offset, data_size, blob, data);
			break;
		case TCSD_PACKET_TYPE_NONCE:
			LoadBlob(offset, sizeof(TCPA_NONCE), blob, ((TCPA_NONCE *)data)->nonce);
			break;
		case TCSD_PACKET_TYPE_DIGEST:
			LoadBlob(offset, sizeof(TCPA_DIGEST), blob, ((TCPA_DIGEST *)data)->digest);
			break;
		case TCSD_PACKET_TYPE_AUTH:
			LoadBlob_Auth_Special(offset, blob, ((TPM_AUTH *)data));
			break;
#ifdef TSS_BUILD_PS
		case TCSD_PACKET_TYPE_UUID:
			LoadBlob_UUID(offset, blob, *((TSS_UUID *)data));
			break;
		case TCSD_PACKET_TYPE_KM_KEYINFO:
			LoadBlob_KM_KEYINFO(offset, blob, ((TSS_KM_KEYINFO *)data));
			break;
		case TCSD_PACKET_TYPE_KM_KEYINFO2:
			LoadBlob_KM_KEYINFO2(offset, blob, ((TSS_KM_KEYINFO2 *)data));
			break;
		case TCSD_PACKET_TYPE_LOADKEY_INFO:
			LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data));
			break;
#endif
		case TCSD_PACKET_TYPE_ENCAUTH:
			LoadBlob(offset, sizeof(TCPA_ENCAUTH), blob,
				 ((TCPA_ENCAUTH *)data)->authdata);
			break;
		case TCSD_PACKET_TYPE_VERSION:
			LoadBlob_VERSION(offset, blob, ((TPM_VERSION *)data));
			break;
#ifdef TSS_BUILD_PCR_EVENTS
		case TCSD_PACKET_TYPE_PCR_EVENT:
			LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data));
			break;
#endif
		case TCSD_PACKET_TYPE_SECRET:
			LoadBlob(offset, sizeof(TCPA_SECRET), blob,
				 ((TCPA_SECRET *)data)->authdata);
			break;
		default:
			LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff);
			return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	return TSS_SUCCESS;
}
TSS_RESULT
TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    TSS_UUID *KeyUUID,			/* in */
			    TCS_LOADKEY_INFO * pLoadKeyInfo,	/* in, out */
			    TCS_KEY_HANDLE * phKeyTCSI)		/* out */
{
	UINT32 keyslot = 0, keySize;
	UINT32 ordinal;
	TSS_RESULT result;
	TSS_UUID parentUuid;
	BYTE keyBlob[0x1000];
	UINT16 blobSize = sizeof(keyBlob);
	UINT64 offset;
	TCS_KEY_HANDLE parentTCSKeyHandle;

	if (TPM_VERSION_IS(1,2))
		ordinal = TPM_ORD_LoadKey2;
	else
		ordinal = TPM_ORD_LoadKey;

	LogDebugFn("Enter: uuid: 0x%lx auth? 0x%x ***********", (unsigned long)KeyUUID,
		  pLoadKeyInfo == NULL ? 0xdeadbeef : pLoadKeyInfo->authData.AuthHandle);

	if ((result = ctx_verify_context(hContext)))
		return result;

	memset(&parentUuid, 0, sizeof(TSS_UUID));

	if (pLoadKeyInfo &&
	    memcmp(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID))) {
		if (ps_get_key_by_uuid(&pLoadKeyInfo->keyUUID, keyBlob, &blobSize))
			return TCSERR(TSS_E_PS_KEY_NOTFOUND);

		if (mc_get_handles_by_uuid(&pLoadKeyInfo->parentKeyUUID, &parentTCSKeyHandle,
					   &keyslot))
			return TCSERR(TCS_E_KM_LOADFAILED);

		return LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle,
					      blobSize, keyBlob,
					      &pLoadKeyInfo->authData,
					      phKeyTCSI, &keyslot);
	}

	/* if KeyUUID is already loaded, increment the ref count and return */
	if (mc_get_handles_by_uuid(KeyUUID, phKeyTCSI, &keyslot) == TSS_SUCCESS) {
		if (keyslot) {
			if (ctx_mark_key_loaded(hContext, *phKeyTCSI)) {
				LogError("Error marking key as loaded");
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
			return TSS_SUCCESS;
		}
	}
	/*********************************************************************
	 *	The first thing to do in this func is setup all the info and make sure
	 *		that we get it all from either the keyfile or the keyCache
	 *		also, it's important to return if the key is already loaded
	 ***********************************************************************/
	LogDebugFn("calling ps_get_key_by_uuid");
	if (ps_get_key_by_uuid(KeyUUID, keyBlob, &blobSize))
		return TCSERR(TSS_E_PS_KEY_NOTFOUND);
	/* convert UINT16 to UIN32 */
	keySize = blobSize;

	LogDebugFn("calling getParentUUIDByUUID");
	/*---	Get my parent's UUID.  Since My key is registered, my parent should be as well. */
	if ((result = getParentUUIDByUUID(KeyUUID, &parentUuid)))
		return TCSERR(TCS_E_KM_LOADFAILED);

	if ((result = TCSP_LoadKeyByUUID_Internal(hContext, &parentUuid,
						  pLoadKeyInfo, &parentTCSKeyHandle)))
		return result;

	LogDebugFn("calling LoadKeyByBlob_Internal");
	/*******************************************************
	 * If no errors have happend up till now, then the parent is loaded and ready for use.
	 * The parent's TCS Handle should be in parentTCSKeyHandle.
	 ******************************************************/
	if ((result = LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle,
					     keySize, keyBlob,
					     NULL,
					     phKeyTCSI, &keyslot))) {
		LogDebugFn("LoadKeyByBlob_Internal returned 0x%x", result);
		if (result == TCPA_E_AUTHFAIL && pLoadKeyInfo) {
			BYTE blob[1000];

			/* set up a load key info struct */
			memcpy(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID));
			memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, sizeof(TSS_UUID));

			/* calculate the paramDigest */
			offset = 0;
			LoadBlob_UINT32(&offset, ordinal, blob);
			LoadBlob(&offset, keySize, blob, keyBlob);
			if (Hash(TSS_HASH_SHA1, offset, blob,
				 (BYTE *)&pLoadKeyInfo->paramDigest.digest))
				result = TCSERR(TSS_E_INTERNAL_ERROR);

			result = TCSERR(TCS_E_KM_LOADFAILED);
		}
	}

	return result;
}
Exemple #6
0
void *
tcsd_thread_run(void *v)
{
	struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
	BYTE *buffer;
	int recv_size, send_size;
	TSS_RESULT result;
	UINT64 offset;
#ifndef TCSD_SINGLE_THREAD_DEBUG
	int rc;

	thread_signal_init();
#endif

	data->comm.buf_size = TCSD_INIT_TXBUF_SIZE;
	data->comm.buf = calloc(1, data->comm.buf_size);
	while (data->comm.buf) {
		/* get the packet header to get the size of the incoming packet */
		buffer = data->comm.buf;
		recv_size = sizeof(struct tcsd_packet_hdr);
		if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
			break;
		buffer += sizeof(struct tcsd_packet_hdr);       /* increment the buffer pointer */

		/* check the packet size */
		recv_size = Decode_UINT32(data->comm.buf);
		if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
			LogError("Packet to receive from socket %d is too small (%d bytes)",
					data->sock, recv_size);
			break;
		}

		if (recv_size > data->comm.buf_size ) {
			BYTE *new_buffer;

			LogDebug("Increasing communication buffer to %d bytes.", recv_size);
			new_buffer = realloc(data->comm.buf, recv_size);
			if (new_buffer == NULL) {
				LogError("realloc of %d bytes failed.", recv_size);
				break;
			}
			buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
			data->comm.buf_size = recv_size;
			data->comm.buf = new_buffer;
		}

		/* get the rest of the packet */
		recv_size -= sizeof(struct tcsd_packet_hdr);    /* already received the header */
		if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
			break;
		LogDebug("Rx'd packet");
		printf("recv data:\n");
		player_print_hex(data->comm.buf, data->comm.hdr.packet_size);
		/* create a platform version of the tcsd header */
		offset = 0;
		UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf);
		UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf);

		if ((result = getTCSDPacket(data)) != TSS_SUCCESS) {
			/* something internal to the TCSD went wrong in preparing the packet
			 * to return to the TSP.  Use our already allocated buffer to return a
			 * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
			 * these LoadBlob's are done in getTCSDPacket().
			 */
			/* set everything to zero, fill in what is non-zero */
			memset(data->comm.buf, 0, data->comm.buf_size);
			offset = 0;
			/* load packet size */
			LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), data->comm.buf);
			/* load result */
			LoadBlob_UINT32(&offset, result, data->comm.buf);
		}
		send_size = Decode_UINT32(data->comm.buf);
		LogDebug("Sending 0x%X bytes back", send_size);
		printf("send data:\n");
		player_print_hex(data->comm.buf, send_size);
		send_size = send_to_socket(data->sock, data->comm.buf, send_size);
		if (send_size < 0)
			break;

		/* check for shutdown */
		if (tm->shutdown) {
			LogDebug("Thread %ld exiting via shutdown signal!", THREAD_ID);
			break;
		}
	}

	LogDebug("Thread exiting.");

	/* Closing connection to TSP */
	close(data->sock);
	data->sock = -1;
	free(data->comm.buf);
	data->comm.buf = NULL;
	data->comm.buf_size = -1;
	/* If the connection was not shut down cleanly, free TCS resources here */
	if (data->context != NULL_TCS_HANDLE) {
		TCS_CloseContext_Internal(data->context);
		data->context = NULL_TCS_HANDLE;
	}
	if(data->hostname != NULL) {
		free(data->hostname);
		data->hostname = NULL;
	}

#ifndef TCSD_SINGLE_THREAD_DEBUG
	pthread_mutex_lock(&(tm->lock));
	tm->num_active_threads--;
	/* if we're not in shutdown mode, then nobody is waiting to join this thread, so
	 * detach it so that its resources are free at pthread_exit() time. */
	if (!tm->shutdown) {
		if ((rc = pthread_detach(*(data->thread_id)))) {
			LogError("pthread_detach failed (errno %d)."
				 " Resources may not be properly released.", rc);
		}
	}
	free(data->thread_id);
	data->thread_id = THREAD_NULL;
	pthread_mutex_unlock(&(tm->lock));
	pthread_exit(NULL);
	return NULL; /*never go into here,just for compiling ,add by xlyu*/
#else
	return NULL;
#endif
}
Exemple #7
0
void *
tcsd_thread_run(void *v)
{
	struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
	BYTE buffer[TCSD_TXBUF_SIZE];
	struct tcsd_packet_hdr *ret_buf = NULL;
	TSS_RESULT result;
	int sizeToSend, sent_total, sent;
	UINT64 offset;
#ifndef TCSD_SINGLE_THREAD_DEBUG
	int rc;

	thread_signal_init();
#endif

	if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
		LogError("Failed Receive: %s", strerror(errno));
		goto done;
	}
	LogDebug("Rx'd packet");

	data->buf = buffer;

	while (1) {
		sent_total = 0;
		if (data->buf_size > TCSD_TXBUF_SIZE) {
			LogError("Packet received from socket %d was too large (%u bytes)",
				 data->sock, data->buf_size);
			goto done;
		} else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) {
			LogError("Packet received from socket %d was too small (%u bytes)",
				 data->sock, data->buf_size);
			goto done;
		}

		if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) {
			/* something internal to the TCSD went wrong in preparing the packet
			 * to return to the TSP.  Use our already allocated buffer to return a
			 * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
			 * these LoadBlob's are done in getTCSDPacket().
			 */
			offset = 0;
			/* load result */
			LoadBlob_UINT32(&offset, result, buffer);
			/* load packet size */
			LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
			/* load num parms */
			LoadBlob_UINT16(&offset, 0, buffer);

			sizeToSend = sizeof(struct tcsd_packet_hdr);
			LogDebug("Sending 0x%X bytes back", sizeToSend);

			while (sent_total < sizeToSend) {
				if ((sent = send(data->sock,
						 &data->buf[sent_total],
						 sizeToSend - sent_total, 0)) < 0) {
					LogError("Packet send to TSP failed: send: %s. Thread exiting.",
							strerror(errno));
					goto done;
				}
				sent_total += sent;
			}
		} else {
			sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));

			LogDebug("Sending 0x%X bytes back", sizeToSend);

			while (sent_total < sizeToSend) {
				if ((sent = send(data->sock,
						 &(((BYTE *)ret_buf)[sent_total]),
						 sizeToSend - sent_total, 0)) < 0) {
					LogError("response to TSP failed: send: %s. Thread exiting.",
							strerror(errno));
					free(ret_buf);
					ret_buf = NULL;
					goto done;
				}
				sent_total += sent;
			}
			free(ret_buf);
			ret_buf = NULL;
		}

		if (tm->shutdown) {
			LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
			break;
		}

		/* receive the next packet */
		if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
			LogError("TSP has closed its connection: %s. Thread exiting.",
				 strerror(errno));
			break;
		} else if (data->buf_size == 0) {
			LogDebug("The TSP has closed the socket's connection. Thread exiting.");
			break;
		}
	}

done:
	/* Closing connection to TSP */
	close(data->sock);
	data->sock = -1;
	data->buf = NULL;
	data->buf_size = -1;
	/* If the connection was not shut down cleanly, free TCS resources here */
	if (data->context != NULL_TCS_HANDLE) {
		TCS_CloseContext_Internal(data->context);
		data->context = NULL_TCS_HANDLE;
	}

#ifndef TCSD_SINGLE_THREAD_DEBUG
	MUTEX_LOCK(tm->lock);
	tm->num_active_threads--;
	/* if we're not in shutdown mode, then nobody is waiting to join this thread, so
	 * detach it so that its resources are free at THREAD_EXIT() time. */
	if (!tm->shutdown) {
		if ((rc = THREAD_DETACH(*(data->thread_id)))) {
			LogError("Thread detach failed (errno %d)."
				 " Resources may not be properly released.", rc);
		}
	}
	free(data->hostname);
	data->hostname = NULL;
	data->thread_id = THREAD_NULL;
	MUTEX_UNLOCK(tm->lock);
	THREAD_EXIT(NULL);
#else
	return NULL;
#endif
}