Home | History | Annotate | Line # | Download | only in tspi
      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. 2005, 2007
      8  *
      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 
     26 TSS_RESULT
     27 obj_pcrs_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject)
     28 {
     29 	TSS_RESULT result;
     30 	UINT32 ver;
     31 	struct tr_pcrs_obj *pcrs;
     32 
     33 	if ((pcrs = calloc(1, sizeof(struct tr_pcrs_obj))) == NULL) {
     34 		LogError("malloc of %zd bytes failed.", sizeof(struct tr_pcrs_obj));
     35 		return TSPERR(TSS_E_OUTOFMEMORY);
     36 	}
     37 
     38 	if (type == TSS_PCRS_STRUCT_DEFAULT) {
     39 		if ((result = obj_context_get_connection_version(tspContext, &ver))) {
     40 			free(pcrs);
     41 			return result;
     42 		}
     43 
     44 		switch (ver) {
     45 			case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2:
     46 				pcrs->type = TSS_PCRS_STRUCT_INFO_LONG;
     47 				pcrs->info.infolong.localityAtRelease = TSS_LOCALITY_ALL;
     48 				break;
     49 			case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1:
     50 				/* fall through */
     51 			default:
     52 				pcrs->type = TSS_PCRS_STRUCT_INFO;
     53 				break;
     54 		}
     55 	} else
     56 		pcrs->type = type;
     57 
     58 	if ((result = obj_list_add(&pcrs_list, tspContext, 0, pcrs, phObject))) {
     59 		free(pcrs);
     60 		return result;
     61 	}
     62 
     63 	return TSS_SUCCESS;
     64 }
     65 
     66 void
     67 pcrs_free(void *data)
     68 {
     69 	struct tr_pcrs_obj *pcrs = (struct tr_pcrs_obj *)data;
     70 
     71 	switch (pcrs->type) {
     72 		case TSS_PCRS_STRUCT_INFO:
     73 			free(pcrs->info.info11.pcrSelection.pcrSelect);
     74 			free(pcrs->pcrs);
     75 			break;
     76 		case TSS_PCRS_STRUCT_INFO_SHORT:
     77 			free(pcrs->info.infoshort.pcrSelection.pcrSelect);
     78 			free(pcrs->pcrs);
     79 			break;
     80 		case TSS_PCRS_STRUCT_INFO_LONG:
     81 			free(pcrs->info.infolong.creationPCRSelection.pcrSelect);
     82 			free(pcrs->info.infolong.releasePCRSelection.pcrSelect);
     83 			break;
     84 		default:
     85 			LogDebugFn("Undefined type of PCRs object");
     86 			break;
     87 	}
     88 
     89 	free(pcrs);
     90 }
     91 
     92 TSS_RESULT
     93 obj_pcrs_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
     94 {
     95 	TSS_RESULT result;
     96 
     97 	if ((result = obj_list_remove(&pcrs_list, &pcrs_free, hObject, tspContext)))
     98 		return result;
     99 
    100 	return TSS_SUCCESS;
    101 }
    102 
    103 TSS_BOOL
    104 obj_is_pcrs(TSS_HOBJECT hObject)
    105 {
    106 	TSS_BOOL answer = FALSE;
    107 
    108 	if ((obj_list_get_obj(&pcrs_list, hObject))) {
    109 		answer = TRUE;
    110 		obj_list_put(&pcrs_list);
    111 	}
    112 
    113 	return answer;
    114 }
    115 
    116 TSS_RESULT
    117 obj_pcrs_get_tsp_context(TSS_HPCRS hPcrs, TSS_HCONTEXT *tspContext)
    118 {
    119 	struct tsp_object *obj;
    120 
    121 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    122 		return TSPERR(TSS_E_INVALID_HANDLE);
    123 
    124 	*tspContext = obj->tspContext;
    125 
    126 	obj_list_put(&pcrs_list);
    127 
    128 	return TSS_SUCCESS;
    129 }
    130 
    131 TSS_RESULT
    132 obj_pcrs_get_type(TSS_HPCRS hPcrs, UINT32 *type)
    133 {
    134 	struct tsp_object *obj;
    135 	struct tr_pcrs_obj *pcrs;
    136 
    137 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    138 		return TSPERR(TSS_E_INVALID_HANDLE);
    139 
    140 	pcrs = (struct tr_pcrs_obj *)obj->data;
    141 
    142 	*type = pcrs->type;
    143 
    144 	obj_list_put(&pcrs_list);
    145 
    146 	return TSS_SUCCESS;
    147 }
    148 
    149 TSS_RESULT
    150 obj_pcrs_get_selection(TSS_HPCRS hPcrs, UINT32 *size, BYTE *out)
    151 {
    152 	struct tsp_object *obj;
    153 	struct tr_pcrs_obj *pcrs;
    154 	TSS_RESULT result = TSS_SUCCESS;
    155 	TPM_PCR_SELECTION *tmp;
    156 	UINT64 offset = 0;
    157 
    158 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    159 		return TSPERR(TSS_E_INVALID_HANDLE);
    160 
    161 	pcrs = (struct tr_pcrs_obj *)obj->data;
    162 
    163 	switch (pcrs->type) {
    164 		case TSS_PCRS_STRUCT_INFO:
    165 			tmp = &pcrs->info.info11.pcrSelection;
    166 			break;
    167 		case TSS_PCRS_STRUCT_INFO_SHORT:
    168 			tmp = &pcrs->info.infoshort.pcrSelection;
    169 			break;
    170 		case TSS_PCRS_STRUCT_INFO_LONG:
    171 			tmp = &pcrs->info.infolong.creationPCRSelection;
    172 			break;
    173 		default:
    174 			LogDebugFn("Undefined type of PCRs object");
    175 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    176 			goto done;
    177 	}
    178 
    179 	Trspi_LoadBlob_PCR_SELECTION(&offset, out, tmp);
    180 	*size = offset;
    181 done:
    182 	obj_list_put(&pcrs_list);
    183 
    184 	return result;
    185 }
    186 
    187 TSS_RESULT
    188 obj_pcrs_set_values(TSS_HPCRS hPcrs, TPM_PCR_COMPOSITE *pcrComp)
    189 {
    190 	TSS_RESULT result = TSS_SUCCESS;
    191 	TPM_PCR_SELECTION *select = &(pcrComp->select);
    192 	UINT16 i, val_idx = 0;
    193 
    194 	for (i = 0; i < select->sizeOfSelect * 8; i++) {
    195 		if (select->pcrSelect[i / 8] & (1 << (i % 8))) {
    196 			if ((result = obj_pcrs_set_value(hPcrs, i, TCPA_SHA1_160_HASH_LEN,
    197 							 (BYTE *)&pcrComp->pcrValue[val_idx])))
    198 				return result;
    199 
    200 			val_idx++;
    201 		}
    202 	}
    203 
    204 	return result;
    205 }
    206 
    207 TSS_RESULT
    208 obj_pcrs_set_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 size, BYTE *value)
    209 {
    210 	struct tsp_object *obj;
    211 	struct tr_pcrs_obj *pcrs;
    212 	TSS_RESULT result = TSS_SUCCESS;
    213 	TPM_PCR_SELECTION *select;
    214 	TPM_COMPOSITE_HASH *compHash;
    215 	UINT16 bytes_to_hold = (idx / 8) + 1;
    216 
    217 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    218 		return TSPERR(TSS_E_INVALID_HANDLE);
    219 
    220 	pcrs = (struct tr_pcrs_obj *)obj->data;
    221 
    222 	switch(pcrs->type) {
    223 		case TSS_PCRS_STRUCT_INFO:
    224 			bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold;
    225 			select = &pcrs->info.info11.pcrSelection;
    226 			compHash = &pcrs->info.info11.digestAtRelease;
    227 			break;
    228 		case TSS_PCRS_STRUCT_INFO_SHORT:
    229 			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
    230 			select = &pcrs->info.infoshort.pcrSelection;
    231 			compHash = &pcrs->info.infoshort.digestAtRelease;
    232 			break;
    233 		case TSS_PCRS_STRUCT_INFO_LONG:
    234 			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
    235 			select = &pcrs->info.infolong.releasePCRSelection;
    236 			compHash = &pcrs->info.infolong.digestAtRelease;
    237 			break;
    238 		default:
    239 			LogDebugFn("Undefined type of PCRs object");
    240 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    241 			goto done;
    242 			break;
    243 	}
    244 
    245 	/* allocate the selection structure */
    246 	if (select->pcrSelect == NULL) {
    247 		if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) {
    248 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    249 			result = TSPERR(TSS_E_OUTOFMEMORY);
    250 			goto done;
    251 		}
    252 		select->sizeOfSelect = bytes_to_hold;
    253 		__tspi_memset(select->pcrSelect, 0, bytes_to_hold);
    254 
    255 		/* allocate the pcr array */
    256 		if ((pcrs->pcrs = malloc(bytes_to_hold * 8 *
    257 					 TCPA_SHA1_160_HASH_LEN)) == NULL) {
    258 			LogError("malloc of %d bytes failed.",
    259 				bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN);
    260 			result = TSPERR(TSS_E_OUTOFMEMORY);
    261 			goto done;
    262 		}
    263 	} else if (select->sizeOfSelect < bytes_to_hold) {
    264 		if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
    265 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    266 			result = TSPERR(TSS_E_OUTOFMEMORY);
    267 			goto done;
    268 		}
    269 		/* set the newly allocated bytes to 0 */
    270 		__tspi_memset(&select->pcrSelect[select->sizeOfSelect], 0,
    271 			      bytes_to_hold - select->sizeOfSelect);
    272 		select->sizeOfSelect = bytes_to_hold;
    273 
    274 		/* realloc the pcrs array */
    275 		if ((pcrs->pcrs = realloc(pcrs->pcrs, bytes_to_hold * 8 *
    276 					  sizeof(TPM_PCRVALUE))) == NULL) {
    277 			LogError("malloc of %d bytes failed.",
    278 					bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN);
    279 			result = TSPERR(TSS_E_OUTOFMEMORY);
    280 			goto done;
    281 		}
    282 	}
    283 
    284 	/* set the bit in the selection structure */
    285 	select->pcrSelect[idx / 8] |= (1 << (idx % 8));
    286 
    287 	/* set the value in the pcrs array */
    288 	memcpy(&(pcrs->pcrs[idx]), value, size);
    289 
    290 	result = pcrs_calc_composite(select, pcrs->pcrs, compHash);
    291 
    292 done:
    293 	obj_list_put(&pcrs_list);
    294 
    295 	return result;
    296 }
    297 
    298 TSS_RESULT
    299 obj_pcrs_get_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 *size, BYTE **value)
    300 {
    301 	struct tsp_object *obj;
    302 	struct tr_pcrs_obj *pcrs;
    303 	TSS_RESULT result = TSS_SUCCESS;
    304 	TPM_PCR_SELECTION *select;
    305 
    306 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    307 		return TSPERR(TSS_E_INVALID_HANDLE);
    308 
    309 	pcrs = (struct tr_pcrs_obj *)obj->data;
    310 
    311 	switch(pcrs->type) {
    312 		case TSS_PCRS_STRUCT_INFO:
    313 			select = &pcrs->info.info11.pcrSelection;
    314 			break;
    315 		case TSS_PCRS_STRUCT_INFO_SHORT:
    316 			select = &pcrs->info.infoshort.pcrSelection;
    317 			break;
    318 		case TSS_PCRS_STRUCT_INFO_LONG:
    319 			select = &pcrs->info.infolong.creationPCRSelection;
    320 			break;
    321 		default:
    322 			LogDebugFn("Undefined type of PCRs object");
    323 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    324 			goto done;
    325 			break;
    326 	}
    327 
    328 	if (select->sizeOfSelect < (idx / 8) + 1) {
    329 		result = TSPERR(TSS_E_BAD_PARAMETER);
    330 		goto done;
    331 	}
    332 
    333 	if ((*value = calloc_tspi(obj->tspContext, TCPA_SHA1_160_HASH_LEN)) == NULL) {
    334 		LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN);
    335 		result = TSPERR(TSS_E_OUTOFMEMORY);
    336 		goto done;
    337 	}
    338 
    339 	*size = TCPA_SHA1_160_HASH_LEN;
    340 	memcpy(*value, &pcrs->pcrs[idx], TCPA_SHA1_160_HASH_LEN);
    341 
    342 done:
    343 	obj_list_put(&pcrs_list);
    344 
    345 	return result;
    346 }
    347 
    348 TSS_RESULT
    349 obj_pcrs_get_digest_at_release(TSS_HPCRS hPcrs, UINT32 *size, BYTE **out)
    350 {
    351 	struct tsp_object *obj;
    352 	struct tr_pcrs_obj *pcrs;
    353 	TSS_RESULT result = TSS_SUCCESS;
    354 	BYTE *digest;
    355 
    356 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    357 		return TSPERR(TSS_E_INVALID_HANDLE);
    358 
    359 	pcrs = (struct tr_pcrs_obj *)obj->data;
    360 
    361 	switch(pcrs->type) {
    362 		case TSS_PCRS_STRUCT_INFO:
    363 #ifdef TSS_SPEC_COMPLIANCE
    364 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    365 			goto done;
    366 #else
    367             digest = (BYTE *)&pcrs->info.info11.digestAtRelease;
    368             break;
    369 #endif
    370 		case TSS_PCRS_STRUCT_INFO_SHORT:
    371 			digest = (BYTE *)&pcrs->info.infoshort.digestAtRelease;
    372 			break;
    373 		case TSS_PCRS_STRUCT_INFO_LONG:
    374 			digest = (BYTE *)&pcrs->info.infolong.digestAtRelease;
    375 			break;
    376 		default:
    377 			LogDebugFn("Undefined type of PCRs object");
    378 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    379 			goto done;
    380 			break;
    381 	}
    382 
    383 	if ((*out = calloc_tspi(obj->tspContext, sizeof(TPM_COMPOSITE_HASH))) == NULL) {
    384 		LogError("malloc of %zd bytes failed.", sizeof(TPM_COMPOSITE_HASH));
    385 		result = TSPERR(TSS_E_OUTOFMEMORY);
    386 		goto done;
    387 	}
    388 	memcpy(*out, digest, sizeof(TPM_COMPOSITE_HASH));
    389 	*size = sizeof(TPM_COMPOSITE_HASH);
    390 
    391 done:
    392 	obj_list_put(&pcrs_list);
    393 
    394 	return result;
    395 }
    396 
    397 TSS_RESULT
    398 obj_pcrs_select_index(TSS_HPCRS hPcrs, UINT32 idx)
    399 {
    400 	struct tsp_object *obj;
    401 	struct tr_pcrs_obj *pcrs;
    402 	TSS_RESULT result = TSS_SUCCESS;
    403 	TPM_PCR_SELECTION *select;
    404 	UINT16 bytes_to_hold = (idx / 8) + 1;
    405 
    406 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    407 		return TSPERR(TSS_E_INVALID_HANDLE);
    408 
    409 	pcrs = (struct tr_pcrs_obj *)obj->data;
    410 
    411 	switch(pcrs->type) {
    412 		case TSS_PCRS_STRUCT_INFO:
    413 			bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold;
    414 			select = &pcrs->info.info11.pcrSelection;
    415 			break;
    416 		case TSS_PCRS_STRUCT_INFO_SHORT:
    417 		case TSS_PCRS_STRUCT_INFO_LONG:
    418 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    419 			goto done;
    420 		default:
    421 			LogDebugFn("Undefined type of PCRs object");
    422 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    423 			goto done;
    424 			break;
    425 	}
    426 
    427 	/* allocate the selection structure */
    428 	if (select->pcrSelect == NULL) {
    429 		if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) {
    430 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    431 			result = TSPERR(TSS_E_OUTOFMEMORY);
    432 			goto done;
    433 		}
    434 		select->sizeOfSelect = bytes_to_hold;
    435 		__tspi_memset(select->pcrSelect, 0, bytes_to_hold);
    436 
    437 		/* alloc the pcrs array */
    438 		if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
    439 			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
    440 				 TCPA_SHA1_160_HASH_LEN);
    441 			result = TSPERR(TSS_E_OUTOFMEMORY);
    442 			goto done;
    443 		}
    444 	} else if (select->sizeOfSelect < bytes_to_hold) {
    445 		if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
    446 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    447 			result = TSPERR(TSS_E_OUTOFMEMORY);
    448 			goto done;
    449 		}
    450 		/* set the newly allocated bytes to 0 */
    451 		__tspi_memset(&select->pcrSelect[select->sizeOfSelect], 0,
    452 			      bytes_to_hold - select->sizeOfSelect);
    453 		select->sizeOfSelect = bytes_to_hold;
    454 
    455 		/* realloc the pcrs array */
    456 		if ((pcrs->pcrs = realloc(pcrs->pcrs,
    457 					  bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
    458 			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
    459 				 TCPA_SHA1_160_HASH_LEN);
    460 			result = TSPERR(TSS_E_OUTOFMEMORY);
    461 			goto done;
    462 		}
    463 	}
    464 
    465 	/* set the bit in the selection structure */
    466 	select->pcrSelect[idx / 8] |= (1 << (idx % 8));
    467 
    468 done:
    469 	obj_list_put(&pcrs_list);
    470 
    471 	return result;
    472 }
    473 
    474 TSS_RESULT
    475 obj_pcrs_select_index_ex(TSS_HPCRS hPcrs, UINT32 dir, UINT32 idx)
    476 {
    477 	struct tsp_object *obj;
    478 	struct tr_pcrs_obj *pcrs;
    479 	TSS_RESULT result = TSS_SUCCESS;
    480 	TPM_PCR_SELECTION *select;
    481 	UINT16 bytes_to_hold = (idx / 8) + 1;
    482 
    483 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    484 		return TSPERR(TSS_E_INVALID_HANDLE);
    485 
    486 	pcrs = (struct tr_pcrs_obj *)obj->data;
    487 
    488 	switch(pcrs->type) {
    489 		case TSS_PCRS_STRUCT_INFO:
    490 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    491 			goto done;
    492 		case TSS_PCRS_STRUCT_INFO_SHORT:
    493 			if (dir == TSS_PCRS_DIRECTION_CREATION) {
    494 				result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    495 				goto done;
    496 			}
    497 			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
    498 			select = &pcrs->info.infoshort.pcrSelection;
    499 			break;
    500 		case TSS_PCRS_STRUCT_INFO_LONG:
    501 			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
    502 			if (dir == TSS_PCRS_DIRECTION_CREATION)
    503 				select = &pcrs->info.infolong.creationPCRSelection;
    504 			else
    505 				select = &pcrs->info.infolong.releasePCRSelection;
    506 			break;
    507 		default:
    508 			LogDebugFn("Undefined type of PCRs object");
    509 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    510 			goto done;
    511 			break;
    512 	}
    513 
    514 	/* allocate the selection structure */
    515 	if (select->pcrSelect == NULL) {
    516 		if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) {
    517 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    518 			result = TSPERR(TSS_E_OUTOFMEMORY);
    519 			goto done;
    520 		}
    521 		select->sizeOfSelect = bytes_to_hold;
    522 		__tspi_memset(select->pcrSelect, 0, bytes_to_hold);
    523 
    524 		/* alloc the pcrs array */
    525 		if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
    526 			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
    527 				 TCPA_SHA1_160_HASH_LEN);
    528 			result = TSPERR(TSS_E_OUTOFMEMORY);
    529 			goto done;
    530 		}
    531 	} else if (select->sizeOfSelect < bytes_to_hold) {
    532 		if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
    533 			LogError("malloc of %d bytes failed.", bytes_to_hold);
    534 			result = TSPERR(TSS_E_OUTOFMEMORY);
    535 			goto done;
    536 		}
    537 		/* set the newly allocated bytes to 0 */
    538 		__tspi_memset(&select->pcrSelect[select->sizeOfSelect], 0,
    539 			      bytes_to_hold - select->sizeOfSelect);
    540 		select->sizeOfSelect = bytes_to_hold;
    541 
    542 		/* realloc the pcrs array */
    543 		if ((pcrs->pcrs = realloc(pcrs->pcrs,
    544 					  bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
    545 			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
    546 				 TCPA_SHA1_160_HASH_LEN);
    547 			result = TSPERR(TSS_E_OUTOFMEMORY);
    548 			goto done;
    549 		}
    550 	}
    551 
    552 	/* set the bit in the selection structure */
    553 	select->pcrSelect[idx / 8] |= (1 << (idx % 8));
    554 
    555 done:
    556 	obj_list_put(&pcrs_list);
    557 
    558 	return result;
    559 }
    560 
    561 TSS_RESULT
    562 obj_pcrs_create_info_type(TSS_HPCRS hPcrs, UINT32 *type, UINT32 *size, BYTE **info)
    563 {
    564 	TSS_RESULT result;
    565 
    566 	/* If type equals 0, then we create the structure
    567 	   based on how the object was created */
    568 	if (*type == 0) {
    569 		struct tsp_object *obj;
    570 		struct tr_pcrs_obj *pcrs;
    571 
    572 		if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    573 			return TSPERR(TSS_E_INVALID_HANDLE);
    574 
    575 		pcrs = (struct tr_pcrs_obj *)obj->data;
    576 		*type = pcrs->type;
    577 
    578 		obj_list_put(&pcrs_list);
    579 	}
    580 
    581 	switch (*type) {
    582 	case TSS_PCRS_STRUCT_INFO:
    583 		result = obj_pcrs_create_info(hPcrs, size, info);
    584 		break;
    585 	case TSS_PCRS_STRUCT_INFO_LONG:
    586 		result = obj_pcrs_create_info_long(hPcrs, size, info);
    587 		break;
    588 	case TSS_PCRS_STRUCT_INFO_SHORT:
    589 		result = obj_pcrs_create_info_short(hPcrs, size, info);
    590 		break;
    591 	default:
    592 		return TSPERR(TSS_E_INTERNAL_ERROR);
    593 	}
    594 
    595 	return result;
    596 }
    597 
    598 /* Create a PCR info struct based on the hPcrs object */
    599 TSS_RESULT
    600 obj_pcrs_create_info(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info)
    601 {
    602 	struct tsp_object *obj;
    603 	struct tr_pcrs_obj *pcrs;
    604 	TSS_RESULT result = TSS_SUCCESS;
    605 	TPM_PCR_INFO info11;
    606 	UINT64 offset;
    607 	UINT32 ret_size;
    608 	BYTE *ret;
    609 
    610 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    611 		return TSPERR(TSS_E_INVALID_HANDLE);
    612 
    613 	pcrs = (struct tr_pcrs_obj *)obj->data;
    614 
    615 	/* Set everything that is not assigned to be all zeroes */
    616 	__tspi_memset(&info11, 0, sizeof(info11));
    617 
    618 	switch (pcrs->type) {
    619 		case TSS_PCRS_STRUCT_INFO:
    620 			info11 = pcrs->info.info11;
    621 			break;
    622 		case TSS_PCRS_STRUCT_INFO_LONG:
    623 			info11.pcrSelection = pcrs->info.infolong.releasePCRSelection;
    624 			info11.digestAtRelease = pcrs->info.infolong.digestAtRelease;
    625 			break;
    626 		case TSS_PCRS_STRUCT_INFO_SHORT:
    627 			info11.pcrSelection = pcrs->info.infoshort.pcrSelection;
    628 			info11.digestAtRelease = pcrs->info.infoshort.digestAtRelease;
    629 			break;
    630 		default:
    631 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    632 			goto done;
    633 	}
    634 
    635 	offset = 0;
    636 	Trspi_LoadBlob_PCR_INFO(&offset, NULL, &info11);
    637 	ret_size = offset;
    638 
    639 	if ((ret = calloc(1, ret_size)) == NULL) {
    640 		result = TSPERR(TSS_E_OUTOFMEMORY);
    641 		LogDebug("malloc of %u bytes failed.", ret_size);
    642 		goto done;
    643 	}
    644 
    645 	offset = 0;
    646 	Trspi_LoadBlob_PCR_INFO(&offset, ret, &info11);
    647 
    648 	*info = ret;
    649 	*size = ret_size;
    650 
    651 done:
    652 	obj_list_put(&pcrs_list);
    653 
    654 	return result;
    655 }
    656 
    657 TSS_RESULT
    658 obj_pcrs_create_info_long(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info)
    659 {
    660 	struct tsp_object *obj;
    661 	struct tr_pcrs_obj *pcrs;
    662 	TSS_RESULT result = TSS_SUCCESS;
    663 	TPM_PCR_INFO_LONG infolong;
    664 	BYTE dummyBits[3] = { 0, 0, 0 };
    665 	TPM_PCR_SELECTION dummySelection = { 3, dummyBits };
    666 	UINT64 offset;
    667 	UINT32 ret_size;
    668 	BYTE *ret;
    669 
    670 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    671 		return TSPERR(TSS_E_INVALID_HANDLE);
    672 
    673 	pcrs = (struct tr_pcrs_obj *)obj->data;
    674 
    675 	/* Set everything that is not assigned to be all zeroes */
    676 	__tspi_memset(&infolong, 0, sizeof(infolong));
    677 
    678 	infolong.tag = TPM_TAG_PCR_INFO_LONG;
    679 	/* localityAtCreation and creationPCRSelection certainly do not need to be set here, but
    680 	 * some chips such as Winbond do not ignore them on input, so we must give them dummy
    681 	 * "good" values */
    682 	infolong.localityAtCreation = TPM_LOC_ZERO;
    683 	infolong.creationPCRSelection = dummySelection;
    684 	switch (pcrs->type) {
    685 		case TSS_PCRS_STRUCT_INFO:
    686 			infolong.localityAtRelease = TSS_LOCALITY_ALL;
    687 			infolong.releasePCRSelection = pcrs->info.info11.pcrSelection;
    688 			infolong.digestAtRelease = pcrs->info.info11.digestAtRelease;
    689 			break;
    690 		case TSS_PCRS_STRUCT_INFO_LONG:
    691 			infolong.localityAtRelease = pcrs->info.infolong.localityAtRelease;
    692 			infolong.releasePCRSelection = pcrs->info.infolong.releasePCRSelection;
    693 			infolong.digestAtRelease = pcrs->info.infolong.digestAtRelease;
    694 			break;
    695 		case TSS_PCRS_STRUCT_INFO_SHORT:
    696 			infolong.localityAtRelease = pcrs->info.infoshort.localityAtRelease;
    697 			infolong.releasePCRSelection = pcrs->info.infoshort.pcrSelection;
    698 			infolong.digestAtRelease = pcrs->info.infoshort.digestAtRelease;
    699 			break;
    700 		default:
    701 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    702 			goto done;
    703 	}
    704 
    705 	offset = 0;
    706 	Trspi_LoadBlob_PCR_INFO_LONG(&offset, NULL, &infolong);
    707 	ret_size = offset;
    708 
    709 	if ((ret = calloc(1, ret_size)) == NULL) {
    710 		result = TSPERR(TSS_E_OUTOFMEMORY);
    711 		LogDebug("malloc of %u bytes failed.", ret_size);
    712 		goto done;
    713 	}
    714 
    715 	offset = 0;
    716 	Trspi_LoadBlob_PCR_INFO_LONG(&offset, ret, &infolong);
    717 
    718 	*info = ret;
    719 	*size = ret_size;
    720 
    721 done:
    722 	obj_list_put(&pcrs_list);
    723 
    724 	return result;
    725 }
    726 
    727 TSS_RESULT
    728 obj_pcrs_create_info_short(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info)
    729 {
    730 	struct tsp_object *obj;
    731 	struct tr_pcrs_obj *pcrs;
    732 	TSS_RESULT result = TSS_SUCCESS;
    733 	TPM_PCR_INFO_SHORT infoshort;
    734 	BYTE select[] = { 0, 0, 0 };
    735 	UINT64 offset;
    736 	UINT32 ret_size;
    737 	BYTE *ret;
    738 
    739 	/* Set everything that is not assigned to be all zeroes */
    740 	__tspi_memset(&infoshort, 0, sizeof(infoshort));
    741 
    742 	if (hPcrs != NULL_HPCRS) {
    743 		if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    744 			return TSPERR(TSS_E_INVALID_HANDLE);
    745 
    746 		pcrs = (struct tr_pcrs_obj *)obj->data;
    747 
    748 		switch (pcrs->type) {
    749 			case TSS_PCRS_STRUCT_INFO:
    750 				infoshort.pcrSelection = pcrs->info.info11.pcrSelection;
    751 				infoshort.localityAtRelease = TSS_LOCALITY_ALL;
    752 				infoshort.digestAtRelease = pcrs->info.info11.digestAtRelease;
    753 				break;
    754 			case TSS_PCRS_STRUCT_INFO_LONG:
    755 				infoshort.pcrSelection = pcrs->info.infolong.releasePCRSelection;
    756 				infoshort.localityAtRelease = pcrs->info.infolong.localityAtRelease;
    757 				infoshort.digestAtRelease = pcrs->info.infolong.digestAtRelease;
    758 				break;
    759 			case TSS_PCRS_STRUCT_INFO_SHORT:
    760 				infoshort = pcrs->info.infoshort;
    761 				break;
    762 			default:
    763 				result = TSPERR(TSS_E_INTERNAL_ERROR);
    764 				goto done;
    765 		}
    766 	} else {
    767 		infoshort.pcrSelection.sizeOfSelect = sizeof(select);
    768 		infoshort.pcrSelection.pcrSelect = select;
    769 		infoshort.localityAtRelease = TSS_LOCALITY_ALL;
    770 	}
    771 
    772 	offset = 0;
    773 	Trspi_LoadBlob_PCR_INFO_SHORT(&offset, NULL, &infoshort);
    774 	ret_size = offset;
    775 
    776 	if ((ret = calloc(1, ret_size)) == NULL) {
    777 		result = TSPERR(TSS_E_OUTOFMEMORY);
    778 		LogDebug("malloc of %u bytes failed.", ret_size);
    779 		goto done;
    780 	}
    781 
    782 	offset = 0;
    783 	Trspi_LoadBlob_PCR_INFO_SHORT(&offset, ret, &infoshort);
    784 
    785 	*info = ret;
    786 	*size = ret_size;
    787 
    788 done:
    789 	if (hPcrs != NULL_HPCRS)
    790 		obj_list_put(&pcrs_list);
    791 
    792 	return result;
    793 }
    794 
    795 TSS_RESULT
    796 obj_pcrs_get_locality(TSS_HPCRS hPcrs, UINT32 *out)
    797 {
    798 	struct tsp_object *obj;
    799 	struct tr_pcrs_obj *pcrs;
    800 	TSS_RESULT result = TSS_SUCCESS;
    801 	BYTE *locality;
    802 
    803 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    804 		return TSPERR(TSS_E_INVALID_HANDLE);
    805 
    806 	pcrs = (struct tr_pcrs_obj *)obj->data;
    807 
    808 	switch(pcrs->type) {
    809 		case TSS_PCRS_STRUCT_INFO:
    810 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    811 			goto done;
    812 		case TSS_PCRS_STRUCT_INFO_SHORT:
    813 			locality = &pcrs->info.infoshort.localityAtRelease;
    814 			break;
    815 		case TSS_PCRS_STRUCT_INFO_LONG:
    816 			locality = &pcrs->info.infolong.localityAtRelease;
    817 			break;
    818 		default:
    819 			LogDebugFn("Undefined type of PCRs object");
    820 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    821 			goto done;
    822 	}
    823 
    824 	*out = (UINT32)*locality;
    825 
    826 done:
    827 	obj_list_put(&pcrs_list);
    828 
    829 	return result;
    830 }
    831 
    832 TSS_RESULT
    833 obj_pcrs_set_locality(TSS_HPCRS hPcrs, UINT32 locality)
    834 {
    835 	struct tsp_object *obj;
    836 	struct tr_pcrs_obj *pcrs;
    837 	TSS_RESULT result = TSS_SUCCESS;
    838 	BYTE *loc;
    839 
    840 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    841 		return TSPERR(TSS_E_INVALID_HANDLE);
    842 
    843 	pcrs = (struct tr_pcrs_obj *)obj->data;
    844 
    845 	switch(pcrs->type) {
    846 		case TSS_PCRS_STRUCT_INFO:
    847 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    848 			goto done;
    849 		case TSS_PCRS_STRUCT_INFO_SHORT:
    850 			loc = &pcrs->info.infoshort.localityAtRelease;
    851 			break;
    852 		case TSS_PCRS_STRUCT_INFO_LONG:
    853 			loc = &pcrs->info.infolong.localityAtRelease;
    854 			break;
    855 		default:
    856 			LogDebugFn("Undefined type of PCRs object");
    857 			result = TSPERR(TSS_E_INTERNAL_ERROR);
    858 			goto done;
    859 	}
    860 
    861 	*loc = locality;
    862 done:
    863 	obj_list_put(&pcrs_list);
    864 
    865 	return result;
    866 }
    867 
    868 TSS_RESULT
    869 obj_pcrs_set_digest_at_release(TSS_HPCRS hPcrs, TPM_COMPOSITE_HASH digest)
    870 {
    871 	struct tsp_object *obj;
    872 	struct tr_pcrs_obj *pcrs;
    873 	TSS_RESULT result = TSS_SUCCESS;
    874 	TPM_COMPOSITE_HASH *dig;
    875 
    876 	LogDebugFn("######## Digest to be set on TSS object:");
    877 	LogDebugData(TCPA_SHA1_160_HASH_LEN, digest.digest);
    878 
    879 	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
    880 		return TSPERR(TSS_E_INVALID_HANDLE);
    881 
    882 	pcrs = (struct tr_pcrs_obj *)obj->data;
    883 
    884 	switch(pcrs->type) {
    885 	case TSS_PCRS_STRUCT_INFO:
    886 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
    887 		goto done;
    888 	case TSS_PCRS_STRUCT_INFO_SHORT:
    889 		dig = &pcrs->info.infoshort.digestAtRelease;
    890 		break;
    891 	case TSS_PCRS_STRUCT_INFO_LONG:
    892 		dig = &pcrs->info.infolong.digestAtRelease;
    893 		break;
    894 	default:
    895 		LogDebugFn("Undefined type of PCRs object");
    896 		result = TSPERR(TSS_E_INTERNAL_ERROR);
    897 		goto done;
    898 	}
    899 
    900 	/* Copy the digest information */
    901 	memcpy(dig->digest,&digest.digest,TPM_SHA1_160_HASH_LEN);
    902 
    903 	LogDebugFn("######## Digest SET on TSS object:");
    904 	LogDebugData(TCPA_SHA1_160_HASH_LEN,pcrs->info.infoshort.digestAtRelease.digest);
    905 
    906 done:
    907 	obj_list_put(&pcrs_list);
    908 
    909 	return result;
    910 }
    911 
    912