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 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