1 /*
2  * The Initial Developer of the Original Code is Intel Corporation.
3  * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation.
4  * All Rights Reserved.
5  *
6  * trousers - An open source TCG Software Stack
7  *
8  * Author: james.xu@intel.com Rossey.liu@intel.com
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 TSS_RESULT
obj_nvstore_add(TSS_HCONTEXT tspContext,TSS_HOBJECT * phObject)26 obj_nvstore_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject)
27 {
28           TSS_RESULT result;
29           struct tr_nvstore_obj *nvstore = calloc(1, sizeof(struct tr_nvstore_obj));
30 
31           if (nvstore == NULL) {
32                     LogError("malloc of %zd bytes failed.",
33                                         sizeof(struct tr_nvstore_obj));
34                     return TSPERR(TSS_E_OUTOFMEMORY);
35           }
36 
37           if ((result = obj_list_add(&nvstore_list, tspContext, 0, nvstore, phObject))) {
38                     free(nvstore);
39                     return result;
40           }
41 
42           return TSS_SUCCESS;
43 }
44 
45 TSS_BOOL
obj_is_nvstore(TSS_HOBJECT hObject)46 obj_is_nvstore(TSS_HOBJECT hObject)
47 {
48           TSS_BOOL answer = FALSE;
49 
50           if ((obj_list_get_obj(&nvstore_list, hObject))) {
51                     answer = TRUE;
52                     obj_list_put(&nvstore_list);
53           }
54 
55           return answer;
56 }
57 
58 void
nvstore_free(void * data)59 nvstore_free(void *data)
60 {
61           struct tr_nvstore_obj *nvstore = (struct tr_nvstore_obj *)data;
62 
63           free(nvstore);
64 }
65 
66 TSS_RESULT
obj_nvstore_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)67 obj_nvstore_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
68 {
69           TSS_RESULT result;
70 
71           if ((result = obj_list_remove(&nvstore_list, &nvstore_free, hObject, tspContext)))
72                     return result;
73 
74           return TSS_SUCCESS;
75 }
76 
77 TSS_RESULT
obj_nvstore_get_tsp_context(TSS_HNVSTORE hNvstore,TSS_HCONTEXT * tspContext)78 obj_nvstore_get_tsp_context(TSS_HNVSTORE hNvstore, TSS_HCONTEXT * tspContext)
79 {
80           struct tsp_object *obj;
81 
82           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
83                     return TSPERR(TSS_E_INVALID_HANDLE);
84 
85           *tspContext = obj->tspContext;
86 
87           obj_list_put(&nvstore_list);
88 
89           return TSS_SUCCESS;
90 }
91 
92 TSS_RESULT
obj_nvstore_set_index(TSS_HNVSTORE hNvstore,UINT32 index)93 obj_nvstore_set_index(TSS_HNVSTORE hNvstore, UINT32 index)
94 {
95           struct tsp_object *obj;
96           struct tr_nvstore_obj *nvstore;
97           TSS_RESULT result=TSS_SUCCESS;
98 
99           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
100                     return TSPERR(TSS_E_INVALID_HANDLE);
101 
102           nvstore = (struct tr_nvstore_obj *)obj->data;
103 
104           nvstore->nvIndex = index;
105 
106           obj_list_put(&nvstore_list);
107 
108           return result;
109 }
110 
111 TSS_RESULT
obj_nvstore_get_index(TSS_HNVSTORE hNvstore,UINT32 * index)112 obj_nvstore_get_index(TSS_HNVSTORE hNvstore, UINT32 * index)
113 {
114           struct tsp_object *obj;
115           struct tr_nvstore_obj *nvstore;
116           TSS_RESULT result=TSS_SUCCESS;
117 
118           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
119                     return TSPERR(TSS_E_INVALID_HANDLE);
120 
121           nvstore = (struct tr_nvstore_obj *)obj->data;
122 
123           *index = nvstore->nvIndex;
124 
125           obj_list_put(&nvstore_list);
126 
127           return result;
128 }
129 
130 TSS_RESULT
obj_nvstore_set_datasize(TSS_HNVSTORE hNvstore,UINT32 datasize)131 obj_nvstore_set_datasize(TSS_HNVSTORE hNvstore, UINT32 datasize)
132 {
133           struct tsp_object *obj;
134           struct tr_nvstore_obj *nvstore;
135           TSS_RESULT result=TSS_SUCCESS;
136 
137           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
138                     return TSPERR(TSS_E_INVALID_HANDLE);
139 
140           nvstore = (struct tr_nvstore_obj *)obj->data;
141 
142           nvstore->dataSize= datasize;
143 
144           obj_list_put(&nvstore_list);
145 
146           return result;
147 }
148 
149 TSS_RESULT
obj_nvstore_get_datasize(TSS_HNVSTORE hNvstore,UINT32 * datasize)150 obj_nvstore_get_datasize(TSS_HNVSTORE hNvstore, UINT32 * datasize)
151 {
152           struct tsp_object *obj;
153           struct tr_nvstore_obj *nvstore;
154           TSS_RESULT result=TSS_SUCCESS;
155 
156           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
157                     return TSPERR(TSS_E_INVALID_HANDLE);
158 
159           nvstore = (struct tr_nvstore_obj *)obj->data;
160 
161           *datasize = nvstore->dataSize;
162 
163           obj_list_put(&nvstore_list);
164 
165           return result;
166 }
167 
168 TSS_RESULT
obj_nvstore_set_permission(TSS_HNVSTORE hNvstore,UINT32 permission)169 obj_nvstore_set_permission(TSS_HNVSTORE hNvstore, UINT32 permission)
170 {
171           struct tsp_object *obj;
172           struct tr_nvstore_obj *nvstore;
173           TSS_RESULT result=TSS_SUCCESS;
174 
175           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
176                     return TSPERR(TSS_E_INVALID_HANDLE);
177 
178           nvstore = (struct tr_nvstore_obj *)obj->data;
179 
180           nvstore->permission.attributes= permission;
181 
182           obj_list_put(&nvstore_list);
183 
184           return result;
185 }
186 
187 TSS_RESULT
obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore,UINT32 * permission)188 obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore, UINT32 * permission)
189 {
190           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE] = {0};
191           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
192           UINT32 offset;
193           UINT16 pcrread_sizeOfSelect;
194           UINT16 pcrwrite_sizeOfSelect;
195           TPM_NV_ATTRIBUTES nv_attributes_value;
196           TSS_HCONTEXT tspContext;
197           TSS_RESULT result;
198 
199           if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
200                     return result;
201 
202           if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
203                     return result;
204 
205           offset = 0;
206           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
207           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
208 
209           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
210                               + sizeof(TPM_LOCALITY_SELECTION)
211                               + sizeof(TPM_COMPOSITE_HASH);
212           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
213 
214           offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
215                               + sizeof(TPM_LOCALITY_SELECTION)
216                               + sizeof(TPM_COMPOSITE_HASH);
217 
218           nv_attributes_value.attributes = Decode_UINT32(nv_data_public
219                                                                    + offset + sizeof(TPM_STRUCTURE_TAG));
220           *permission = nv_attributes_value.attributes;
221 
222           return result;
223 }
224 
225 TSS_RESULT
obj_nvstore_get_permission(TSS_HNVSTORE hNvstore,UINT32 * permission)226 obj_nvstore_get_permission(TSS_HNVSTORE hNvstore, UINT32 * permission)
227 {
228           struct tsp_object *obj;
229           struct tr_nvstore_obj *nvstore;
230           TSS_RESULT result=TSS_SUCCESS;
231 
232           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
233                     return TSPERR(TSS_E_INVALID_HANDLE);
234 
235           nvstore = (struct tr_nvstore_obj *)obj->data;
236 
237           *permission = nvstore->permission.attributes;
238 
239           obj_list_put(&nvstore_list);
240 
241           return result;
242 }
243 
244 TSS_RESULT
obj_nvstore_set_policy(TSS_HNVSTORE hNvstore,TSS_HPOLICY hPolicy)245 obj_nvstore_set_policy(TSS_HNVSTORE hNvstore, TSS_HPOLICY hPolicy)
246 {
247           struct tsp_object *obj;
248           struct tr_nvstore_obj *nvstore;
249           UINT32 policyType;
250           TSS_RESULT result = TSS_SUCCESS;
251 
252           if ((result = obj_policy_get_type(hPolicy, &policyType)))
253                     return result;
254 
255           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
256                     return TSPERR(TSS_E_INVALID_HANDLE);
257 
258           nvstore = (struct tr_nvstore_obj *)obj->data;
259 
260           switch (policyType) {
261                     case TSS_POLICY_USAGE:
262                               nvstore->policy = hPolicy;
263                               break;
264                     default:
265                               result = TSPERR(TSS_E_BAD_PARAMETER);
266           }
267 
268           obj_list_put(&nvstore_list);
269 
270           return result;
271 }
272 
273 TSS_RESULT
obj_nvstore_get_policy(TSS_HNVSTORE hNvstore,UINT32 policyType,TSS_HPOLICY * phPolicy)274 obj_nvstore_get_policy(TSS_HNVSTORE hNvstore, UINT32 policyType, TSS_HPOLICY *phPolicy)
275 {
276           struct tsp_object *obj;
277           struct tr_nvstore_obj *nvstore;
278           TSS_RESULT result=TSS_SUCCESS;
279 
280           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
281                     return TSPERR(TSS_E_INVALID_HANDLE);
282 
283           nvstore = (struct tr_nvstore_obj *)obj->data;
284 
285           switch (policyType) {
286                     case TSS_POLICY_USAGE:
287                               *phPolicy = nvstore->policy;
288                               break;
289                     default:
290                               result = TSPERR(TSS_E_BAD_PARAMETER);
291           }
292 
293           obj_list_put(&nvstore_list);
294 
295           return result;
296 }
297 
298 TSS_RESULT
obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore,UINT32 * size,BYTE * nv_data_public)299 obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public)
300 {
301           struct tsp_object *obj;
302           TSS_HCONTEXT  hContext;
303           TSS_HTPM hTpm;
304           TSS_RESULT result;
305           struct tr_nvstore_obj *nvstore;
306           UINT32 uiResultLen;
307           BYTE *pResult;
308           UINT32 i;
309           TPM_BOOL defined_index = FALSE;
310 
311           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
312                     return TSPERR(TSS_E_INVALID_HANDLE);
313 
314           hContext = obj->tspContext;
315           nvstore = (struct tr_nvstore_obj *)obj->data;
316 
317           if ((result = obj_tpm_get(hContext, &hTpm)))
318                     goto out;
319 
320           if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
321                                          NULL, &uiResultLen, &pResult))) {
322                     goto out;
323           }
324 
325           for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
326                     if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
327                               defined_index = TRUE;
328                               break;
329                     }
330           }
331 
332           free_tspi(hContext, pResult);
333 
334           if (!defined_index) {
335                     result = TSPERR(TPM_E_BADINDEX);
336                     goto out;
337           }
338 
339           if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX,
340                                                        sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)),
341                                                        &uiResultLen, &pResult))) {
342                     LogDebug("get the index capability error");
343                     goto out;
344           }
345 
346           if (uiResultLen > *size) {
347                     free_tspi(hContext, pResult);
348                     result = TSPERR(TSS_E_INTERNAL_ERROR);
349                     goto out;
350           }
351           *size = uiResultLen;
352           memcpy(nv_data_public, pResult, uiResultLen);
353           free_tspi(hContext, pResult);
354 
355 out:
356           obj_list_put(&nvstore_list);
357           return result;
358 }
359 
360 TSS_RESULT
obj_nvstore_get_readdigestatrelease(TSS_HNVSTORE hNvstore,UINT32 * size,BYTE ** data)361 obj_nvstore_get_readdigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
362 {
363           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
364           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
365           UINT32 offset;
366           UINT16 pcrread_sizeOfSelect;
367           TSS_HCONTEXT tspContext;
368           TSS_RESULT result;
369 
370           if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
371                     return result;
372 
373           if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
374                     return result;
375 
376           *size = sizeof(TPM_COMPOSITE_HASH);
377           *data = calloc_tspi(tspContext, *size);
378           if (*data == NULL) {
379                     LogError("malloc of %u bytes failed.", *size);
380                     result = TSPERR(TSS_E_OUTOFMEMORY);
381                     return result;
382           }
383 
384           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
385           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
386           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION);
387           memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH));
388 
389           return result;
390 }
391 
392 TSS_RESULT
obj_nvstore_get_readpcrselection(TSS_HNVSTORE hNvstore,UINT32 * size,BYTE ** data)393 obj_nvstore_get_readpcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
394 {
395           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
396           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
397           UINT32 offset;
398           UINT16 pcrread_sizeOfSelect;
399           TSS_HCONTEXT tspContext;
400           TSS_RESULT result;
401 
402           if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
403                     return result;
404 
405           if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
406                     return result;
407 
408           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
409           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
410 
411           *size = sizeof(UINT16) + pcrread_sizeOfSelect;
412           *data = calloc_tspi(tspContext, *size);
413           if (*data == NULL) {
414                     LogError("malloc of %u bytes failed.", *size);
415                     result = TSPERR(TSS_E_OUTOFMEMORY);
416                     return result;
417           }
418 
419           memcpy(*data, nv_data_public + offset, *size);
420 
421           return result;
422 }
423 
424 TSS_RESULT
obj_nvstore_get_writedigestatrelease(TSS_HNVSTORE hNvstore,UINT32 * size,BYTE ** data)425 obj_nvstore_get_writedigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
426 {
427           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
428           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
429           UINT32 offset;
430           UINT16 pcrread_sizeOfSelect;
431           TSS_HCONTEXT tspContext;
432           TSS_RESULT result;
433 
434           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
435                     return result;
436 
437           if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
438                     return result;
439 
440           *size = sizeof(TPM_COMPOSITE_HASH);
441           *data = calloc_tspi(tspContext, *size);
442           if (*data == NULL) {
443                     LogError("malloc of %u bytes failed.", *size);
444                     result = TSPERR(TSS_E_OUTOFMEMORY);
445                     return result;
446           }
447 
448           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
449           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
450           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
451                               + sizeof(TPM_LOCALITY_SELECTION)
452                               + sizeof(TPM_COMPOSITE_HASH);
453 
454           Decode_UINT16(nv_data_public + offset);
455           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION);
456           memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH));
457 
458           return result;
459 }
460 
461 TSS_RESULT
obj_nvstore_get_writepcrselection(TSS_HNVSTORE hNvstore,UINT32 * size,BYTE ** data)462 obj_nvstore_get_writepcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data)
463 {
464           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
465           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
466           UINT32 offset;
467           UINT16 pcrread_sizeOfSelect;
468           UINT16 pcrwrite_sizeOfSelect;
469           TSS_HCONTEXT tspContext;
470           TSS_RESULT result;
471 
472           if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
473                     return result;
474 
475           if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
476                     return result;
477 
478           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
479           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
480           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
481                               + sizeof(TPM_LOCALITY_SELECTION)
482                               + sizeof(TPM_COMPOSITE_HASH);
483           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
484 
485           *size = sizeof(UINT16) + pcrwrite_sizeOfSelect;
486           *data = calloc_tspi(tspContext, *size);
487           if (*data == NULL) {
488                     LogError("malloc of %u bytes failed.", *size);
489                     result = TSPERR(TSS_E_OUTOFMEMORY);
490                     return result;
491           }
492 
493           memcpy(*data, nv_data_public + offset, *size);
494           return result;
495 }
496 
497 TSS_RESULT
obj_nvstore_get_state_readstclear(TSS_HNVSTORE hNvstore,UINT32 * readstclear)498 obj_nvstore_get_state_readstclear(TSS_HNVSTORE hNvstore, UINT32 * readstclear)
499 {
500           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
501           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
502           UINT32 offset;
503           UINT16 pcrread_sizeOfSelect;
504           UINT16 pcrwrite_sizeOfSelect;
505           TPM_BOOL value;
506           TSS_RESULT result;
507 
508           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
509                     return result;
510 
511           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
512           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
513           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
514                               + sizeof(TPM_LOCALITY_SELECTION)
515                               + sizeof(TPM_COMPOSITE_HASH);
516 
517           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
518           offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
519                               + sizeof(TPM_LOCALITY_SELECTION)
520                               + sizeof(TPM_COMPOSITE_HASH)
521                               + sizeof(TPM_NV_ATTRIBUTES);
522 
523           value = *((TPM_BOOL *)(nv_data_public + offset));
524 
525           *readstclear = value;
526 
527           return result;
528 }
529 
530 TSS_RESULT
obj_nvstore_get_state_writedefine(TSS_HNVSTORE hNvstore,UINT32 * writedefine)531 obj_nvstore_get_state_writedefine(TSS_HNVSTORE hNvstore, UINT32 * writedefine)
532 {
533           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
534           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
535           UINT32 offset;
536           UINT16 pcrread_sizeOfSelect;
537           UINT16 pcrwrite_sizeOfSelect;
538           TPM_BOOL value;
539           TSS_RESULT result;
540 
541           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
542                     return result;
543 
544           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
545           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
546           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
547                               + sizeof(TPM_LOCALITY_SELECTION)
548                               + sizeof(TPM_COMPOSITE_HASH);
549 
550           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
551           offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
552                               + sizeof(TPM_LOCALITY_SELECTION)
553                               + sizeof(TPM_COMPOSITE_HASH)
554                               + sizeof(TPM_NV_ATTRIBUTES)
555                               + sizeof(TPM_BOOL)
556                               + sizeof(TPM_BOOL);
557 
558           value = *((TPM_BOOL *)(nv_data_public + offset));
559 
560           *writedefine = value;
561 
562           return result;
563 }
564 
565 TSS_RESULT
obj_nvstore_get_state_writestclear(TSS_HNVSTORE hNvstore,UINT32 * writestclear)566 obj_nvstore_get_state_writestclear(TSS_HNVSTORE hNvstore, UINT32 * writestclear)
567 {
568           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
569           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
570           UINT32 offset;
571           UINT16 pcrread_sizeOfSelect;
572           UINT16 pcrwrite_sizeOfSelect;
573           TPM_BOOL value;
574           TSS_RESULT result;
575 
576           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
577                     return result;
578 
579           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
580           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
581           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
582                               + sizeof(TPM_LOCALITY_SELECTION)
583                               + sizeof(TPM_COMPOSITE_HASH);
584 
585           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
586           offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect
587                               + sizeof(TPM_LOCALITY_SELECTION)
588                               + sizeof(TPM_COMPOSITE_HASH)
589                               + sizeof(TPM_NV_ATTRIBUTES)
590                               + sizeof(TPM_BOOL);
591 
592           value = *((TPM_BOOL *)(nv_data_public + offset));
593           *writestclear = value;
594 
595           return result;
596 }
597 
598 TSS_RESULT
obj_nvstore_get_readlocalityatrelease(TSS_HNVSTORE hNvstore,UINT32 * readlocalityatrelease)599 obj_nvstore_get_readlocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * readlocalityatrelease)
600 {
601           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
602           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
603           UINT32 offset;
604           UINT16 pcrread_sizeOfSelect;
605           TPM_LOCALITY_SELECTION locality_value;
606           TSS_RESULT result;
607 
608           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
609                     return result;
610 
611           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
612           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
613           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect;
614           locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset));
615           *readlocalityatrelease = locality_value;
616 
617           return result;
618 }
619 
620 TSS_RESULT
obj_nvstore_get_writelocalityatrelease(TSS_HNVSTORE hNvstore,UINT32 * writelocalityatrelease)621 obj_nvstore_get_writelocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * writelocalityatrelease)
622 {
623           BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE];
624           UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE;
625           UINT32 offset;
626           UINT16 pcrread_sizeOfSelect;
627           UINT16 pcrwrite_sizeOfSelect;
628           TPM_LOCALITY_SELECTION locality_value;
629           TSS_RESULT result;
630 
631           if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public)))
632                     return result;
633 
634           offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX);
635           pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
636           offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect
637                               + sizeof(TPM_LOCALITY_SELECTION)
638                               + sizeof(TPM_COMPOSITE_HASH);
639           pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset);
640           offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect;
641 
642           locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset));
643           *writelocalityatrelease = locality_value;
644 
645           return result;
646 }
647 
648 TSS_RESULT
obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore,TSS_HPCRS hPcrComposite,UINT32 * size,BYTE ** data)649 obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore,
650                                         TSS_HPCRS hPcrComposite,
651                                         UINT32 *size,
652                                         BYTE **data)
653 {
654           struct tsp_object *obj;
655           BYTE pdata[MAX_PUBLIC_DATA_SIZE];
656           UINT32 dataLen;
657           UINT64 offset;
658           TSS_HCONTEXT tspContext;
659           TSS_RESULT result = TSS_SUCCESS;
660           BYTE*  ppbHashData;
661           UINT32 i;
662           BYTE  digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, };
663           UINT32 tmp_locAtRelease;
664           TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE
665                                                   | TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR;
666           BYTE tmp_pcr_select[3] = {0, 0, 0};
667           TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select};
668 
669           if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
670                     return TSPERR(TSS_E_INVALID_HANDLE);
671 
672           tspContext = obj->tspContext;
673 
674           if (hPcrComposite) {
675                     if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) {
676                               LogDebug("get_selection error from hReadPcrComposite");
677                               goto out;
678                     }
679 
680                     /* the index should not >= 24, so the sizeofselect should not be >3*/
681                     if (dataLen - sizeof(UINT16) > 3) {
682                               result = TSPERR(TSS_E_BAD_PARAMETER);
683                               goto out;
684                     }
685                     offset = 0;
686                     Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect);
687 
688                     if (pcrSelect.sizeOfSelect != 0) {
689                               if ((result = obj_pcrs_get_digest_at_release(hPcrComposite,
690                                                                                      &dataLen, &ppbHashData))) {
691                                         LogDebug("get_composite error from hReadPcrComposite");
692                                         goto out;
693                               }
694                               memcpy(digAtRelease, ppbHashData, dataLen);
695                               free_tspi(tspContext, ppbHashData);
696                     } else {
697                               pcrSelect.sizeOfSelect = 3;
698                               pcrSelect.pcrSelect = tmp_pcr_select;
699                     }
700 
701                     if (pcrSelect.sizeOfSelect < 3) {
702                               for (i = 0; i < pcrSelect.sizeOfSelect; i++) {
703                                         tmp_pcr_select[i] = pcrSelect.pcrSelect[i];
704                               }
705                               pcrSelect.sizeOfSelect = 3;
706                               pcrSelect.pcrSelect = tmp_pcr_select;
707                     }
708 
709                     if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease)))
710                               goto out;
711                     locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK);
712           }
713 
714           *size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN;
715           *data = calloc_tspi(tspContext, *size);
716           if (*data == NULL) {
717                     LogError("malloc of %u bytes failed.", *size);
718                     result = TSPERR(TSS_E_OUTOFMEMORY);
719                     goto out;
720           }
721 
722           offset = 0;
723           Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect);
724           Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data);
725           Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease);
726 
727 out:
728           obj_list_put(&nvstore_list);
729           return result;
730 }
731 
732 
733