1 2/* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2007 8 * 9 */ 10 11 12#include <stdlib.h> 13#include <stdio.h> 14#include <string.h> 15#include <time.h> 16#include <errno.h> 17#include <assert.h> 18 19#include "trousers/tss.h" 20#include "trousers/trousers.h" 21#include "trousers_types.h" 22#include "tcs_tsp.h" 23#include "spi_utils.h" 24#include "capabilities.h" 25#include "tsplog.h" 26#include "obj.h" 27#include "authsess.h" 28 29 30TSS_RESULT 31secret_PerformAuth_OIAP(TSS_HOBJECT hAuthorizedObject, 32 UINT32 ulPendingFn, 33 TSS_HPOLICY hPolicy, 34 TSS_BOOL cas, /* continue auth session */ 35 TCPA_DIGEST *hashDigest, 36 TPM_AUTH *auth) 37{ 38 TSS_RESULT result; 39 TSS_BOOL bExpired; 40 UINT32 mode; 41 TCPA_SECRET secret; 42 TSS_HCONTEXT tspContext; 43 TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack 44 TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack 45 46 /* This validates that the secret can be used */ 47 if ((result = obj_policy_has_expired(hPolicy, &bExpired))) 48 return result; 49 50 if (bExpired == TRUE) 51 return TSPERR(TSS_E_INVALID_OBJ_ACCESS); 52 53 if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) 54 return result; 55 56 if ((result = obj_policy_get_mode(hPolicy, &mode))) 57 return result; 58 59 if ((result = Init_AuthNonce(tspContext, cas, auth))) 60 return result; 61 62 /* XXX hack for opening a transport session */ 63 if (cas) { 64 OIAP = RPC_OIAP; 65 TerminateHandle = RPC_TerminateHandle; 66 } else { 67 OIAP = TCS_API(tspContext)->OIAP; 68 TerminateHandle = TCS_API(tspContext)->TerminateHandle; 69 } 70 71 /* added retry logic */ 72 if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) { 73 if (result == TCPA_E_RESOURCES) { 74 int retry = 0; 75 do { 76 /* POSIX sleep time, { secs, nanosecs } */ 77 struct timespec t = { 0, AUTH_RETRY_NANOSECS }; 78 79 nanosleep(&t, NULL); 80 81 result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven); 82 } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); 83 } 84 85 if (result) 86 return result; 87 } 88 89 switch (mode) { 90 case TSS_SECRET_MODE_CALLBACK: 91 result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, 92 TRUE, ulPendingFn, 93 auth->fContinueAuthSession, 94 20, 95 auth->NonceEven.nonce, 96 auth->NonceOdd.nonce, 97 NULL, NULL, 20, 98 hashDigest->digest, 99 (BYTE *)&auth->HMAC); 100 break; 101 case TSS_SECRET_MODE_SHA1: 102 case TSS_SECRET_MODE_PLAIN: 103 case TSS_SECRET_MODE_POPUP: 104 if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, 105 &secret))) 106 break; 107 108 HMAC_Auth(secret.authdata, hashDigest->digest, auth); 109 break; 110 case TSS_SECRET_MODE_NONE: 111 /* fall through */ 112 default: 113 result = TSPERR(TSS_E_POLICY_NO_SECRET); 114 break; 115 } 116 117 if (result) { 118 TerminateHandle(tspContext, auth->AuthHandle); 119 return result; 120 } 121 122 return obj_policy_dec_counter(hPolicy); 123} 124#if 0 125TSS_RESULT 126secret_PerformXOR_OSAP(TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, 127 TSS_HPOLICY hMigrationPolicy, TSS_HOBJECT hOSAPObject, 128 UINT16 osapType, UINT32 osapData, 129 TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, 130 BYTE *sharedSecret, TPM_AUTH * auth, TCPA_NONCE * nonceEvenOSAP) 131{ 132 TSS_BOOL bExpired; 133 TCPA_SECRET keySecret; 134 TCPA_SECRET usageSecret; 135 TCPA_SECRET migSecret = { { 0, } }; 136 UINT32 keyMode, usageMode, migMode = 0; 137 TSS_RESULT result; 138 TSS_HCONTEXT tspContext; 139 140 141 if ((result = obj_policy_has_expired(hPolicy, &bExpired))) 142 return result; 143 144 if (bExpired == TRUE) 145 return TSPERR(TSS_E_INVALID_OBJ_ACCESS); 146 147 if ((result = obj_policy_has_expired(hUsagePolicy, &bExpired))) 148 return result; 149 150 if (bExpired == TRUE) 151 return TSPERR(TSS_E_INVALID_OBJ_ACCESS); 152 153 if (hMigrationPolicy) { 154 if ((result = obj_policy_has_expired(hMigrationPolicy, &bExpired))) 155 return result; 156 157 if (bExpired == TRUE) 158 return TSPERR(TSS_E_INVALID_OBJ_ACCESS); 159 160 if ((result = obj_policy_get_mode(hMigrationPolicy, &migMode))) 161 return result; 162 } 163 164 if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) 165 return result; 166 167 if ((result = obj_policy_get_mode(hPolicy, &keyMode))) 168 return result; 169 170 if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) 171 return result; 172 173 if (keyMode == TSS_SECRET_MODE_CALLBACK || 174 usageMode == TSS_SECRET_MODE_CALLBACK || 175 (hMigrationPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { 176 if (keyMode != TSS_SECRET_MODE_CALLBACK || 177 usageMode != TSS_SECRET_MODE_CALLBACK || 178 (hMigrationPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) 179 return TSPERR(TSS_E_BAD_PARAMETER); 180 } 181 182 if (keyMode != TSS_SECRET_MODE_CALLBACK) { 183 if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, &keySecret))) 184 return result; 185 186 if ((result = obj_policy_get_secret(hUsagePolicy, TR_SECRET_CTX_NEW, &usageSecret))) 187 return result; 188 189 if (hMigrationPolicy) { 190 if ((result = obj_policy_get_secret(hMigrationPolicy, TR_SECRET_CTX_NEW, 191 &migSecret))) 192 return result; 193 } 194 195 if ((result = OSAP_Calc(tspContext, osapType, osapData, 196 keySecret.authdata, usageSecret.authdata, 197 migSecret.authdata, encAuthUsage, 198 encAuthMig, sharedSecret, auth))) 199 return result; 200 } else { 201 /* If the secret mode is NONE here, we don't return an error. This is 202 * because there are commands such as CreateKey, which require an auth 203 * session even when creating no-auth keys. A secret of all 0's will be 204 * used in this case. */ 205 if ((result = TCS_API(tspContext)->OSAP(tspContext, osapType, osapData, 206 &auth->NonceOdd, &auth->AuthHandle, 207 &auth->NonceEven, nonceEvenOSAP))) 208 return result; 209 210 if ((result = obj_policy_do_xor(hPolicy, hOSAPObject, 211 hPolicy, TRUE, 20, 212 auth->NonceEven.nonce, NULL, 213 nonceEvenOSAP->nonce, 214 auth->NonceOdd.nonce, 20, 215 encAuthUsage->authdata, 216 encAuthMig->authdata))) { 217 TCS_API(tspContext)->TerminateHandle(tspContext, auth->AuthHandle); 218 return result; 219 } 220 } 221 222 return TSS_SUCCESS; 223} 224 225TSS_RESULT 226secret_PerformAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn, 227 TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, 228 TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20], 229 TPM_AUTH *auth, BYTE *hashDigest, 230 TCPA_NONCE *nonceEvenOSAP) 231{ 232 TSS_RESULT result; 233 UINT32 keyMode, usageMode, migMode = 0; 234 235 if ((result = obj_policy_get_mode(hPolicy, &keyMode))) 236 return result; 237 238 if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) 239 return result; 240 241 if (hMigPolicy) { 242 if ((result = obj_policy_get_mode(hMigPolicy, &migMode))) 243 return result; 244 } 245 246 /* --- If any of them is a callback */ 247 if (keyMode == TSS_SECRET_MODE_CALLBACK || 248 usageMode == TSS_SECRET_MODE_CALLBACK || 249 (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { 250 /* --- And they're not all callback */ 251 if (keyMode != TSS_SECRET_MODE_CALLBACK || 252 usageMode != TSS_SECRET_MODE_CALLBACK || 253 (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) 254 return TSPERR(TSS_E_BAD_PARAMETER); 255 } 256 257 if (keyMode == TSS_SECRET_MODE_CALLBACK) { 258 if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, 259 TRUE, ulPendingFn, 260 auth->fContinueAuthSession, 261 20, 262 auth->NonceEven.nonce, 263 NULL, 264 nonceEvenOSAP->nonce, 265 auth->NonceOdd.nonce, 20, 266 hashDigest, 267 (BYTE *)&auth->HMAC))) 268 return result; 269 } else { 270 HMAC_Auth(sharedSecret, hashDigest, auth); 271 } 272 273 if ((result = obj_policy_dec_counter(hPolicy))) 274 return result; 275 276 if ((result = obj_policy_dec_counter(hUsagePolicy))) 277 return result; 278 279 if (hMigPolicy) { 280 if ((result = obj_policy_dec_counter(hMigPolicy))) 281 return result; 282 } 283 284 return TSS_SUCCESS; 285} 286 287TSS_RESULT 288secret_ValidateAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn, 289 TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, 290 TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20], 291 TPM_AUTH *auth, BYTE *hashDigest, 292 TCPA_NONCE *nonceEvenOSAP) 293{ 294 TSS_RESULT result; 295 UINT32 keyMode, usageMode, migMode = 0; 296 297 if ((result = obj_policy_get_mode(hPolicy, &keyMode))) 298 return result; 299 300 if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) 301 return result; 302 303 if (hMigPolicy) { 304 if ((result = obj_policy_get_mode(hMigPolicy, &migMode))) 305 return result; 306 } 307 308 /* --- If any of them is a callback */ 309 if (keyMode == TSS_SECRET_MODE_CALLBACK || 310 usageMode == TSS_SECRET_MODE_CALLBACK || 311 (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { 312 /* --- And they're not all callback */ 313 if (keyMode != TSS_SECRET_MODE_CALLBACK || 314 usageMode != TSS_SECRET_MODE_CALLBACK || 315 (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) 316 return TSPERR(TSS_E_BAD_PARAMETER); 317 } 318 319 if (keyMode != TSS_SECRET_MODE_CALLBACK) { 320 if (validateReturnAuth(sharedSecret, hashDigest, auth)) 321 return TSPERR(TSS_E_TSP_AUTHFAIL); 322 } else { 323 if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, 324 FALSE, ulPendingFn, 325 auth->fContinueAuthSession, 326 20, 327 auth->NonceEven.nonce, 328 NULL, 329 nonceEvenOSAP->nonce, 330 auth->NonceOdd.nonce, 20, 331 hashDigest, 332 (BYTE *)&auth->HMAC))) 333 return result; 334 } 335 336 return TSS_SUCCESS; 337} 338#endif 339TSS_RESULT 340Init_AuthNonce(TSS_HCONTEXT tspContext, TSS_BOOL cas, TPM_AUTH * auth) 341{ 342 TSS_RESULT result; 343 344 auth->fContinueAuthSession = cas; 345 if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), 346 (BYTE **)auth->NonceOdd.nonce))) { 347 LogError("Failed creating random nonce"); 348 return TSPERR(TSS_E_INTERNAL_ERROR); 349 } 350 351 return TSS_SUCCESS; 352} 353 354TSS_BOOL 355validateReturnAuth(BYTE *secret, BYTE *hash, TPM_AUTH *auth) 356{ 357 BYTE digest[20]; 358 /* auth is expected to have both nonces and the digest from the TPM */ 359 memcpy(digest, &auth->HMAC, 20); 360 HMAC_Auth(secret, hash, auth); 361 362 return ((TSS_BOOL) (memcmp(digest, &auth->HMAC, 20) != 0)); 363} 364 365void 366HMAC_Auth(BYTE * secret, BYTE * Digest, TPM_AUTH * auth) 367{ 368 UINT64 offset; 369 BYTE Blob[61]; 370 371 offset = 0; 372 Trspi_LoadBlob(&offset, 20, Blob, Digest); 373 Trspi_LoadBlob(&offset, 20, Blob, auth->NonceEven.nonce); 374 Trspi_LoadBlob(&offset, 20, Blob, auth->NonceOdd.nonce); 375 Blob[offset++] = auth->fContinueAuthSession; 376 377 Trspi_HMAC(TSS_HASH_SHA1, 20, secret, offset, Blob, (BYTE *)&auth->HMAC); 378} 379 380TSS_RESULT 381OSAP_Calc(TSS_HCONTEXT tspContext, UINT16 EntityType, UINT32 EntityValue, 382 BYTE * authSecret, BYTE * usageSecret, BYTE * migSecret, 383 TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, 384 BYTE * sharedSecret, TPM_AUTH * auth) 385{ 386 TSS_RESULT rc; 387 TCPA_NONCE nonceEvenOSAP; 388 UINT64 offset; 389 BYTE hmacBlob[0x200]; 390 BYTE hashBlob[0x200]; 391 BYTE xorUsageAuth[20]; 392 BYTE xorMigAuth[20]; 393 UINT32 i; 394 395 if ((rc = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), 396 (BYTE **)auth->NonceOdd.nonce))) { 397 LogError("Failed creating random nonce"); 398 return TSPERR(TSS_E_INTERNAL_ERROR); 399 } 400 auth->fContinueAuthSession = 0x00; 401 402 if ((rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, &auth->NonceOdd, 403 &auth->AuthHandle, &auth->NonceEven, &nonceEvenOSAP))) { 404 if (rc == TCPA_E_RESOURCES) { 405 int retry = 0; 406 do { 407 /* POSIX sleep time, { secs, nanosecs } */ 408 struct timespec t = { 0, AUTH_RETRY_NANOSECS }; 409 410 nanosleep(&t, NULL); 411 412 rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, 413 &auth->NonceOdd, &auth->AuthHandle, 414 &auth->NonceEven, &nonceEvenOSAP); 415 } while (rc == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); 416 } 417 418 if (rc) 419 return rc; 420 } 421 422 offset = 0; 423 Trspi_LoadBlob(&offset, 20, hmacBlob, nonceEvenOSAP.nonce); 424 Trspi_LoadBlob(&offset, 20, hmacBlob, auth->NonceOdd.nonce); 425 426 Trspi_HMAC(TSS_HASH_SHA1, 20, authSecret, offset, hmacBlob, sharedSecret); 427 428 offset = 0; 429 Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); 430 Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceEven.nonce); 431 432 if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorUsageAuth))) 433 return rc; 434 435 offset = 0; 436 Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); 437 Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceOdd.nonce); 438 if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorMigAuth))) 439 return rc; 440 441 for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) 442 encAuthUsage->authdata[i] = usageSecret[i] ^ xorUsageAuth[i]; 443 for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) 444 encAuthMig->authdata[i] = migSecret[i] ^ xorMigAuth[i]; 445 446 return TSS_SUCCESS; 447} 448 449TSS_RESULT 450obj_policy_validate_auth_oiap(TSS_HPOLICY hPolicy, TCPA_DIGEST *hashDigest, TPM_AUTH *auth) 451{ 452 TSS_RESULT result = TSS_SUCCESS; 453 struct tsp_object *obj; 454 struct tr_policy_obj *policy; 455 BYTE wellKnown[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; 456 457 if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) 458 return TSPERR(TSS_E_INVALID_HANDLE); 459 460 policy = (struct tr_policy_obj *)obj->data; 461 462 switch (policy->SecretMode) { 463 case TSS_SECRET_MODE_CALLBACK: 464 result = policy->Tspicb_CallbackHMACAuth( 465 policy->hmacAppData, 466 hPolicy, 467 0, 468 auth->fContinueAuthSession, 469 FALSE, 470 20, 471 auth->NonceEven.nonce, 472 auth->NonceOdd.nonce, 473 NULL, NULL, 20, 474 hashDigest->digest, 475 (BYTE *)&auth->HMAC); 476 break; 477 case TSS_SECRET_MODE_SHA1: 478 case TSS_SECRET_MODE_PLAIN: 479 case TSS_SECRET_MODE_POPUP: 480 if (validateReturnAuth(policy->Secret, hashDigest->digest, auth)) 481 result = TSPERR(TSS_E_TSP_AUTHFAIL); 482 break; 483 case TSS_SECRET_MODE_NONE: 484 if (validateReturnAuth(wellKnown, hashDigest->digest, auth)) 485 result = TSPERR(TSS_E_TSP_AUTHFAIL); 486 break; 487 default: 488 result = TSPERR(TSS_E_POLICY_NO_SECRET); 489 break; 490 } 491 492 obj_list_put(&policy_list); 493 494 return result; 495} 496 497#if 0 498TSS_RESULT 499authsess_oiap_get(TSS_HOBJECT obj, TPM_COMMAND_CODE ord, TPM_DIGEST *digest, TPM_AUTH *auth) 500{ 501 TSS_RESULT result = TSS_SUCCESS; 502 TSS_BOOL bExpired; 503 UINT32 mode; 504 TPM_SECRET secret; 505 TSS_HCONTEXT tspContext; 506 TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack 507 TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack 508 509 510 if (obj_is_tpm(obj)) 511 result = obj_tpm_get_tsp_context(obj, hContext); 512 else if (obj_is_rsakey(obj)) 513 result = obj_rsakey_get_tsp_context(obj, hContext); 514 else if (obj_is_encdata(obj)) 515 result = obj_encdata_get_tsp_context(obj, hContext); 516 else if (obj_is_nvstore(obj)) 517 result = obj_nvstore_get_tsp_context(obj, hContext); 518 else 519 result = TSPERR(TSS_E_INVALID_HANDLE); 520 521#if 0 522 /* This validates that the secret can be used */ 523 if ((result = obj_policy_has_expired(hPolicy, &bExpired))) 524 return result; 525 526 if (bExpired == TRUE) 527 return TSPERR(TSS_E_INVALID_OBJ_ACCESS); 528 529 if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) 530 return result; 531 532 if ((result = obj_policy_get_mode(hPolicy, &mode))) 533 return result; 534#else 535 if ((result = obj_policy_get_authsess_params())) 536 return result; 537#endif 538 if ((result = Init_AuthNonce(tspContext, cas, auth))) 539 return result; 540 541 /* XXX hack for opening a transport session */ 542 if (cas) { 543 OIAP = RPC_OIAP; 544 TerminateHandle = RPC_TerminateHandle; 545 } else { 546 OIAP = TCS_API(tspContext)->OIAP; 547 TerminateHandle = TCS_API(tspContext)->TerminateHandle; 548 } 549 550 /* added retry logic */ 551 if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) { 552 if (result == TCPA_E_RESOURCES) { 553 int retry = 0; 554 do { 555 /* POSIX sleep time, { secs, nanosecs } */ 556 struct timespec t = { 0, AUTH_RETRY_NANOSECS }; 557 558 nanosleep(&t, NULL); 559 560 result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven); 561 } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); 562 } 563 564 if (result) 565 return result; 566 } 567 568 switch (mode) { 569 case TSS_SECRET_MODE_CALLBACK: 570 result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, 571 TRUE, ulPendingFn, 572 auth->fContinueAuthSession, 573 20, 574 auth->NonceEven.nonce, 575 auth->NonceOdd.nonce, 576 NULL, NULL, 20, 577 hashDigest->digest, 578 (BYTE *)&auth->HMAC); 579 break; 580 case TSS_SECRET_MODE_SHA1: 581 case TSS_SECRET_MODE_PLAIN: 582 case TSS_SECRET_MODE_POPUP: 583 if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, 584 &secret))) 585 break; 586 587 HMAC_Auth(secret.authdata, hashDigest->digest, auth); 588 break; 589 case TSS_SECRET_MODE_NONE: 590 /* fall through */ 591 default: 592 result = TSPERR(TSS_E_POLICY_NO_SECRET); 593 break; 594 } 595 596 if (result) { 597 TerminateHandle(tspContext, auth->AuthHandle); 598 return result; 599 } 600 601 return obj_policy_dec_counter(hPolicy); 602} 603 604TSS_RESULT 605authsess_oiap_put(TPM_AUTH *auth) 606{ 607} 608#endif 609 610#ifdef TSS_BUILD_DELEGATION 611TSS_RESULT 612authsess_do_dsap(struct authsess *sess) 613{ 614 TSS_RESULT result; 615 616 if ((result = TCS_API(sess->tspContext)->DSAP(sess->tspContext, sess->entity_type, 617 sess->obj_parent, &sess->nonceOddxSAP, 618 sess->entityValueSize, sess->entityValue, 619 &sess->pAuth->AuthHandle, 620 &sess->pAuth->NonceEven, 621 &sess->nonceEvenxSAP))) { 622 if (result == TCPA_E_RESOURCES) { 623 int retry = 0; 624 do { 625 /* POSIX sleep time, { secs, nanosecs } */ 626 struct timespec t = { 0, AUTH_RETRY_NANOSECS }; 627 628 nanosleep(&t, NULL); 629 630 result = TCS_API(sess->tspContext)->DSAP(sess->tspContext, 631 sess->entity_type, 632 sess->obj_parent, 633 &sess->nonceOddxSAP, 634 sess->entityValueSize, 635 sess->entityValue, 636 &sess->pAuth->AuthHandle, 637 &sess->pAuth->NonceEven, 638 &sess->nonceEvenxSAP); 639 } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); 640 } 641 } 642 643 return result; 644} 645#endif 646 647TSS_RESULT 648authsess_do_osap(struct authsess *sess) 649{ 650 TSS_RESULT result; 651 652 if ((result = TCS_API(sess->tspContext)->OSAP(sess->tspContext, sess->entity_type, 653 sess->obj_parent, &sess->nonceOddxSAP, 654 &sess->pAuth->AuthHandle, 655 &sess->pAuth->NonceEven, 656 &sess->nonceEvenxSAP))) { 657 if (result == TCPA_E_RESOURCES) { 658 int retry = 0; 659 do { 660 /* POSIX sleep time, { secs, nanosecs } */ 661 struct timespec t = { 0, AUTH_RETRY_NANOSECS }; 662 663 nanosleep(&t, NULL); 664 665 result = TCS_API(sess->tspContext)->OSAP(sess->tspContext, 666 sess->entity_type, 667 sess->obj_parent, 668 &sess->nonceOddxSAP, 669 &sess->pAuth->AuthHandle, 670 &sess->pAuth->NonceEven, 671 &sess->nonceEvenxSAP); 672 } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); 673 } 674 } 675 676 return result; 677} 678 679TSS_RESULT 680authsess_callback_xor(PVOID lpAppData, 681 TSS_HOBJECT hOSAPObject, 682 TSS_HOBJECT hObject, 683 TSS_FLAG PurposeSecret, 684 UINT32 ulSizeNonces, 685 BYTE *rgbNonceEven, 686 BYTE *rgbNonceOdd, 687 BYTE *rgbNonceEvenOSAP, 688 BYTE *rgbNonceOddOSAP, 689 UINT32 ulSizeEncAuth, 690 BYTE *rgbEncAuthUsage, 691 BYTE *rgbEncAuthMigration) 692{ 693 TSS_RESULT result; 694 BYTE xorUseAuth[sizeof(TPM_DIGEST)]; 695 BYTE xorMigAuth[sizeof(TPM_DIGEST)]; 696 Trspi_HashCtx hashCtx; 697 UINT32 i; 698 struct authsess *sess = (struct authsess *)lpAppData; 699 700 /* sess->sharedSecret was calculated in authsess_xsap_init */ 701 702 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 703 result |= Trspi_Hash_SECRET(&hashCtx, sess->sharedSecret.digest); 704 result |= Trspi_Hash_NONCE(&hashCtx, rgbNonceEven); 705 if ((result |= Trspi_HashFinal(&hashCtx, xorUseAuth))) 706 return result; 707 708 for (i = 0; i < ulSizeEncAuth; i++) 709 rgbEncAuthUsage[i] ^= xorUseAuth[i]; 710 711 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 712 result |= Trspi_Hash_SECRET(&hashCtx, sess->sharedSecret.digest); 713 result |= Trspi_Hash_NONCE(&hashCtx, rgbNonceOdd); 714 if ((result |= Trspi_HashFinal(&hashCtx, xorMigAuth))) 715 return result; 716 717 for (i = 0; i < ulSizeEncAuth; i++) 718 rgbEncAuthMigration[i] ^= xorMigAuth[i]; 719 720 return TSS_SUCCESS; 721} 722 723TSS_RESULT 724authsess_callback_hmac(PVOID lpAppData, 725 TSS_HOBJECT hAuthorizedObject, 726 TSS_BOOL ReturnOrVerify, 727 UINT32 ulPendingFunction, 728 TSS_BOOL ContinueUse, 729 UINT32 ulSizeNonces, 730 BYTE *rgbNonceEven, 731 BYTE *rgbNonceOdd, 732 BYTE *rgbNonceEvenOSAP, 733 BYTE *rgbNonceOddOSAP, 734 UINT32 ulSizeDigestHmac, 735 BYTE *rgbParamDigest, 736 BYTE *rgbHmacData) 737{ 738 struct authsess *sess = (struct authsess *)lpAppData; 739 TSS_RESULT result = TSS_SUCCESS; 740 UINT64 offset; 741 BYTE Blob[61]; 742 743 offset = 0; 744 Trspi_LoadBlob(&offset, ulSizeDigestHmac, Blob, rgbParamDigest); 745 Trspi_LoadBlob(&offset, ulSizeNonces, Blob, rgbNonceEven); 746 Trspi_LoadBlob(&offset, ulSizeNonces, Blob, rgbNonceOdd); 747 Blob[offset++] = ContinueUse; 748 749 if (ReturnOrVerify) { 750 Trspi_HMAC(TSS_HASH_SHA1, ulSizeDigestHmac, sess->sharedSecret.digest, offset, Blob, 751 rgbHmacData); 752 } else { 753 TPM_HMAC hmacVerify; 754 755 Trspi_HMAC(TSS_HASH_SHA1, ulSizeDigestHmac, sess->sharedSecret.digest, offset, Blob, 756 hmacVerify.digest); 757 result = memcmp(rgbHmacData, hmacVerify.digest, ulSizeDigestHmac); 758 if (result) 759 result = TPM_E_AUTHFAIL; 760 } 761 762 return result; 763} 764 765/* Create an OSAP session. @requirements is used in different ways depending on the command to 766 * indicate whether we should require a policy or auth value */ 767TSS_RESULT 768authsess_xsap_init(TSS_HCONTEXT tspContext, 769 TSS_HOBJECT obj_parent, 770 TSS_HOBJECT obj_child, 771 TSS_BOOL requirements, 772 TPM_COMMAND_CODE command, 773 TPM_ENTITY_TYPE entity_type, 774 struct authsess **xsess) 775{ 776 TSS_RESULT result; 777 TSS_BOOL authdatausage = FALSE, req_auth = TRUE, get_child_auth = TRUE, secret_set = FALSE; 778 BYTE hmacBlob[2 * sizeof(TPM_DIGEST)]; 779 UINT64 offset; 780 TSS_BOOL new_secret = TR_SECRET_CTX_NOT_NEW; 781 struct authsess *sess; 782 783 if ((sess = calloc(1, sizeof(struct authsess))) == NULL) { 784 LogError("malloc of %zd bytes failed", sizeof(struct authsess)); 785 return TSPERR(TSS_E_OUTOFMEMORY); 786 } 787 788 switch (command) { 789 /* Parent is Key for the cases below */ 790 case TPM_ORD_Delegate_CreateKeyDelegation: 791 case TPM_ORD_CreateWrapKey: 792 case TPM_ORD_CMK_CreateKey: 793 case TPM_ORD_Seal: 794 case TPM_ORD_Sealx: 795 case TPM_ORD_Unseal: 796 case TPM_ORD_ChangeAuth: 797 if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, 798 &sess->hUsageParent, NULL))) 799 goto error; 800 break; 801 /* Parent is TPM for the cases below */ 802 case TPM_ORD_Delegate_CreateOwnerDelegation: 803 req_auth = FALSE; 804 /* fall through */ 805 case TPM_ORD_MakeIdentity: 806 case TPM_ORD_NV_DefineSpace: 807 if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, 808 &sess->hUsageParent))) 809 goto error; 810 break; 811 case TPM_ORD_ChangeAuthOwner: 812 /* Special case, ChangeAuthOwner is used to change Owner and SRK auth */ 813 if (obj_is_rsakey(obj_parent)) { 814 if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, 815 &sess->hUsageParent, NULL))) 816 goto error; 817 } else { 818 if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, 819 &sess->hUsageParent))) 820 goto error; 821 } 822 break; 823 default: 824 result = TSPERR(TSS_E_INTERNAL_ERROR); 825 goto error; 826 } 827 828 if (requirements && !sess->hUsageParent) { 829 result = TSPERR(TSS_E_TSP_AUTHREQUIRED); 830 goto error; 831 } 832 833 if (sess->hUsageParent) { 834 /* These are trousers callback functions which will be used to process the auth 835 * session. If the policy type is callback for hUsageParent, they will be 836 * overwritten by the application defined callback functions in the policy */ 837 sess->cb_xor.callback = authsess_callback_xor; 838 sess->cb_xor.appData = (PVOID)sess; 839 sess->cb_hmac.callback = authsess_callback_hmac; 840 sess->cb_hmac.appData = (PVOID)sess; 841 842 /* XXX the parent object doesn't always hold the callbacks */ 843 if ((result = obj_policy_get_xsap_params(sess->hUsageParent, command, 844 &sess->entity_type, &sess->entityValueSize, 845 &sess->entityValue, 846 sess->parentSecret.authdata, &sess->cb_xor, 847 &sess->cb_hmac, NULL, &sess->parentMode, 848 new_secret))) 849 goto error; 850 } else 851 sess->parentMode = TSS_SECRET_MODE_NONE; 852 853 switch (command) { 854 /* Child is a Key object */ 855 case TPM_ORD_CreateWrapKey: 856 case TPM_ORD_CMK_CreateKey: 857 if ((result = obj_rsakey_get_policies(obj_child, &sess->hUsageChild, 858 &sess->hMigChild, &authdatausage))) 859 goto error; 860 861 if (authdatausage && !sess->hUsageChild) { 862 result = TSPERR(TSS_E_TSP_AUTHREQUIRED); 863 goto error; 864 } 865 866 if (obj_rsakey_is_migratable(obj_child)) { 867 if (!sess->hMigChild) { 868 result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY); 869 goto error; 870 } 871 872 if ((result = obj_policy_get_xsap_params(sess->hMigChild, 0, NULL, NULL, 873 NULL, sess->encAuthMig.authdata, 874 NULL, NULL, NULL, &sess->mMode, 875 new_secret))) 876 goto error; 877 } 878 879 if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) 880 goto error; 881 break; 882 /* Child is an Encdata object */ 883 case TPM_ORD_Unseal: 884#ifdef TSS_BUILD_SEALX 885 case TPM_ORD_Sealx: 886 /* These may be overwritten down below, when obj_policy_get_xsap_params is called 887 * on the child usage policy */ 888 sess->cb_sealx.callback = sealx_mask_cb; 889 sess->cb_sealx.appData = (PVOID)sess; 890 /* fall through */ 891#endif 892 case TPM_ORD_Seal: 893 if ((result = obj_encdata_get_policy(obj_child, TSS_POLICY_USAGE, 894 &sess->hUsageChild))) 895 goto error; 896 897 if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) 898 goto error; 899 break; 900#ifdef TSS_BUILD_NV 901 /* Child is an NV object */ 902 case TPM_ORD_NV_DefineSpace: 903 /* The requirements variable tells us whether nv object auth is required */ 904 req_auth = requirements; 905 906 if (req_auth) { 907 if (sess->parentMode == TSS_SECRET_MODE_NONE) { 908 result = TSPERR(TSS_E_TSP_AUTHREQUIRED); 909 goto error; 910 } 911 912 if ((result = obj_nvstore_get_policy(obj_child, TSS_POLICY_USAGE, 913 &sess->hUsageChild))) 914 goto error; 915 916 /* According to the spec, we must fall back on the TSP context's policy for 917 * auth if none is set in the NV object */ 918 if (!sess->hUsageChild) { 919 if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, 920 &sess->hUsageChild))) 921 goto error; 922 } 923 924 if ((result = obj_policy_is_secret_set(sess->hUsageChild, &secret_set))) 925 goto error; 926 927 if (!secret_set) { 928 result = TSPERR(TSS_E_TSP_AUTHREQUIRED); 929 goto error; 930 } 931 } else { 932 /* In this case, the TPM is owned, but we're creating a no-auth NV area */ 933 get_child_auth = FALSE; 934 } 935 936 break; 937#endif 938 /* Child is a Key object */ 939 case TPM_ORD_MakeIdentity: 940 if ((result = obj_rsakey_get_policy(obj_child, TSS_POLICY_USAGE, 941 &sess->hUsageChild, NULL))) 942 goto error; 943 break; 944 /* Child is a Policy object */ 945 case TPM_ORD_Delegate_CreateKeyDelegation: 946 case TPM_ORD_ChangeAuth: 947 if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) 948 goto error; 949 /* fall through */ 950 case TPM_ORD_Delegate_CreateOwnerDelegation: 951 case TPM_ORD_ChangeAuthOwner: 952 sess->hUsageChild = obj_child; 953 new_secret = TR_SECRET_CTX_NEW; 954 break; 955 default: 956 result = TSPERR(TSS_E_INTERNAL_ERROR); 957 goto error; 958 } 959 960 /* If req_auth is FALSE here, we don't actually need to set up an auth session, so returning 961 * is OK. At this point, authsess->pAuth is NULL, so the TCS API will not get any 962 * authdata. */ 963 if (req_auth == FALSE && sess->parentMode == TSS_SECRET_MODE_NONE) 964 goto done; 965 966 if (get_child_auth) { 967 if ((result = obj_policy_get_xsap_params(sess->hUsageChild, 0, 0, NULL, NULL, 968 sess->encAuthUse.authdata, NULL, NULL, 969 &sess->cb_sealx, &sess->uMode, 970 new_secret))) 971 goto error; 972 } 973 974 if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), 975 (BYTE **)sess->nonceOddxSAP.nonce))) 976 goto error; 977 978 sess->obj_child = obj_child; 979 sess->tspContext = tspContext; 980 sess->pAuth = &sess->auth; 981 sess->command = command; 982 983#ifdef TSS_BUILD_DELEGATION 984 /* if entityValue is set, we have a custom entity, i.e. delegation blob or row */ 985 if (sess->entityValue) { 986 /* DSAP's entity type was pulled from the policy in the authsess_xsap_init call 987 * above */ 988 if ((result = authsess_do_dsap(sess))) 989 goto error; 990 } 991#endif 992 if (!sess->entityValue) { 993 sess->entity_type = entity_type; 994 if ((result = authsess_do_osap(sess))) 995 goto error; 996 } 997 998 if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), 999 (BYTE **)sess->auth.NonceOdd.nonce))) 1000 goto error; 1001 1002 /* We have both OSAP nonces, so calculate the shared secret if we're responsible for it */ 1003 if (sess->parentMode != TSS_SECRET_MODE_CALLBACK) { 1004 offset = 0; 1005 Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceEvenxSAP.nonce); 1006 Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceOddxSAP.nonce); 1007 1008 if ((result = Trspi_HMAC(TSS_HASH_SHA1, sizeof(TPM_ENCAUTH), 1009 sess->parentSecret.authdata, offset, hmacBlob, 1010 sess->sharedSecret.digest))) 1011 goto error; 1012 } 1013 1014 /* XXX What does a PurposeSecret of TRUE mean here? */ 1015 if ((result = 1016 ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HOBJECT, TSS_FLAG, 1017 UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, 1018 BYTE *))sess->cb_xor.callback)(sess->cb_xor.appData, sess->hUsageParent, 1019 sess->hUsageChild, TRUE, sizeof(TPM_DIGEST), 1020 sess->auth.NonceEven.nonce, sess->auth.NonceOdd.nonce, 1021 sess->nonceEvenxSAP.nonce, sess->nonceOddxSAP.nonce, 1022 sizeof(TPM_ENCAUTH), sess->encAuthUse.authdata, 1023 sess->encAuthMig.authdata))) 1024 return result; 1025 1026done: 1027 *xsess = sess; 1028 1029 return TSS_SUCCESS; 1030error: 1031 free(sess); 1032 return result; 1033} 1034 1035TSS_RESULT 1036authsess_xsap_hmac(struct authsess *sess, TPM_DIGEST *digest) 1037{ 1038 TSS_RESULT result; 1039 1040 /* If no auth session was established using this authsess object, return success */ 1041 if (!sess->pAuth) 1042 return TSS_SUCCESS; 1043 1044 /* XXX Placeholder for future continueAuthSession support: 1045 * conditionally bump NonceOdd if continueAuthSession == TRUE here 1046 */ 1047 1048 if ((result = 1049 ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL, 1050 UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *, 1051 BYTE *, BYTE *, UINT32, BYTE *, 1052 BYTE *))sess->cb_hmac.callback)(sess->cb_hmac.appData, 1053 sess->hUsageParent, TRUE, sess->command, 1054 sess->auth.fContinueAuthSession, sizeof(TPM_NONCE), 1055 sess->auth.NonceEven.nonce, 1056 sess->auth.NonceOdd.nonce, 1057 sess->nonceEvenxSAP.nonce, 1058 sess->nonceOddxSAP.nonce, sizeof(TPM_DIGEST), 1059 digest->digest, sess->auth.HMAC.authdata))) 1060 return result; 1061 1062 if (sess->hUsageParent) 1063 obj_policy_dec_counter(sess->hUsageParent); 1064 1065 if (sess->hUsageChild) 1066 obj_policy_dec_counter(sess->hUsageChild); 1067 1068 if (sess->hMigChild) 1069 obj_policy_dec_counter(sess->hMigChild); 1070 1071 return TSS_SUCCESS; 1072} 1073 1074TSS_RESULT 1075authsess_xsap_verify(struct authsess *sess, TPM_DIGEST *digest) 1076{ 1077 /* If no auth session was established using this authsess object, return success */ 1078 if (!sess->pAuth) 1079 return TSS_SUCCESS; 1080 1081 return ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL, 1082 UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *, 1083 BYTE *, BYTE *, UINT32, BYTE *, 1084 BYTE *))sess->cb_hmac.callback)(sess->cb_hmac.appData, 1085 sess->hUsageParent, FALSE, sess->command, 1086 sess->auth.fContinueAuthSession, sizeof(TPM_NONCE), 1087 sess->auth.NonceEven.nonce, 1088 sess->auth.NonceOdd.nonce, 1089 sess->nonceEvenxSAP.nonce, 1090 sess->nonceOddxSAP.nonce, sizeof(TPM_DIGEST), 1091 digest->digest, sess->auth.HMAC.authdata); 1092} 1093 1094TSS_RESULT 1095__tspi_free_resource(TSS_HCONTEXT tspContext, UINT32 handle, UINT32 resourceType) 1096{ 1097 TSS_RESULT result = TSS_SUCCESS; 1098#ifdef TSS_BUILD_TSS12 1099 UINT32 version = 0; 1100 1101 if ((result = obj_context_get_tpm_version(tspContext, &version))) 1102 return result; 1103 1104 if (version == 2) { 1105 return TCS_API(tspContext)->FlushSpecific(tspContext, handle, resourceType); 1106 } 1107#endif 1108 1109 switch (resourceType) { 1110 case TPM_RT_KEY: 1111 result = TCS_API(tspContext)->EvictKey(tspContext, handle); 1112 break; 1113 case TPM_RT_AUTH: 1114 result = TCS_API(tspContext)->TerminateHandle(tspContext, handle); 1115 break; 1116 default: 1117 LogDebugFn("Trying to free TPM 1.2 resource type 0x%x on 1.1 TPM!", 1118 resourceType); 1119 result = TSPERR(TSS_E_INTERNAL_ERROR); 1120 break; 1121 } 1122 1123 return result; 1124} 1125 1126void 1127authsess_free(struct authsess *xsap) 1128{ 1129 if (xsap) { 1130 if (xsap->auth.AuthHandle && xsap->auth.fContinueAuthSession) 1131 (void)__tspi_free_resource(xsap->tspContext, xsap->auth.AuthHandle, TPM_RT_AUTH); 1132 1133 free(xsap->entityValue); 1134 free(xsap); 1135 xsap = NULL; 1136 } 1137} 1138 1139#ifdef TSS_BUILD_TRANSPORT 1140TSS_RESULT 1141Transport_OIAP(TSS_HCONTEXT tspContext, /* in */ 1142 TCS_AUTHHANDLE* authHandle, /* out */ 1143 TPM_NONCE* nonce0) /* out */ 1144{ 1145 TSS_RESULT result; 1146 UINT32 decLen = 0; 1147 BYTE *dec = NULL; 1148 UINT64 offset; 1149 TCS_HANDLE handlesLen = 0; 1150 1151 if ((result = obj_context_transport_init(tspContext))) 1152 return result; 1153 1154 LogDebugFn("Executing in a transport session"); 1155 1156 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OIAP, 0, NULL, NULL, 1157 &handlesLen, NULL, NULL, NULL, &decLen, &dec))) 1158 return result; 1159 1160 if (decLen != sizeof(TCS_AUTHHANDLE) + sizeof(TPM_NONCE)) 1161 return TSPERR(TSS_E_INTERNAL_ERROR); 1162 1163 offset = 0; 1164 Trspi_UnloadBlob_UINT32(&offset, authHandle, dec); 1165 Trspi_UnloadBlob_NONCE(&offset, dec, nonce0); 1166 1167 return result; 1168} 1169 1170TSS_RESULT 1171Transport_OSAP(TSS_HCONTEXT tspContext, /* in */ 1172 TPM_ENTITY_TYPE entityType, /* in */ 1173 UINT32 entityValue, /* in */ 1174 TPM_NONCE* nonceOddOSAP, /* in */ 1175 TCS_AUTHHANDLE* authHandle, /* out */ 1176 TPM_NONCE* nonceEven, /* out */ 1177 TPM_NONCE* nonceEvenOSAP) /* out */ 1178{ 1179 TSS_RESULT result; 1180 UINT32 decLen = 0; 1181 BYTE *dec = NULL; 1182 UINT64 offset; 1183 TCS_HANDLE handlesLen = 0; 1184 BYTE data[sizeof(UINT16) + sizeof(UINT32) + sizeof(TPM_NONCE)]; 1185 1186 if ((result = obj_context_transport_init(tspContext))) 1187 return result; 1188 1189 LogDebugFn("Executing in a transport session"); 1190 1191 offset = 0; 1192 Trspi_LoadBlob_UINT16(&offset, entityType, data); 1193 Trspi_LoadBlob_UINT32(&offset, entityValue, data); 1194 Trspi_LoadBlob_NONCE(&offset, data, nonceOddOSAP); 1195 1196 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OSAP, sizeof(data), data, 1197 NULL, &handlesLen, NULL, NULL, NULL, &decLen, 1198 &dec))) 1199 return result; 1200 1201 offset = 0; 1202 Trspi_UnloadBlob_UINT32(&offset, authHandle, dec); 1203 Trspi_UnloadBlob_NONCE(&offset, dec, nonceEven); 1204 Trspi_UnloadBlob_NONCE(&offset, dec, nonceEvenOSAP); 1205 1206 return TSS_SUCCESS; 1207} 1208 1209TSS_RESULT 1210Transport_TerminateHandle(TSS_HCONTEXT tspContext, /* in */ 1211 TCS_AUTHHANDLE handle) /* in */ 1212{ 1213 TSS_RESULT result; 1214 TCS_HANDLE handlesLen = 0, *handles, *handles_track; 1215 1216 /* Call ExecuteTransport */ 1217 handlesLen = 1; 1218 if ((handles = malloc(sizeof(TCS_HANDLE))) == NULL) { 1219 LogError("malloc of %zd bytes failed", sizeof(TCS_HANDLE)); 1220 return TSPERR(TSS_E_OUTOFMEMORY); 1221 } 1222 1223 *handles = handle; 1224 handles_track = handles; 1225 1226 // Since the call tree of this function can possibly alloc memory 1227 // (check RPC_ExecuteTransport_TP function), its better to keep track of 1228 // the handle. 1229 result = obj_context_transport_execute(tspContext, TPM_ORD_Terminate_Handle, 0, NULL, 1230 NULL, &handlesLen, &handles, NULL, NULL, NULL, NULL); 1231 1232 free(handles); 1233 handles = NULL; 1234 free(handles_track); 1235 1236 return result; 1237} 1238#endif 1239