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; }
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; } }
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, ¶mSize); 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; }
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; }
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 }
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 }