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