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