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