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  * Kent Yoder - updates for new authsession mechanism
11  * (C) International Business Machines Corp. 2007
12  *
13  */
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <inttypes.h>
19 
20 #include "trousers/tss.h"
21 #include "trousers/trousers.h"
22 #include "trousers_types.h"
23 #include "trousers_types.h"
24 #include "spi_utils.h"
25 #include "capabilities.h"
26 #include "tsplog.h"
27 #include "obj.h"
28 #include "authsess.h"
29 
30 TSS_RESULT
Tspi_NV_DefineSpace(TSS_HNVSTORE hNvstore,TSS_HPCRS hReadPcrComposite,TSS_HPCRS hWritePcrComposite)31 Tspi_NV_DefineSpace(TSS_HNVSTORE hNvstore,	/* in */
32 		    TSS_HPCRS hReadPcrComposite,	/* in, may be NULL */
33 		    TSS_HPCRS hWritePcrComposite)	/* in, may be NULL*/
34 {
35 	TSS_HCONTEXT  tspContext;
36 	TSS_HTPM hTpm;
37 	TSS_RESULT result;
38 	UINT32 uiResultLen;
39 	BYTE *pResult;
40 	UINT32 i;
41 
42 	TPM_BOOL defined_index = FALSE;
43 	NV_DATA_PUBLIC nv_data_public;
44 	TSS_BOOL need_authdata = FALSE;
45 	TCPA_DIGEST digest;
46 	BYTE *pReadPCR;
47 	UINT32 pReadPCR_len;
48 	BYTE *pWritePCR;
49 	UINT32 pWritePCR_len;
50 	UINT64 NVPublic_DataSize;
51 	BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE];
52 	Trspi_HashCtx hashCtx;
53 	struct authsess *xsap = NULL;
54 
55 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
56 		return result;
57 
58 	__tspi_memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC));
59 
60 	if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
61 		return result;
62 
63 	if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize)))
64 		return result;
65 
66 	if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes)))
67 		return result;
68 
69 	if ((result = obj_tpm_get(tspContext, &hTpm)))
70 		return result;
71 
72 	if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
73 					    NULL, &uiResultLen, &pResult)))
74 		return result;
75 
76 	for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
77 		if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
78 			defined_index = TRUE;
79 			break;
80 		}
81 	}
82 	free_tspi(tspContext, pResult);
83 
84 	if (defined_index) {
85 		result = TSPERR(TSS_E_NV_AREA_EXIST);
86 		return result;
87 	}
88 
89 	need_authdata = (nv_data_public.permission.attributes
90 			& (TPM_NV_PER_AUTHREAD |TPM_NV_PER_AUTHWRITE)) ? TRUE : FALSE;
91 
92 	nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC;
93 
94 	if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hReadPcrComposite,
95 						      &pReadPCR_len, &pReadPCR)))
96 		return result;
97 
98 	if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hWritePcrComposite,
99 						      &pWritePCR_len, &pWritePCR))) {
100 		free_tspi(tspContext, pReadPCR);
101 		return result;
102 	}
103 
104 	NVPublic_DataSize = 0;
105 	Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData);
106 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData);
107 	Trspi_LoadBlob(&NVPublic_DataSize, pReadPCR_len, NVPublicData, pReadPCR);
108 	Trspi_LoadBlob(&NVPublic_DataSize, pWritePCR_len, NVPublicData, pWritePCR);
109 	Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData);
110 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.permission.attributes, NVPublicData);
111 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData);
112 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData);
113 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData);
114 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData);
115 	free_tspi(tspContext, pReadPCR);
116 	free_tspi(tspContext, pWritePCR);
117 
118 	if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, need_authdata,
119 					 TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap))) {
120 		if (result == TSPERR(TSS_E_TSP_AUTHREQUIRED))
121 			result = TSS_ERROR_CODE(TSS_E_BAD_PARAMETER);
122 		return result;
123 	}
124 
125 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
126 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
127 	result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData);
128 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
129 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
130 		goto error;
131 
132 	if ((result = authsess_xsap_hmac(xsap, &digest)))
133 		goto error;
134 
135 	if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize,
136 								   NVPublicData, xsap->encAuthUse,
137 								   xsap->pAuth)))
138 			goto error;
139 
140 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
141 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
142 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
143 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
144 		goto error;
145 
146 	result = authsess_xsap_verify(xsap, &digest);
147 error:
148 	authsess_free(xsap);
149 
150 	return result;
151 }
152 
153 TSS_RESULT
Tspi_NV_ReleaseSpace(TSS_HNVSTORE hNvstore)154 Tspi_NV_ReleaseSpace(TSS_HNVSTORE hNvstore)	/* in */
155 {
156 	TSS_HCONTEXT  tspContext;
157 	TSS_HTPM hTpm;
158 	TSS_RESULT result;
159 	UINT32 uiResultLen;
160 	BYTE *pResult;
161 	UINT32 i;
162 	TPM_BOOL defined_index = FALSE;
163 	NV_DATA_PUBLIC nv_data_public;
164 	TCPA_DIGEST digest;
165 	BYTE *pPCR;
166 	UINT32 pPCR_len;
167 
168 	UINT64 NVPublic_DataSize;
169 	BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE];
170 	Trspi_HashCtx hashCtx;
171 	struct authsess *xsap = NULL;
172 
173 	__tspi_memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC));
174 
175 	if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
176 		return result;
177 
178 	if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
179 		return result;
180 
181 	if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize)))
182 		return result;
183 
184 	if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes)))
185 		return result;
186 
187 	if ((result = obj_tpm_get(tspContext, &hTpm)))
188 		return result;
189 
190 	if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
191 					    NULL, &uiResultLen, &pResult)))
192 		return result;
193 
194 	for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
195 		if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
196 			defined_index = TRUE;
197 			break;
198 		}
199 	}
200 	free_tspi(tspContext, pResult);
201 
202 	if (!defined_index) {
203 		result = TSPERR(TSS_E_NV_AREA_NOT_EXIST);
204 		return result;
205 	}
206 
207 	nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC;
208 
209 	if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, NULL_HPCRS, &pPCR_len, &pPCR)))
210 		return result;
211 
212 	NVPublic_DataSize = 0;
213 	Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData);
214 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData);
215 	/* load the read pcr short info */
216 	Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR);
217 	/* load the write pcr short info */
218 	Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR);
219 	Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData);
220 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize,
221 			      nv_data_public.permission.attributes, NVPublicData);
222 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData);
223 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData);
224 	Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData);
225 	/*Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData);*/
226 	Trspi_LoadBlob_UINT32(&NVPublic_DataSize, 0, NVPublicData);
227 	free_tspi(tspContext, pPCR);
228 
229 	if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, TSS_AUTH_POLICY_NOT_REQUIRED,
230 					 TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap)))
231 		return result;
232 
233 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
234 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
235 	result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData);
236 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
237 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
238 		goto error;
239 
240 	if ((result = authsess_xsap_hmac(xsap, &digest)))
241 		goto error;
242 
243 	if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize,
244 								   NVPublicData, xsap->encAuthUse,
245 								   xsap->pAuth)))
246 		goto error;
247 
248 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
249 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
250 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
251 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
252 		goto error;
253 
254 	result = authsess_xsap_verify(xsap, &digest);
255 error:
256 	authsess_free(xsap);
257 
258 	return result;
259 }
260 
261 TSS_RESULT
Tspi_NV_WriteValue(TSS_HNVSTORE hNvstore,UINT32 offset,UINT32 ulDataLength,BYTE * rgbDataToWrite)262 Tspi_NV_WriteValue(TSS_HNVSTORE hNvstore,	/* in */
263 		   UINT32 offset,		/* in */
264 		   UINT32 ulDataLength,		/* in */
265 		   BYTE* rgbDataToWrite)	/* in */
266 {
267 	TSS_HCONTEXT  tspContext;
268 	TSS_HTPM hTpm;
269 	TSS_RESULT result;
270 	NV_DATA_PUBLIC nv_data_public;
271 	UINT32 need_authdata = 0;
272 	UINT32  authwrite =0;
273 	TSS_HPOLICY hPolicy;
274 	TPM_AUTH auth;
275 	TCPA_DIGEST digest;
276 	Trspi_HashCtx hashCtx;
277 
278 	if ((ulDataLength != 0) && (rgbDataToWrite == NULL))
279 		return TSPERR(TSS_E_BAD_PARAMETER);
280 
281 	if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
282 		return result;
283 
284 	if ((result = obj_tpm_get(tspContext, &hTpm)))
285 		return result;
286 
287 	if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
288 		return result;
289 
290 	if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy)))
291 		return result;
292 
293 	if (hPolicy) {
294 		if ((result = obj_nvstore_get_permission_from_tpm(hNvstore,
295 					&nv_data_public.permission.attributes)))
296 			return result;
297 
298 		need_authdata = nv_data_public.permission.attributes
299 				& (TPM_NV_PER_AUTHWRITE | TPM_NV_PER_OWNERWRITE);
300 
301 		authwrite = nv_data_public.permission.attributes & TPM_NV_PER_AUTHWRITE;
302 
303 		if (need_authdata) {
304 			if (!authwrite) {
305 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
306 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue);
307 				result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
308 				result |= Trspi_Hash_UINT32(&hashCtx, offset);
309 				result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
310 				result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite);
311 
312 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
313 					return result;
314 
315 				if ((result = secret_PerformAuth_OIAP(hNvstore,
316 								      TPM_ORD_NV_WriteValue,
317 								      hPolicy, FALSE, &digest,
318 								      &auth)))
319 					return result;
320 
321 				if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext,
322 									nv_data_public.nvIndex,
323 									offset, ulDataLength,
324 									rgbDataToWrite, &auth)))
325 					return result;
326 
327 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
328 				result |= Trspi_Hash_UINT32(&hashCtx, result);
329 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue);
330 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
331 					return result;
332 
333 				if ((result = obj_policy_validate_auth_oiap(hPolicy,
334 									    &digest, &auth)))
335 					return result;
336 			} else {
337 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
338 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth);
339 				result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
340 				result |= Trspi_Hash_UINT32(&hashCtx, offset);
341 				result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
342 				result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite);
343 
344 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
345 					return result;
346 
347 				if ((result = secret_PerformAuth_OIAP(hNvstore,
348 								      TPM_ORD_NV_WriteValueAuth,
349 								      hPolicy, FALSE, &digest,
350 								      &auth)))
351 					return result;
352 
353 				if ((result = TCS_API(tspContext)->NV_WriteValueAuth(tspContext,
354 									nv_data_public.nvIndex,
355 									offset, ulDataLength,
356 									rgbDataToWrite, &auth)))
357 					return result;
358 
359 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
360 				result |= Trspi_Hash_UINT32(&hashCtx, result);
361 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth);
362 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
363 					return result;
364 
365 				if ((result = obj_policy_validate_auth_oiap(hPolicy,
366 									    &digest, &auth)))
367 					return result;
368 			}
369 		} else {
370 			if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext,
371 									 nv_data_public.nvIndex,
372 									 offset, ulDataLength,
373 									 rgbDataToWrite, NULL)))
374 				return result;
375 		}
376 	} else {
377 		LogDebug("no policy, so noauthentication");
378 		if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext, nv_data_public.nvIndex,
379 								 offset, ulDataLength,
380 								 rgbDataToWrite, NULL)))
381 			return result;
382 	}
383 
384 	return result;
385 }
386 
387 TSS_RESULT
Tspi_NV_ReadValue(TSS_HNVSTORE hNvstore,UINT32 offset,UINT32 * ulDataLength,BYTE ** rgbDataRead)388 Tspi_NV_ReadValue(TSS_HNVSTORE hNvstore,	/* in */
389 		  UINT32 offset,		/* in */
390 		  UINT32* ulDataLength,		/* in, out */
391 		  BYTE** rgbDataRead)		/* out */
392 {
393 	TSS_HCONTEXT  tspContext;
394 	TSS_HTPM hTpm;
395 	TSS_RESULT result;
396 	NV_DATA_PUBLIC nv_data_public;
397 	UINT32 need_authdata = 0;
398 	UINT32  authread =0;
399 	TSS_HPOLICY hPolicy;
400 
401 	TPM_AUTH auth;
402 	TCPA_DIGEST digest;
403 	Trspi_HashCtx hashCtx;
404 
405 	if (ulDataLength == NULL || rgbDataRead == NULL)
406 		return TSPERR(TSS_E_BAD_PARAMETER);
407 
408 	if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
409 		return result;
410 
411 	if ((result = obj_tpm_get(tspContext, &hTpm)))
412 		return result;
413 
414 	if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
415 		return result;
416 
417 	if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy)))
418 		return result;
419 
420 	if (hPolicy) {/*if the policy secret is set*/
421 		if ((result = obj_nvstore_get_permission_from_tpm(hNvstore,
422 							 &nv_data_public.permission.attributes)))
423 			return result;
424 
425 		need_authdata = nv_data_public.permission.attributes
426 				& (TPM_NV_PER_AUTHREAD | TPM_NV_PER_OWNERREAD);
427 
428 		authread = nv_data_public.permission.attributes & TPM_NV_PER_AUTHREAD;
429 
430 		if (need_authdata) {
431 			if (!authread) {
432 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
433 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue);
434 				result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
435 				result |= Trspi_Hash_UINT32(&hashCtx, offset);
436 				result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
437 
438 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
439 					return result;
440 
441 				if ((result = secret_PerformAuth_OIAP(hNvstore,
442 								      TPM_ORD_NV_ReadValue,
443 								      hPolicy, FALSE, &digest,
444 								      &auth)))
445 					return result;
446 
447 				if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext,
448 									nv_data_public.nvIndex,
449 									offset, ulDataLength,
450 									&auth, rgbDataRead)))
451 					return result;
452 
453 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
454 				result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
455 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue);
456 				result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
457 				result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead);
458 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
459 					return result;
460 
461 				if ((result = obj_policy_validate_auth_oiap(hPolicy,
462 									    &digest, &auth)))
463 					return result;
464 			} else {
465 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
466 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth);
467 				result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
468 				result |= Trspi_Hash_UINT32(&hashCtx, offset);
469 				result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
470 
471 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
472 					return result;
473 
474 				if ((result = secret_PerformAuth_OIAP(hNvstore,
475 								      TPM_ORD_NV_ReadValueAuth,
476 								      hPolicy, FALSE, &digest,
477 								      &auth)))
478 					return result;
479 
480 				if ((result = TCS_API(tspContext)->NV_ReadValueAuth(tspContext,
481 									nv_data_public.nvIndex,
482 									offset, ulDataLength,
483 									&auth, rgbDataRead)))
484 					return result;
485 
486 				result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
487 				result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
488 				result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth);
489 				result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
490 				result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead);
491 				if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
492 					return result;
493 
494 				if ((result = obj_policy_validate_auth_oiap(hPolicy,
495 									    &digest, &auth)))
496 					return result;
497 			}
498 		} else {
499 			if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext,
500 									nv_data_public.nvIndex,
501 									offset, ulDataLength, NULL,
502 									rgbDataRead)))
503 				return result;
504 		}
505 	} else {
506 		if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext, nv_data_public.nvIndex,
507 								offset, ulDataLength, NULL,
508 								rgbDataRead)))
509 			return result;
510 	}
511 
512 	return result;
513 }
514