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