xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/obj_pcrs.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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
obj_pcrs_add(TSS_HCONTEXT tspContext,UINT32 type,TSS_HOBJECT * phObject)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
pcrs_free(void * data)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
obj_pcrs_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)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
obj_is_pcrs(TSS_HOBJECT hObject)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
obj_pcrs_get_tsp_context(TSS_HPCRS hPcrs,TSS_HCONTEXT * tspContext)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
obj_pcrs_get_type(TSS_HPCRS hPcrs,UINT32 * type)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
obj_pcrs_get_selection(TSS_HPCRS hPcrs,UINT32 * size,BYTE * out)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
obj_pcrs_set_values(TSS_HPCRS hPcrs,TPM_PCR_COMPOSITE * pcrComp)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
obj_pcrs_set_value(TSS_HPCRS hPcrs,UINT32 idx,UINT32 size,BYTE * value)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
obj_pcrs_get_value(TSS_HPCRS hPcrs,UINT32 idx,UINT32 * size,BYTE ** value)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
obj_pcrs_get_digest_at_release(TSS_HPCRS hPcrs,UINT32 * size,BYTE ** out)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
obj_pcrs_select_index(TSS_HPCRS hPcrs,UINT32 idx)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
obj_pcrs_select_index_ex(TSS_HPCRS hPcrs,UINT32 dir,UINT32 idx)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
obj_pcrs_create_info_type(TSS_HPCRS hPcrs,UINT32 * type,UINT32 * size,BYTE ** info)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
obj_pcrs_create_info(TSS_HPCRS hPcrs,UINT32 * size,BYTE ** info)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
obj_pcrs_create_info_long(TSS_HPCRS hPcrs,UINT32 * size,BYTE ** info)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
obj_pcrs_create_info_short(TSS_HPCRS hPcrs,UINT32 * size,BYTE ** info)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
obj_pcrs_get_locality(TSS_HPCRS hPcrs,UINT32 * out)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
obj_pcrs_set_locality(TSS_HPCRS hPcrs,UINT32 locality)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
obj_pcrs_set_digest_at_release(TSS_HPCRS hPcrs,TPM_COMPOSITE_HASH digest)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