int blob_pubkey(char *out, unsigned int olen, char *in, unsigned int ilen, char *p, unsigned int psize) { unsigned int offset, size; if (olen < ilen) { printf("\t\tblob_pubkey failed: olen < ilen\n"); return; } if (psize == 0) { printf("\t\tblob_pubkey failed: psize == 0\n"); return; } memcpy(out, in, ilen); /* Keep all the keyparms the same, overwrite the public key at end. * Check sizes to make sure we get the right offset. They are * big-endian. */ offset = 4 + 2 + 2; /* Key parms length */ size = Decode_UINT32(in + offset); offset += 4; offset += size; /* Key length */ UINT32ToArray(psize, out + offset); offset += 4; /* out + offset should now be pointing to the public key */ memcpy(out + offset, p, psize); offset += psize; return offset; }
UINT16 get_num_pcrs(TSS_HCONTEXT tspContext) { TSS_RESULT result; static UINT16 ret = 0; UINT32 subCap; UINT32 respSize; BYTE *resp; if (ret != 0) return ret; subCap = endian32(TPM_CAP_PROP_PCR); if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, TPM_CAP_PROPERTY, sizeof(UINT32), (BYTE *)&subCap, &respSize, &resp))) { if ((resp = (BYTE *)getenv("TSS_DEFAULT_NUM_PCRS")) == NULL) return TSS_DEFAULT_NUM_PCRS; /* don't set ret here, next time we may be connected */ return atoi((char *)resp); } ret = (UINT16)Decode_UINT32(resp); free(resp); return ret; }
TSS_RESULT obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore, UINT32 * permission) { BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE] = {0}; UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; UINT32 offset; UINT16 pcrread_sizeOfSelect; UINT16 pcrwrite_sizeOfSelect; TPM_NV_ATTRIBUTES nv_attributes_value; TSS_HCONTEXT tspContext; TSS_RESULT result; if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) return result; if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) return result; offset = 0; offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION) + sizeof(TPM_COMPOSITE_HASH); pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION) + sizeof(TPM_COMPOSITE_HASH); nv_attributes_value.attributes = Decode_UINT32(nv_data_public + offset + sizeof(TPM_STRUCTURE_TAG)); *permission = nv_attributes_value.attributes; return result; }
int json_2_struct_write_elem(void * node,void * addr,TEMPLATE_ELEM * elem_template) { JSON_NODE * json_node = (JSON_NODE *)node; struct struct_elem_attr * elem_attr; BYTE * buf; int retval; int int_value; unsigned char char_value; UINT16 short_value; long long long_long_value; int i,j; BYTE * data; V_String * vstring; TEMPLATE_ELEM * elem_define; int define_value; retval=0; elem_attr=elem_template->elem_desc; switch(elem_attr->type) { case OS210_TYPE_STRING : if(json_node->elem_type!=JSON_ELEM_STRING) return -EINVAL; retval=elem_attr->size; memset(addr,0,retval); strncpy(addr,json_node->value_str,retval); break; case OS210_TYPE_INT : retval=sizeof(int); if(json_node->elem_type!=JSON_ELEM_NUM) return -EINVAL; int_value=atoi(json_node->value_str); memcpy(addr,&int_value,retval); break; case OS210_TYPE_ENUM : retval=sizeof(int); if(json_node->elem_type == JSON_ELEM_NUM) { int_value=atoi(json_node->value_str); memcpy(addr,&int_value,retval); } else if(json_node->elem_type ==JSON_ELEM_STRING) { if(!strcmp(nulstring,json_node->value_str)) { int_value=0; } else { NAME2VALUE * EnumList; if((elem_template->elem_var != NULL) && !IS_ERR(elem_template->elem_var)) EnumList=elem_template->elem_var; else EnumList=elem_template->elem_desc->attr; if((EnumList==NULL)||IS_ERR(EnumList)) return -EINVAL; char * string=json_node->value_str; for(i=0;EnumList[i].name!=NULL;i++) { if(!strcmp(EnumList[i].name,string)) { int_value=EnumList[i].value; memcpy(addr,&int_value,retval); break; } } if(EnumList[i].name==NULL) return -EINVAL; } } else return -EINVAL; break; case OS210_TYPE_FLAG : retval=sizeof(int); if(json_node->elem_type == JSON_ELEM_NUM) { int_value=atoi(json_node->value_str); memcpy(addr,&int_value,retval); } else if(json_node->elem_type ==JSON_ELEM_STRING) { if(!strcmp(nulstring,json_node->value_str)) { int_value=0; } else { NAME2VALUE * FlagList; if((elem_template->elem_var != NULL) && !IS_ERR(elem_template->elem_var)) FlagList=elem_template->elem_var; else FlagList=elem_template->elem_desc->attr; if((FlagList==NULL)||IS_ERR(FlagList)) return -EINVAL; int_value=0; char temp_string[256]; int stroffset=0; char * string=json_node->value_str; for(i=0;string[i]==' ';i++); if(string[i]==0) return 0; for(;i<strlen(string);i++) { // duplicate one flag bit string temp_string[stroffset++]=string[i]; if((string[i+1]!='|') && (string[i+1]!=0)) continue; i++; for(;string[i]==' ';i++) { if(string[i]==0) break; } temp_string[stroffset]=0; stroffset=0; // find the flag's value for(j=0;FlagList[j].name!=NULL;j++) { if(strcmp(FlagList[j].name,temp_string)) continue; int_value|=FlagList[j].value; break; } if(FlagList[j].name==NULL) return -EINVAL; } memcpy(addr,&int_value,retval); } } else return -EINVAL; break; case TPM_TYPE_UINT32 : retval=sizeof(int); if(json_node->elem_type == JSON_ELEM_NUM) { int_value=atoi(json_node->value_str); *(int *)addr=Decode_UINT32(&int_value); } else return -EINVAL; break; case OS210_TYPE_TIME : retval=sizeof(time_t); // memcpy(addr,elem_data,retval); break; case OS210_TYPE_UCHAR : retval=sizeof(unsigned char); memcpy(addr,json_node->value_str,retval); break; case OS210_TYPE_USHORT : retval=sizeof(unsigned short); if(json_node->elem_type == JSON_ELEM_NUM) { short_value=atoi(json_node->value_str); memcpy(addr,&short_value,retval); } else return -EINVAL; break; case TPM_TYPE_UINT16 : retval=sizeof(UINT16); if(json_node->elem_type == JSON_ELEM_NUM) { short_value=atoi(json_node->value_str); *(UINT16 *)addr=Decode_UINT16(&short_value); } else return -EINVAL; break; case OS210_TYPE_LONGLONG: retval=sizeof(long long); if(json_node->elem_type == JSON_ELEM_NUM) { long_long_value=atoi(json_node->value_str); memcpy(addr,&long_long_value,retval); } else return -EINVAL; break; case TPM_TYPE_UINT64 : retval=sizeof(UINT64); if(json_node->elem_type == JSON_ELEM_NUM) { long_long_value=atoi(json_node->value_str); *(UINT64 *)addr=Decode_UINT64(&long_long_value); } else return -EINVAL; break; case OS210_TYPE_BINDATA: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; retval=elem_attr->size; radix64_to_bin(addr,bin_to_radix64_len(retval),json_node->value_str); break; case OS210_TYPE_BITMAP: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; { char * tempstring; BYTE * tempbuf; retval=elem_attr->size; tempbuf=(BYTE * )addr; tempstring=json_node->value_str; for(i=0;i<retval;i++) { tempbuf[i]=0; while(*tempstring==' ') tempstring++; for(j=0;j<8;j++) { if((*tempstring!= '0') &&(*tempstring!='1')) return -EINVAL; tempbuf[i]=tempbuf[i]<<1+(*tempstring-'0'); tempstring++; } } } break; case OS210_TYPE_HEXDATA: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; { char * tempstring; BYTE * tempbuf; retval=elem_attr->size; tempbuf=(BYTE * )addr; tempstring=json_node->value_str; for(i=0;i<retval;i++) { tempbuf[i]=0; while(*tempstring==' ') tempstring++; for(j=0;j<2;j++) { if((*tempstring>='0') &&(*tempstring<='9')) { tempbuf[i]=tempbuf[i]*0x10+(*tempstring-'0'); } else if((*tempstring>='A') &&(*tempstring<='F')) { tempbuf[i]=tempbuf[i]*0x10+(*tempstring-'A'+9); } else if((*tempstring>='a') &&(*tempstring<='f')) { tempbuf[i]=tempbuf[i]*0x10+(*tempstring-'a'+9); } else return -EINVAL; tempstring++; } } } break; case OS210_TYPE_BINARRAY: if(json_node->elem_type != JSON_ELEM_ARRAY) return -EINVAL; { retval=elem_attr->size*(int)(elem_attr->attr); memset(addr,0,retval); JSON_VALUE * curr_value; for(i=0;i<(int)(elem_attr->attr);i++) { if(i==0) curr_value=get_first_json_child(json_node); else curr_value=get_next_json_child(json_node); if(curr_value==NULL) break; if(curr_value->value_type!=JSON_ELEM_STRING) return -EINVAL; radix64_to_bin(addr+i*elem_attr->size,bin_to_radix64_len(elem_attr->size),json_node->value_str); } } break; case OS210_TYPE_VSTRING: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; int_value=strlen(json_node->value_str); vstring = (V_String *)addr; vstring->length=int_value; if((vstring->length <0) || vstring->length> OS210_MAX_BUF) { retval=-EINVAL; } vstring->String=kmalloc(vstring->length,GFP_KERNEL); if(vstring->String==NULL) return -ENOMEM; memcpy(vstring->String,json_node->value_str,vstring->length); retval=sizeof(V_String); break; case OS210_TYPE_ESTRING: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; { char * estring; retval=strlen(json_node->value_str); if(retval<0) retval=-EINVAL; if((elem_attr->size!=0) && (retval>elem_attr->size)) retval=-EINVAL; retval++; estring=kmalloc(retval,GFP_KERNEL); if(estring==NULL) return -ENOMEM; memcpy(estring,json_node->value_str,retval); *(char **)addr=estring; retval=sizeof(char *); } break; case OS210_TYPE_DEFINE: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; elem_define=(TEMPLATE_ELEM *)(elem_template->elem_var); retval=elem_attr->size*(*(int*)(elem_define->elem_var)); if(retval!=radix64_to_bin(addr,strlen(json_node->value_str),json_node->value_str)) return -EINVAL; break; case OS210_TYPE_DEFSTR: if(json_node->elem_type != JSON_ELEM_STRING) return -EINVAL; elem_define=(TEMPLATE_ELEM *)(elem_template->elem_var); retval=elem_attr->size*(*(int*)(elem_define->elem_var)); { char * estring; retval++; estring=kmalloc(retval,GFP_KERNEL); if(estring==NULL) return -ENOMEM; memcpy(estring,json_node->value_str,retval); *(char **)addr=estring; } retval=sizeof(char *); break; case OS210_TYPE_DEFSTRARRAY: if(json_node->elem_type != JSON_ELEM_ARRAY) return -EINVAL; elem_define=(TEMPLATE_ELEM *)(elem_template->elem_var); define_value=*(int *)elem_define->elem_var; if(define_value<0) return -EINVAL; if(define_value>32768) return -EINVAL; retval=elem_attr->size*define_value; { char * estring; estring=kmalloc(retval,GFP_KERNEL); if(estring==NULL) return -ENOMEM; memset(estring,0,retval); JSON_NODE * curr_node; // JSON_VALUE * curr_value; for(i=0;i<define_value;i++) { if(i==0) curr_node=get_first_json_child(json_node); else curr_node=get_next_json_child(json_node); if(curr_node==NULL) break; if(curr_node->elem_type!=JSON_ELEM_STRING) return -EINVAL; // radix64_to_bin(addr+i*elem_attr->size,bin_to_radix64_len(elem_attr->size),json_node->value_str); strncpy(estring+i*elem_attr->size,curr_node->value_str,elem_attr->size); } *(char **)addr=estring; } break; case OS210_TYPE_ORGCHAIN: retval= 0; // retval = os210_struct_size_sum(elem_attr->attr); break; case OS210_TYPE_NODATA: default: break; } return retval; }
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 }
TSS_RESULT obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public) { struct tsp_object *obj; TSS_HCONTEXT hContext; TSS_HTPM hTpm; TSS_RESULT result; struct tr_nvstore_obj *nvstore; UINT32 uiResultLen; BYTE *pResult; UINT32 i; TPM_BOOL defined_index = FALSE; if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); hContext = obj->tspContext; nvstore = (struct tr_nvstore_obj *)obj->data; if ((result = obj_tpm_get(hContext, &hTpm))) goto out; if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, NULL, &uiResultLen, &pResult))) { goto out; } for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { defined_index = TRUE; break; } } free_tspi(hContext, pResult); if (!defined_index) { result = TSPERR(TPM_E_BADINDEX); goto out; } if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX, sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)), &uiResultLen, &pResult))) { LogDebug("get the index capability error"); goto out; } if (uiResultLen > *size) { free_tspi(hContext, pResult); result = TSPERR(TSS_E_INTERNAL_ERROR); goto out; } *size = uiResultLen; memcpy(nv_data_public, pResult, uiResultLen); free_tspi(hContext, pResult); out: obj_list_put(&nvstore_list); return result; }