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-2006 8 * 9 */ 10 11 #include <limits.h> 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <inttypes.h> 16 #include <limits.h> 17 18 #include "trousers/tss.h" 19 #include "trousers/trousers.h" 20 #include "trousers_types.h" 21 #include "spi_utils.h" 22 #include "capabilities.h" 23 #include "tsplog.h" 24 #include "obj.h" 25 #include "authsess.h" 26 27 28 TSS_RESULT 29 Tspi_TPM_CollateIdentityRequest(TSS_HTPM hTPM, /* in */ 30 TSS_HKEY hKeySRK, /* in */ 31 TSS_HKEY hCAPubKey, /* in */ 32 UINT32 ulIdentityLabelLength, /* in */ 33 BYTE * rgbIdentityLabelData, /* in */ 34 TSS_HKEY hIdentityKey, /* in */ 35 TSS_ALGORITHM_ID algID, /* in */ 36 UINT32 * pulTcpaIdentityReqLength, /* out */ 37 BYTE ** prgbTcpaIdentityReq) /* out */ 38 { 39 #ifdef TSS_BUILD_TRANSPORT 40 UINT32 transport; 41 #endif 42 TPM_AUTH srkAuth; 43 TCPA_RESULT result; 44 UINT64 offset; 45 BYTE hashblob[USHRT_MAX], idReqBlob[USHRT_MAX], testblob[USHRT_MAX]; 46 TCPA_DIGEST digest; 47 TSS_HPOLICY hSRKPolicy, hIDPolicy, hCAPolicy; 48 UINT32 caKeyBlobSize, idKeySize, idPubSize; 49 BYTE *caKeyBlob, *idKey, *newIdKey, *idPub; 50 TSS_KEY caKey; 51 TCPA_CHOSENID_HASH chosenIDHash = { { 0, } }; 52 UINT32 pcIdentityBindingSize; 53 BYTE *prgbIdentityBinding = NULL; 54 UINT32 pcEndorsementCredentialSize; 55 BYTE *prgbEndorsementCredential = NULL; 56 UINT32 pcPlatformCredentialSize; 57 BYTE *prgbPlatformCredential = NULL; 58 UINT32 pcConformanceCredentialSize; 59 BYTE *prgbConformanceCredential = NULL; 60 #define CHOSENID_BLOB_SIZE 2048 61 BYTE chosenIDBlob[CHOSENID_BLOB_SIZE]; 62 TSS_HCONTEXT tspContext; 63 UINT32 encSymKeySize = 256, tmp; 64 BYTE encSymKey[256], *cb_var; 65 TSS_BOOL usesAuth; 66 TPM_AUTH *pSrkAuth = &srkAuth; 67 TCPA_IDENTITY_REQ rgbTcpaIdentityReq; 68 TCPA_KEY_PARMS symParms, asymParms; 69 TCPA_SYMMETRIC_KEY symKey; 70 int padding; 71 TSS_CALLBACK *cb; 72 Trspi_HashCtx hashCtx; 73 UINT32 tempCredSize; 74 BYTE *tempCred = NULL; 75 struct authsess *xsap = NULL; 76 77 if (pulTcpaIdentityReqLength == NULL || prgbTcpaIdentityReq == NULL) 78 return TSPERR(TSS_E_BAD_PARAMETER); 79 80 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 81 return result; 82 83 if ((result = obj_tpm_get_cb12(hTPM, TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY, &tmp, 84 &cb_var))) 85 return result; 86 87 cb = (TSS_CALLBACK *)cb_var; 88 if (cb->callback == NULL) { 89 free_tspi(tspContext, cb); 90 cb = NULL; 91 } 92 93 /* Get Policies */ 94 if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSRKPolicy, &usesAuth))) 95 return result; 96 97 if ((result = obj_rsakey_get_policy(hCAPubKey, TSS_POLICY_USAGE, 98 &hCAPolicy, NULL))) 99 return result; 100 101 if ((result = obj_rsakey_get_policy(hIdentityKey, TSS_POLICY_USAGE, 102 &hIDPolicy, NULL))) 103 return result; 104 105 /* setup the symmetric key's parms. */ 106 __tspi_memset(&symParms, 0, sizeof(TCPA_KEY_PARMS)); 107 switch (algID) { 108 case TSS_ALG_AES: 109 symParms.algorithmID = TCPA_ALG_AES; 110 symKey.algId = TCPA_ALG_AES; 111 symKey.size = 128/8; 112 break; 113 case TSS_ALG_DES: 114 symParms.algorithmID = TCPA_ALG_DES; 115 symKey.algId = TCPA_ALG_DES; 116 symKey.size = 64/8; 117 break; 118 case TSS_ALG_3DES: 119 symParms.algorithmID = TCPA_ALG_3DES; 120 symKey.algId = TCPA_ALG_3DES; 121 symKey.size = 192/8; 122 break; 123 default: 124 result = TSPERR(TSS_E_BAD_PARAMETER); 125 goto error; 126 break; 127 } 128 129 /* No symmetric key encryption schemes existed in the 1.1 time frame */ 130 symParms.encScheme = TCPA_ES_NONE; 131 132 /* get the CA Pubkey's encryption scheme */ 133 if ((result = obj_rsakey_get_es(hCAPubKey, &tmp))) 134 return TSPERR(TSS_E_BAD_PARAMETER); 135 136 switch (tmp) { 137 case TSS_ES_RSAESPKCSV15: 138 padding = TR_RSA_PKCS1_PADDING; 139 break; 140 case TSS_ES_RSAESOAEP_SHA1_MGF1: 141 padding = TR_RSA_PKCS1_OAEP_PADDING; 142 break; 143 case TSS_ES_NONE: 144 /* fall through */ 145 default: 146 padding = TR_RSA_NO_PADDING; 147 break; 148 } 149 150 /* Get Key blobs */ 151 if ((result = obj_rsakey_get_blob(hIdentityKey, &idKeySize, &idKey))) 152 return result; 153 154 if ((result = obj_rsakey_get_blob(hCAPubKey, &caKeyBlobSize, &caKeyBlob))) 155 return result; 156 157 offset = 0; 158 __tspi_memset(&caKey, 0, sizeof(TSS_KEY)); 159 if ((result = UnloadBlob_TSS_KEY(&offset, caKeyBlob, &caKey))) 160 return result; 161 162 /* ChosenID hash = SHA1(label || TCPA_PUBKEY(CApub)) */ 163 offset = 0; 164 Trspi_LoadBlob(&offset, ulIdentityLabelLength, chosenIDBlob, rgbIdentityLabelData); 165 Trspi_LoadBlob_KEY_PARMS(&offset, chosenIDBlob, &caKey.algorithmParms); 166 Trspi_LoadBlob_STORE_PUBKEY(&offset, chosenIDBlob, &caKey.pubKey); 167 168 if (offset > CHOSENID_BLOB_SIZE) 169 return TSPERR(TSS_E_INTERNAL_ERROR); 170 171 if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, chosenIDBlob, chosenIDHash.digest))) { 172 free_key_refs(&caKey); 173 return result; 174 } 175 176 /* use chosenIDBlob temporarily */ 177 offset = 0; 178 Trspi_LoadBlob_KEY_PARMS(&offset, chosenIDBlob, &caKey.algorithmParms); 179 180 offset = 0; 181 if ((result = Trspi_UnloadBlob_KEY_PARMS(&offset, chosenIDBlob, &asymParms))) 182 return result; 183 184 if ((result = authsess_xsap_init(tspContext, hTPM, hIdentityKey, TSS_AUTH_POLICY_REQUIRED, 185 TPM_ORD_MakeIdentity, TPM_ET_OWNER, &xsap))){ 186 free(asymParms.parms); 187 return result; 188 } 189 190 /* Hash the Auth data */ 191 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 192 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); 193 result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); 194 result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, chosenIDHash.digest); 195 result |= Trspi_HashUpdate(&hashCtx, idKeySize, idKey); 196 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 197 goto error; 198 199 /* Do the Auth's */ 200 if (usesAuth) { 201 if ((result = secret_PerformAuth_OIAP(hKeySRK, TPM_ORD_MakeIdentity, hSRKPolicy, 202 FALSE, &digest, &srkAuth))) 203 goto error; 204 pSrkAuth = &srkAuth; 205 } else { 206 pSrkAuth = NULL; 207 } 208 209 if ((result = authsess_xsap_hmac(xsap, &digest))) 210 goto error; 211 212 #ifdef TSS_BUILD_TRANSPORT 213 if ((result = obj_context_transport_get_control(tspContext, TSS_TSPATTRIB_ENABLE_TRANSPORT, 214 &transport))) 215 goto error; 216 217 if (transport) { 218 if ((result = Transport_MakeIdentity2(tspContext, xsap->encAuthUse, chosenIDHash, 219 idKeySize, idKey, pSrkAuth, xsap->pAuth, 220 &idKeySize, &newIdKey, &pcIdentityBindingSize, 221 &prgbIdentityBinding))) 222 goto error; 223 } else { 224 #endif 225 if ((result = RPC_MakeIdentity(tspContext, xsap->encAuthUse, chosenIDHash, 226 idKeySize, idKey, pSrkAuth, xsap->pAuth, &idKeySize, 227 &newIdKey, &pcIdentityBindingSize, 228 &prgbIdentityBinding, &pcEndorsementCredentialSize, 229 &prgbEndorsementCredential, 230 &pcPlatformCredentialSize, &prgbPlatformCredential, 231 &pcConformanceCredentialSize, 232 &prgbConformanceCredential))) 233 goto error; 234 #ifdef TSS_BUILD_TRANSPORT 235 } 236 #endif 237 238 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 239 result |= Trspi_Hash_UINT32(&hashCtx, result); 240 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); 241 result |= Trspi_HashUpdate(&hashCtx, idKeySize, newIdKey); 242 result |= Trspi_Hash_UINT32(&hashCtx, pcIdentityBindingSize); 243 result |= Trspi_HashUpdate(&hashCtx, pcIdentityBindingSize, prgbIdentityBinding); 244 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { 245 free(newIdKey); 246 goto error; 247 } 248 249 if ((result = authsess_xsap_verify(xsap, &digest))) { 250 free(newIdKey); 251 goto error; 252 } 253 254 if (usesAuth == TRUE) { 255 if ((result = obj_policy_validate_auth_oiap(hSRKPolicy, &digest, &srkAuth))) { 256 free(newIdKey); 257 goto error; 258 } 259 } 260 261 if ((result = obj_rsakey_set_tcpakey(hIdentityKey, idKeySize, newIdKey))) { 262 free(newIdKey); 263 goto error; 264 } 265 free(newIdKey); 266 if ((result = obj_rsakey_set_tcs_handle(hIdentityKey, 0))) 267 goto error; 268 269 if ((result = obj_rsakey_get_pub_blob(hIdentityKey, &idPubSize, &idPub))) 270 goto error; 271 272 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_EKCERT, &tempCredSize, &tempCred))) 273 goto error; 274 275 if (tempCred != NULL) { 276 free(prgbEndorsementCredential); 277 prgbEndorsementCredential = tempCred; 278 pcEndorsementCredentialSize = tempCredSize; 279 } 280 281 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_TPM_CC, &tempCredSize, &tempCred))) 282 goto error; 283 284 if (tempCred != NULL) { 285 free(prgbConformanceCredential); 286 prgbConformanceCredential = tempCred; 287 pcConformanceCredentialSize = tempCredSize; 288 } 289 290 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_PLATFORMCERT, &tempCredSize, &tempCred))) 291 goto error; 292 293 if (tempCred != NULL) { 294 free(prgbPlatformCredential); 295 prgbPlatformCredential = tempCred; 296 pcPlatformCredentialSize = tempCredSize; 297 } 298 299 /* set up the TCPA_IDENTITY_PROOF structure */ 300 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 301 /* XXX hash this incrementally using a Trspi_HashCtx */ 302 offset = 0; 303 Trspi_LoadBlob_TSS_VERSION(&offset, hashblob, VERSION_1_1); 304 Trspi_LoadBlob_UINT32(&offset, ulIdentityLabelLength, hashblob); 305 Trspi_LoadBlob_UINT32(&offset, pcIdentityBindingSize, hashblob); 306 Trspi_LoadBlob_UINT32(&offset, pcEndorsementCredentialSize, hashblob); 307 Trspi_LoadBlob_UINT32(&offset, pcPlatformCredentialSize, hashblob); 308 Trspi_LoadBlob_UINT32(&offset, pcConformanceCredentialSize, hashblob); 309 Trspi_LoadBlob(&offset, idPubSize, hashblob, idPub); 310 free_tspi(tspContext, idPub); 311 Trspi_LoadBlob(&offset, ulIdentityLabelLength, hashblob, rgbIdentityLabelData); 312 Trspi_LoadBlob(&offset, pcIdentityBindingSize, hashblob, prgbIdentityBinding); 313 Trspi_LoadBlob(&offset, pcEndorsementCredentialSize, hashblob, prgbEndorsementCredential); 314 Trspi_LoadBlob(&offset, pcPlatformCredentialSize, hashblob, prgbPlatformCredential); 315 Trspi_LoadBlob(&offset, pcConformanceCredentialSize, hashblob, prgbConformanceCredential); 316 317 if (cb && cb->callback) { 318 /* Alloc the space for the callback to copy into. The additional 32 bytes will 319 * attempt to account for padding that the symmetric encryption will do. */ 320 rgbTcpaIdentityReq.asymBlob = calloc(1, (int)offset + 32); 321 rgbTcpaIdentityReq.symBlob = calloc(1, (int)offset + 32); 322 if (rgbTcpaIdentityReq.asymBlob == NULL || 323 rgbTcpaIdentityReq.symBlob == NULL) { 324 free(rgbTcpaIdentityReq.asymBlob); 325 free(rgbTcpaIdentityReq.symBlob); 326 LogError("malloc of %" PRIu64 " bytes failed", offset); 327 free_tspi(tspContext, cb); 328 result = TSPERR(TSS_E_OUTOFMEMORY); 329 goto error; 330 } 331 rgbTcpaIdentityReq.asymSize = (UINT32)offset + 32; 332 rgbTcpaIdentityReq.symSize = (UINT32)offset + 32; 333 334 if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, UINT32 *, BYTE *, 335 UINT32 *, BYTE *))cb->callback)(cb->appData, (UINT32)offset, 336 hashblob, algID, 337 &rgbTcpaIdentityReq.asymSize, 338 rgbTcpaIdentityReq.asymBlob, 339 &rgbTcpaIdentityReq.symSize, 340 rgbTcpaIdentityReq.symBlob))) { 341 LogDebug("CollateIdentityRequest callback returned error 0x%x", result); 342 free_tspi(tspContext, cb); 343 goto error; 344 } 345 } else { 346 /* generate the symmetric key. */ 347 if ((result = get_local_random(tspContext, TRUE, symKey.size, &symKey.data))) 348 goto error; 349 350 /* No symmetric key encryption schemes existed in the 1.1 time frame */ 351 symKey.encScheme = TCPA_ES_NONE; 352 353 /* encrypt the proof */ 354 rgbTcpaIdentityReq.symSize = sizeof(testblob); 355 if ((result = Trspi_SymEncrypt(algID, TR_SYM_MODE_CBC, symKey.data, NULL, hashblob, 356 offset, testblob, &rgbTcpaIdentityReq.symSize))) 357 goto error; 358 359 rgbTcpaIdentityReq.symBlob = testblob; 360 361 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 362 offset = 0; 363 Trspi_LoadBlob_SYMMETRIC_KEY(&offset, hashblob, &symKey); 364 365 if ((result = Trspi_RSA_Public_Encrypt(hashblob, offset, encSymKey, &encSymKeySize, 366 caKey.pubKey.key, caKey.pubKey.keyLength, 367 65537, padding))) 368 goto error; 369 370 rgbTcpaIdentityReq.asymSize = encSymKeySize; 371 rgbTcpaIdentityReq.asymBlob = encSymKey; 372 } 373 374 rgbTcpaIdentityReq.asymAlgorithm = asymParms; 375 rgbTcpaIdentityReq.symAlgorithm = symParms; 376 377 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 378 offset = 0; 379 Trspi_LoadBlob_IDENTITY_REQ(&offset, idReqBlob, &rgbTcpaIdentityReq); 380 381 if (cb && cb->callback) { 382 free(rgbTcpaIdentityReq.symBlob); 383 free(rgbTcpaIdentityReq.asymBlob); 384 free_tspi(tspContext, cb); 385 } 386 387 if ((*prgbTcpaIdentityReq = calloc_tspi(tspContext, offset)) == NULL) { 388 result = TSPERR(TSS_E_OUTOFMEMORY); 389 goto error; 390 } 391 392 memcpy(*prgbTcpaIdentityReq, idReqBlob, offset); 393 *pulTcpaIdentityReqLength = offset; 394 error: 395 authsess_free(xsap); 396 free_key_refs(&caKey); 397 free(asymParms.parms); 398 free(prgbIdentityBinding); 399 free(prgbEndorsementCredential); 400 free(prgbPlatformCredential); 401 free(prgbConformanceCredential); 402 403 return result; 404 } 405 406 TSS_RESULT 407 Tspi_TPM_ActivateIdentity(TSS_HTPM hTPM, /* in */ 408 TSS_HKEY hIdentKey, /* in */ 409 UINT32 ulAsymCAContentsBlobLength, /* in */ 410 BYTE * rgbAsymCAContentsBlob, /* in */ 411 UINT32 ulSymCAAttestationBlobLength, /* in */ 412 BYTE * rgbSymCAAttestationBlob, /* in */ 413 UINT32 * pulCredentialLength, /* out */ 414 BYTE ** prgbCredential) /* out */ 415 { 416 TPM_AUTH idKeyAuth; 417 TPM_AUTH ownerAuth; 418 TSS_HCONTEXT tspContext; 419 TSS_HPOLICY hIDPolicy, hTPMPolicy; 420 UINT64 offset; 421 BYTE credBlob[0x1000]; 422 TCPA_DIGEST digest; 423 TSS_RESULT result; 424 TCS_KEY_HANDLE tcsKeyHandle; 425 TSS_BOOL usesAuth; 426 TPM_AUTH *pIDKeyAuth; 427 BYTE *symKeyBlob, *credCallback, *cb_var; 428 UINT32 symKeyBlobLen, credLen, tmp; 429 TCPA_SYMMETRIC_KEY symKey; 430 TSS_CALLBACK *cb; 431 Trspi_HashCtx hashCtx; 432 TPM_SYM_CA_ATTESTATION symCAAttestation; 433 434 if (pulCredentialLength == NULL || prgbCredential == NULL) 435 return TSPERR(TSS_E_BAD_PARAMETER); 436 437 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 438 return result; 439 440 if ((result = obj_tpm_get_cb12(hTPM, TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY, &tmp, 441 &cb_var))) 442 return result; 443 444 cb = (TSS_CALLBACK *)cb_var; 445 if (cb->callback == NULL) { 446 free_tspi(tspContext, cb); 447 cb = NULL; 448 } 449 450 if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle))) 451 return result; 452 453 if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, 454 &hIDPolicy, &usesAuth))) 455 return result; 456 457 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hTPMPolicy))) 458 return result; 459 460 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 461 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); 462 result |= Trspi_Hash_UINT32(&hashCtx, ulAsymCAContentsBlobLength); 463 result |= Trspi_HashUpdate(&hashCtx, ulAsymCAContentsBlobLength, rgbAsymCAContentsBlob); 464 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 465 return result; 466 467 if (usesAuth) { 468 if ((result = secret_PerformAuth_OIAP(hIDPolicy, TPM_ORD_ActivateIdentity, 469 hIDPolicy, FALSE, &digest, &idKeyAuth))) 470 return result; 471 pIDKeyAuth = &idKeyAuth; 472 } else { 473 pIDKeyAuth = NULL; 474 } 475 476 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ActivateIdentity, hTPMPolicy, FALSE, 477 &digest, &ownerAuth))) 478 return result; 479 480 if ((result = TCS_API(tspContext)->ActivateTPMIdentity(tspContext, tcsKeyHandle, 481 ulAsymCAContentsBlobLength, 482 rgbAsymCAContentsBlob, pIDKeyAuth, 483 &ownerAuth, &symKeyBlobLen, 484 &symKeyBlob))) 485 return result; 486 487 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 488 result |= Trspi_Hash_UINT32(&hashCtx, result); 489 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); 490 result |= Trspi_HashUpdate(&hashCtx, symKeyBlobLen, symKeyBlob); 491 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 492 return result; 493 494 if (usesAuth) { 495 if ((result = obj_policy_validate_auth_oiap(hIDPolicy, &digest, 496 &idKeyAuth))) { 497 LogDebugFn("Identity key auth validation of the symmetric key failed."); 498 return result; 499 } 500 } 501 502 if ((result = obj_policy_validate_auth_oiap(hTPMPolicy, &digest, 503 &ownerAuth))) { 504 LogDebugFn("Owner auth validation of the symmetric key failed."); 505 return result; 506 } 507 508 offset = 0; 509 if ((result = Trspi_UnloadBlob_SYM_CA_ATTESTATION(&offset, rgbSymCAAttestationBlob, 510 &symCAAttestation))) { 511 LogDebugFn("Error unloading CA's attestation blob."); 512 return result; 513 } 514 515 if (cb && cb->callback) { 516 /* alloc the space for the callback to copy into */ 517 credCallback = calloc(1, ulSymCAAttestationBlobLength); 518 if (credCallback == NULL) { 519 LogDebug("malloc of %u bytes failed", ulSymCAAttestationBlobLength); 520 free(symKeyBlob); 521 free_tspi(tspContext, cb); 522 return TSPERR(TSS_E_INTERNAL_ERROR); 523 } 524 credLen = ulSymCAAttestationBlobLength; 525 526 if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, BYTE *, UINT32 *, 527 BYTE *))cb->callback)(cb->appData, symKeyBlobLen, symKeyBlob, 528 symCAAttestation.credSize, 529 symCAAttestation.credential, 530 &credLen, credCallback))) { 531 LogDebug("ActivateIdentity callback returned error 0x%x", result); 532 free(symCAAttestation.credential); 533 free(symKeyBlob); 534 free_tspi(tspContext, cb); 535 free(credCallback); 536 return TSPERR(TSS_E_INTERNAL_ERROR); 537 } 538 free(symCAAttestation.credential); 539 free_tspi(tspContext, cb); 540 free(symKeyBlob); 541 542 if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { 543 free(credCallback); 544 return TSPERR(TSS_E_OUTOFMEMORY); 545 } 546 547 memcpy(*prgbCredential, credCallback, credLen); 548 *pulCredentialLength = credLen; 549 free(credCallback); 550 551 return TSS_SUCCESS; 552 } 553 554 /* decrypt the symmetric blob using the recovered symmetric key */ 555 offset = 0; 556 if ((result = Trspi_UnloadBlob_SYMMETRIC_KEY(&offset, symKeyBlob, &symKey))) { 557 free(symCAAttestation.credential); 558 free(symKeyBlob); 559 return result; 560 } 561 free(symKeyBlob); 562 563 if ((result = Trspi_SymDecrypt(symKey.algId, symKey.encScheme, symKey.data, NULL, 564 symCAAttestation.credential, symCAAttestation.credSize, 565 credBlob, &credLen))) { 566 free(symCAAttestation.credential); 567 free(symKey.data); 568 return result; 569 } 570 free(symCAAttestation.credential); 571 572 if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { 573 free(symKey.data); 574 return TSPERR(TSS_E_OUTOFMEMORY); 575 } 576 577 free(symKey.data); 578 memcpy(*prgbCredential, credBlob, credLen); 579 *pulCredentialLength = credLen; 580 581 return TSS_SUCCESS; 582 } 583