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