Home | History | Annotate | Line # | Download | only in tspi
      1 /*
      2  * The Initial Developer of the Original Code is Intel Corporation.
      3  * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation.
      4  * All Rights Reserved.
      5  *
      6  * trousers - An open source TCG Software Stack
      7  *
      8  * Author: james.xu (at) intel.com Rossey.liu (at) intel.com
      9  *
     10  */
     11 
     12 #include <stdlib.h>
     13 #include <stdio.h>
     14 #include <errno.h>
     15 #include <string.h>
     16 
     17 #include "trousers/tss.h"
     18 #include "trousers/trousers.h"
     19 #include "trousers_types.h"
     20 #include "spi_utils.h"
     21 #include "capabilities.h"
     22 #include "tsplog.h"
     23 #include "obj.h"
     24 
     25 TSS_RESULT
     26 obj_nvstore_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject)
     27 {
     28 	TSS_RESULT result;
     29 	struct tr_nvstore_obj *nvstore = calloc(1, sizeof(struct tr_nvstore_obj));
     30 
     31 	if (nvstore == NULL) {
     32 		LogError("malloc of %zd bytes failed.",
     33 				sizeof(struct tr_nvstore_obj));
     34 		return TSPERR(TSS_E_OUTOFMEMORY);
     35 	}
     36 
     37 	if ((result = obj_list_add(&nvstore_list, tspContext, 0, nvstore, phObject))) {
     38 		free(nvstore);
     39 		return result;
     40 	}
     41 
     42 	return TSS_SUCCESS;
     43 }
     44 
     45 TSS_BOOL
     46 obj_is_nvstore(TSS_HOBJECT hObject)
     47 {
     48 	TSS_BOOL answer = FALSE;
     49 
     50 	if ((obj_list_get_obj(&nvstore_list, hObject))) {
     51 		answer = TRUE;
     52 		obj_list_put(&nvstore_list);
     53 	}
     54 
     55 	return answer;
     56 }
     57 
     58 void
     59 nvstore_free(void *data)
     60 {
     61 	struct tr_nvstore_obj *nvstore = (struct tr_nvstore_obj *)data;
     62 
     63 	free(nvstore);
     64 }
     65 
     66 TSS_RESULT
     67 obj_nvstore_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
     68 {
     69 	TSS_RESULT result;
     70 
     71 	if ((result = obj_list_remove(&nvstore_list, &nvstore_free, hObject, tspContext)))
     72 		return result;
     73 
     74 	return TSS_SUCCESS;
     75 }
     76 
     77 TSS_RESULT
     78 obj_nvstore_get_tsp_context(TSS_HNVSTORE hNvstore, TSS_HCONTEXT * tspContext)
     79 {
     80 	struct tsp_object *obj;
     81 
     82 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
     83 		return TSPERR(TSS_E_INVALID_HANDLE);
     84 
     85 	*tspContext = obj->tspContext;
     86 
     87 	obj_list_put(&nvstore_list);
     88 
     89 	return TSS_SUCCESS;
     90 }
     91 
     92 TSS_RESULT
     93 obj_nvstore_set_index(TSS_HNVSTORE hNvstore, UINT32 index)
     94 {
     95 	struct tsp_object *obj;
     96 	struct tr_nvstore_obj *nvstore;
     97 	TSS_RESULT result=TSS_SUCCESS;
     98 
     99 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    100 		return TSPERR(TSS_E_INVALID_HANDLE);
    101 
    102 	nvstore = (struct tr_nvstore_obj *)obj->data;
    103 
    104 	nvstore->nvIndex = index;
    105 
    106 	obj_list_put(&nvstore_list);
    107 
    108 	return result;
    109 }
    110 
    111 TSS_RESULT
    112 obj_nvstore_get_index(TSS_HNVSTORE hNvstore, UINT32 * index)
    113 {
    114 	struct tsp_object *obj;
    115 	struct tr_nvstore_obj *nvstore;
    116 	TSS_RESULT result=TSS_SUCCESS;
    117 
    118 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    119 		return TSPERR(TSS_E_INVALID_HANDLE);
    120 
    121 	nvstore = (struct tr_nvstore_obj *)obj->data;
    122 
    123 	*index = nvstore->nvIndex;
    124 
    125 	obj_list_put(&nvstore_list);
    126 
    127 	return result;
    128 }
    129 
    130 TSS_RESULT
    131 obj_nvstore_set_datasize(TSS_HNVSTORE hNvstore, UINT32 datasize)
    132 {
    133 	struct tsp_object *obj;
    134 	struct tr_nvstore_obj *nvstore;
    135 	TSS_RESULT result=TSS_SUCCESS;
    136 
    137 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    138 		return TSPERR(TSS_E_INVALID_HANDLE);
    139 
    140 	nvstore = (struct tr_nvstore_obj *)obj->data;
    141 
    142 	nvstore->dataSize= datasize;
    143 
    144 	obj_list_put(&nvstore_list);
    145 
    146 	return result;
    147 }
    148 
    149 TSS_RESULT
    150 obj_nvstore_get_datasize(TSS_HNVSTORE hNvstore, UINT32 * datasize)
    151 {
    152 	struct tsp_object *obj;
    153 	struct tr_nvstore_obj *nvstore;
    154 	TSS_RESULT result=TSS_SUCCESS;
    155 
    156 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    157 		return TSPERR(TSS_E_INVALID_HANDLE);
    158 
    159 	nvstore = (struct tr_nvstore_obj *)obj->data;
    160 
    161 	*datasize = nvstore->dataSize;
    162 
    163 	obj_list_put(&nvstore_list);
    164 
    165 	return result;
    166 }
    167 
    168 TSS_RESULT
    169 obj_nvstore_set_permission(TSS_HNVSTORE hNvstore, UINT32 permission)
    170 {
    171 	struct tsp_object *obj;
    172 	struct tr_nvstore_obj *nvstore;
    173 	TSS_RESULT result=TSS_SUCCESS;
    174 
    175 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    176 		return TSPERR(TSS_E_INVALID_HANDLE);
    177 
    178 	nvstore = (struct tr_nvstore_obj *)obj->data;
    179 
    180 	nvstore->permission.attributes= permission;
    181 
    182 	obj_list_put(&nvstore_list);
    183 
    184 	return result;
    185 }
    186 
    187 TSS_RESULT
    188 obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore, UINT32 * permission)
    189 {
    190 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE] = {0};
    191 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    192 	UINT32 offset;
    193 	UINT16 pcrread_sizeOfSelect;
    194 	UINT16 pcrwrite_sizeOfSelect;
    195 	TPM_NV_ATTRIBUTES nv_attributes_value;
    196 	TSS_HCONTEXT tspContext;
    197 	TSS_RESULT result;
    198 
    199 	if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    200 		return result;
    201 
    202 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
    203 		return result;
    204 
    205 	offset = 0;
    206 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    207 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    208 
    209 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    210 			+ sizeof(TPM_LOCALITY_SELECTION)
    211 			+ sizeof(TPM_COMPOSITE_HASH);
    212 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    213 
    214 	offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
    215 			+ sizeof(TPM_LOCALITY_SELECTION)
    216 			+ sizeof(TPM_COMPOSITE_HASH);
    217 
    218 	nv_attributes_value.attributes = Decode_UINT32(nv_data_public
    219 						       + offset + sizeof(TPM_STRUCTURE_TAG));
    220 	*permission = nv_attributes_value.attributes;
    221 
    222 	return result;
    223 }
    224 
    225 TSS_RESULT
    226 obj_nvstore_get_permission(TSS_HNVSTORE hNvstore, UINT32 * permission)
    227 {
    228 	struct tsp_object *obj;
    229 	struct tr_nvstore_obj *nvstore;
    230 	TSS_RESULT result=TSS_SUCCESS;
    231 
    232 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    233 		return TSPERR(TSS_E_INVALID_HANDLE);
    234 
    235 	nvstore = (struct tr_nvstore_obj *)obj->data;
    236 
    237 	*permission = nvstore->permission.attributes;
    238 
    239 	obj_list_put(&nvstore_list);
    240 
    241 	return result;
    242 }
    243 
    244 TSS_RESULT
    245 obj_nvstore_set_policy(TSS_HNVSTORE hNvstore, TSS_HPOLICY hPolicy)
    246 {
    247 	struct tsp_object *obj;
    248 	struct tr_nvstore_obj *nvstore;
    249 	UINT32 policyType;
    250 	TSS_RESULT result = TSS_SUCCESS;
    251 
    252 	if ((result = obj_policy_get_type(hPolicy, &policyType)))
    253 		return result;
    254 
    255 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    256 		return TSPERR(TSS_E_INVALID_HANDLE);
    257 
    258 	nvstore = (struct tr_nvstore_obj *)obj->data;
    259 
    260 	switch (policyType) {
    261 		case TSS_POLICY_USAGE:
    262 			nvstore->policy = hPolicy;
    263 			break;
    264 		default:
    265 			result = TSPERR(TSS_E_BAD_PARAMETER);
    266 	}
    267 
    268 	obj_list_put(&nvstore_list);
    269 
    270 	return result;
    271 }
    272 
    273 TSS_RESULT
    274 obj_nvstore_get_policy(TSS_HNVSTORE hNvstore, UINT32 policyType, TSS_HPOLICY *phPolicy)
    275 {
    276 	struct tsp_object *obj;
    277 	struct tr_nvstore_obj *nvstore;
    278 	TSS_RESULT result=TSS_SUCCESS;
    279 
    280 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    281 		return TSPERR(TSS_E_INVALID_HANDLE);
    282 
    283 	nvstore = (struct tr_nvstore_obj *)obj->data;
    284 
    285 	switch (policyType) {
    286 		case TSS_POLICY_USAGE:
    287 			*phPolicy = nvstore->policy;
    288 			break;
    289 		default:
    290 			result = TSPERR(TSS_E_BAD_PARAMETER);
    291 	}
    292 
    293 	obj_list_put(&nvstore_list);
    294 
    295 	return result;
    296 }
    297 
    298 TSS_RESULT
    299 obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public)
    300 {
    301 	struct tsp_object *obj;
    302 	TSS_HCONTEXT  hContext;
    303 	TSS_HTPM hTpm;
    304 	TSS_RESULT result;
    305 	struct tr_nvstore_obj *nvstore;
    306 	UINT32 uiResultLen;
    307 	BYTE *pResult;
    308 	UINT32 i;
    309 	TPM_BOOL defined_index = FALSE;
    310 
    311 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    312 		return TSPERR(TSS_E_INVALID_HANDLE);
    313 
    314 	hContext = obj->tspContext;
    315 	nvstore = (struct tr_nvstore_obj *)obj->data;
    316 
    317 	if ((result = obj_tpm_get(hContext, &hTpm)))
    318 		goto out;
    319 
    320 	if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
    321 				 NULL, &uiResultLen, &pResult))) {
    322 		goto out;
    323 	}
    324 
    325 	for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
    326 		if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
    327 			defined_index = TRUE;
    328 			break;
    329 		}
    330 	}
    331 
    332 	free_tspi(hContext, pResult);
    333 
    334 	if (!defined_index) {
    335 		result = TSPERR(TPM_E_BADINDEX);
    336 		goto out;
    337 	}
    338 
    339 	if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX,
    340 					     sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)),
    341 					     &uiResultLen, &pResult))) {
    342 		LogDebug("get the index capability error");
    343 		goto out;
    344 	}
    345 
    346 	if (uiResultLen > *size) {
    347 		free_tspi(hContext, pResult);
    348 		result = TSPERR(TSS_E_INTERNAL_ERROR);
    349 		goto out;
    350 	}
    351 	*size = uiResultLen;
    352 	memcpy(nv_data_public, pResult, uiResultLen);
    353 	free_tspi(hContext, pResult);
    354 
    355 out:
    356 	obj_list_put(&nvstore_list);
    357 	return result;
    358 }
    359 
    360 TSS_RESULT
    361 obj_nvstore_get_readdigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
    362 {
    363 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    364 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    365 	UINT32 offset;
    366 	UINT16 pcrread_sizeOfSelect;
    367 	TSS_HCONTEXT tspContext;
    368 	TSS_RESULT result;
    369 
    370 	if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    371 		return result;
    372 
    373 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
    374 		return result;
    375 
    376 	*size = sizeof(TPM_COMPOSITE_HASH);
    377 	*data = calloc_tspi(tspContext, *size);
    378 	if (*data == NULL) {
    379 		LogError("malloc of %u bytes failed.", *size);
    380 		result = TSPERR(TSS_E_OUTOFMEMORY);
    381 		return result;
    382 	}
    383 
    384 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    385 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    386 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION);
    387 	memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH));
    388 
    389 	return result;
    390 }
    391 
    392 TSS_RESULT
    393 obj_nvstore_get_readpcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
    394 {
    395 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    396 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    397 	UINT32 offset;
    398 	UINT16 pcrread_sizeOfSelect;
    399 	TSS_HCONTEXT tspContext;
    400 	TSS_RESULT result;
    401 
    402 	if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    403 		return result;
    404 
    405 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
    406 		return result;
    407 
    408 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    409 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    410 
    411 	*size = sizeof(UINT16) + pcrread_sizeOfSelect;
    412 	*data = calloc_tspi(tspContext, *size);
    413 	if (*data == NULL) {
    414 		LogError("malloc of %u bytes failed.", *size);
    415 		result = TSPERR(TSS_E_OUTOFMEMORY);
    416 		return result;
    417 	}
    418 
    419 	memcpy(*data, nv_data_public + offset, *size);
    420 
    421 	return result;
    422 }
    423 
    424 TSS_RESULT
    425 obj_nvstore_get_writedigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
    426 {
    427 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    428 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    429 	UINT32 offset;
    430 	UINT16 pcrread_sizeOfSelect;
    431 	TSS_HCONTEXT tspContext;
    432 	TSS_RESULT result;
    433 
    434 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    435 		return result;
    436 
    437 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
    438 		return result;
    439 
    440 	*size = sizeof(TPM_COMPOSITE_HASH);
    441 	*data = calloc_tspi(tspContext, *size);
    442 	if (*data == NULL) {
    443 		LogError("malloc of %u bytes failed.", *size);
    444 		result = TSPERR(TSS_E_OUTOFMEMORY);
    445 		return result;
    446 	}
    447 
    448 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    449 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    450 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    451 			+ sizeof(TPM_LOCALITY_SELECTION)
    452 			+ sizeof(TPM_COMPOSITE_HASH);
    453 
    454 	Decode_UINT16(nv_data_public + offset);
    455 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION);
    456 	memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH));
    457 
    458 	return result;
    459 }
    460 
    461 TSS_RESULT
    462 obj_nvstore_get_writepcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
    463 {
    464 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    465 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    466 	UINT32 offset;
    467 	UINT16 pcrread_sizeOfSelect;
    468 	UINT16 pcrwrite_sizeOfSelect;
    469 	TSS_HCONTEXT tspContext;
    470 	TSS_RESULT result;
    471 
    472 	if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    473 		return result;
    474 
    475 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
    476 		return result;
    477 
    478 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    479 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    480 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    481 			+ sizeof(TPM_LOCALITY_SELECTION)
    482 			+ sizeof(TPM_COMPOSITE_HASH);
    483 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    484 
    485 	*size = sizeof(UINT16) + pcrwrite_sizeOfSelect;
    486 	*data = calloc_tspi(tspContext, *size);
    487 	if (*data == NULL) {
    488 		LogError("malloc of %u bytes failed.", *size);
    489 		result = TSPERR(TSS_E_OUTOFMEMORY);
    490 		return result;
    491 	}
    492 
    493 	memcpy(*data, nv_data_public + offset, *size);
    494 	return result;
    495 }
    496 
    497 TSS_RESULT
    498 obj_nvstore_get_state_readstclear(TSS_HNVSTORE hNvstore, UINT32 * readstclear)
    499 {
    500 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    501 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    502 	UINT32 offset;
    503 	UINT16 pcrread_sizeOfSelect;
    504 	UINT16 pcrwrite_sizeOfSelect;
    505 	TPM_BOOL value;
    506 	TSS_RESULT result;
    507 
    508 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    509 		return result;
    510 
    511 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    512 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    513 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    514 			+ sizeof(TPM_LOCALITY_SELECTION)
    515 			+ sizeof(TPM_COMPOSITE_HASH);
    516 
    517 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    518 	offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
    519 			+ sizeof(TPM_LOCALITY_SELECTION)
    520 			+ sizeof(TPM_COMPOSITE_HASH)
    521 			+ sizeof(TPM_NV_ATTRIBUTES);
    522 
    523 	value = *((TPM_BOOL *)(nv_data_public + offset));
    524 
    525 	*readstclear = value;
    526 
    527 	return result;
    528 }
    529 
    530 TSS_RESULT
    531 obj_nvstore_get_state_writedefine(TSS_HNVSTORE hNvstore, UINT32 * writedefine)
    532 {
    533 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    534 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    535 	UINT32 offset;
    536 	UINT16 pcrread_sizeOfSelect;
    537 	UINT16 pcrwrite_sizeOfSelect;
    538 	TPM_BOOL value;
    539 	TSS_RESULT result;
    540 
    541 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    542 		return result;
    543 
    544 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    545 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    546 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    547 			+ sizeof(TPM_LOCALITY_SELECTION)
    548 			+ sizeof(TPM_COMPOSITE_HASH);
    549 
    550 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    551 	offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
    552 			+ sizeof(TPM_LOCALITY_SELECTION)
    553 			+ sizeof(TPM_COMPOSITE_HASH)
    554 			+ sizeof(TPM_NV_ATTRIBUTES)
    555 			+ sizeof(TPM_BOOL)
    556 			+ sizeof(TPM_BOOL);
    557 
    558 	value = *((TPM_BOOL *)(nv_data_public + offset));
    559 
    560 	*writedefine = value;
    561 
    562 	return result;
    563 }
    564 
    565 TSS_RESULT
    566 obj_nvstore_get_state_writestclear(TSS_HNVSTORE hNvstore, UINT32 * writestclear)
    567 {
    568 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    569 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    570 	UINT32 offset;
    571 	UINT16 pcrread_sizeOfSelect;
    572 	UINT16 pcrwrite_sizeOfSelect;
    573 	TPM_BOOL value;
    574 	TSS_RESULT result;
    575 
    576 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    577 		return result;
    578 
    579 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    580 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    581 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    582 			+ sizeof(TPM_LOCALITY_SELECTION)
    583 			+ sizeof(TPM_COMPOSITE_HASH);
    584 
    585 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    586 	offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
    587 			+ sizeof(TPM_LOCALITY_SELECTION)
    588 			+ sizeof(TPM_COMPOSITE_HASH)
    589 			+ sizeof(TPM_NV_ATTRIBUTES)
    590 			+ sizeof(TPM_BOOL);
    591 
    592 	value = *((TPM_BOOL *)(nv_data_public + offset));
    593 	*writestclear = value;
    594 
    595 	return result;
    596 }
    597 
    598 TSS_RESULT
    599 obj_nvstore_get_readlocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * readlocalityatrelease)
    600 {
    601 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    602 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    603 	UINT32 offset;
    604 	UINT16 pcrread_sizeOfSelect;
    605 	TPM_LOCALITY_SELECTION locality_value;
    606 	TSS_RESULT result;
    607 
    608 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    609 		return result;
    610 
    611 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    612 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    613 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect;
    614 	locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset));
    615 	*readlocalityatrelease = locality_value;
    616 
    617 	return result;
    618 }
    619 
    620 TSS_RESULT
    621 obj_nvstore_get_writelocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * writelocalityatrelease)
    622 {
    623 	BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
    624 	UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
    625 	UINT32 offset;
    626 	UINT16 pcrread_sizeOfSelect;
    627 	UINT16 pcrwrite_sizeOfSelect;
    628 	TPM_LOCALITY_SELECTION locality_value;
    629 	TSS_RESULT result;
    630 
    631 	if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
    632 		return result;
    633 
    634 	offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
    635 	pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    636 	offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
    637 			+ sizeof(TPM_LOCALITY_SELECTION)
    638 			+ sizeof(TPM_COMPOSITE_HASH);
    639 	pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
    640 	offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect;
    641 
    642 	locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset));
    643 	*writelocalityatrelease = locality_value;
    644 
    645 	return result;
    646 }
    647 
    648 TSS_RESULT
    649 obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore,
    650 				TSS_HPCRS hPcrComposite,
    651 				UINT32 *size,
    652 				BYTE **data)
    653 {
    654 	struct tsp_object *obj;
    655 	BYTE pdata[MAX_PUBLIC_DATA_SIZE];
    656 	UINT32 dataLen;
    657 	UINT64 offset;
    658 	TSS_HCONTEXT tspContext;
    659 	TSS_RESULT result = TSS_SUCCESS;
    660 	BYTE*  ppbHashData;
    661 	UINT32 i;
    662 	BYTE  digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, };
    663 	UINT32 tmp_locAtRelease;
    664 	TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE
    665 					| TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR;
    666 	BYTE tmp_pcr_select[3] = {0, 0, 0};
    667 	TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select};
    668 
    669 	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
    670 		return TSPERR(TSS_E_INVALID_HANDLE);
    671 
    672 	tspContext = obj->tspContext;
    673 
    674 	if (hPcrComposite) {
    675 		if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) {
    676 			LogDebug("get_selection error from hReadPcrComposite");
    677 			goto out;
    678 		}
    679 
    680 		/* the index should not >= 24, so the sizeofselect should not be >3*/
    681 		if (dataLen - sizeof(UINT16) > 3) {
    682 			result = TSPERR(TSS_E_BAD_PARAMETER);
    683 			goto out;
    684 		}
    685 		offset = 0;
    686 		Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect);
    687 
    688 		if (pcrSelect.sizeOfSelect != 0) {
    689 			if ((result = obj_pcrs_get_digest_at_release(hPcrComposite,
    690 								     &dataLen, &ppbHashData))) {
    691 				LogDebug("get_composite error from hReadPcrComposite");
    692 				goto out;
    693 			}
    694 			memcpy(digAtRelease, ppbHashData, dataLen);
    695 			free_tspi(tspContext, ppbHashData);
    696 		} else {
    697 			pcrSelect.sizeOfSelect = 3;
    698 			pcrSelect.pcrSelect = tmp_pcr_select;
    699 		}
    700 
    701 		if (pcrSelect.sizeOfSelect < 3) {
    702 			for (i = 0; i < pcrSelect.sizeOfSelect; i++) {
    703 				tmp_pcr_select[i] = pcrSelect.pcrSelect[i];
    704 			}
    705 			pcrSelect.sizeOfSelect = 3;
    706 			pcrSelect.pcrSelect = tmp_pcr_select;
    707 		}
    708 
    709 		if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease)))
    710 			goto out;
    711 		locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK);
    712 	}
    713 
    714 	*size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN;
    715 	*data = calloc_tspi(tspContext, *size);
    716 	if (*data == NULL) {
    717 		LogError("malloc of %u bytes failed.", *size);
    718 		result = TSPERR(TSS_E_OUTOFMEMORY);
    719 		goto out;
    720 	}
    721 
    722 	offset = 0;
    723 	Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect);
    724 	Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data);
    725 	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease);
    726 
    727 out:
    728 	obj_list_put(&nvstore_list);
    729 	return result;
    730 }
    731 
    732 
    733