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