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