Home | History | Annotate | Line # | Download | only in tspi
      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 (at) intel.com Rossey.liu (at) 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
     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
    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
    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
    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