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 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 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 return result; 187 188 /* Hash the Auth data */ 189 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 190 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); 191 result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); 192 result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, chosenIDHash.digest); 193 result |= Trspi_HashUpdate(&hashCtx, idKeySize, idKey); 194 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 195 goto error; 196 197 /* Do the Auth's */ 198 if (usesAuth) { 199 if ((result = secret_PerformAuth_OIAP(hKeySRK, TPM_ORD_MakeIdentity, hSRKPolicy, 200 FALSE, &digest, &srkAuth))) 201 goto error; 202 pSrkAuth = &srkAuth; 203 } else { 204 pSrkAuth = NULL; 205 } 206 207 if ((result = authsess_xsap_hmac(xsap, &digest))) 208 goto error; 209 210 #ifdef TSS_BUILD_TRANSPORT 211 if ((result = obj_context_transport_get_control(tspContext, TSS_TSPATTRIB_ENABLE_TRANSPORT, 212 &transport))) 213 goto error; 214 215 if (transport) { 216 if ((result = Transport_MakeIdentity2(tspContext, xsap->encAuthUse, chosenIDHash, 217 idKeySize, idKey, pSrkAuth, xsap->pAuth, 218 &idKeySize, &newIdKey, &pcIdentityBindingSize, 219 &prgbIdentityBinding))) 220 goto error; 221 } else { 222 #endif 223 if ((result = RPC_MakeIdentity(tspContext, xsap->encAuthUse, chosenIDHash, 224 idKeySize, idKey, pSrkAuth, xsap->pAuth, &idKeySize, 225 &newIdKey, &pcIdentityBindingSize, 226 &prgbIdentityBinding, &pcEndorsementCredentialSize, 227 &prgbEndorsementCredential, 228 &pcPlatformCredentialSize, &prgbPlatformCredential, 229 &pcConformanceCredentialSize, 230 &prgbConformanceCredential))) 231 goto error; 232 #ifdef TSS_BUILD_TRANSPORT 233 } 234 #endif 235 236 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 237 result |= Trspi_Hash_UINT32(&hashCtx, result); 238 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); 239 result |= Trspi_HashUpdate(&hashCtx, idKeySize, newIdKey); 240 result |= Trspi_Hash_UINT32(&hashCtx, pcIdentityBindingSize); 241 result |= Trspi_HashUpdate(&hashCtx, pcIdentityBindingSize, prgbIdentityBinding); 242 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { 243 free(newIdKey); 244 goto error; 245 } 246 247 if ((result = authsess_xsap_verify(xsap, &digest))) { 248 free(newIdKey); 249 goto error; 250 } 251 252 if (usesAuth == TRUE) { 253 if ((result = obj_policy_validate_auth_oiap(hSRKPolicy, &digest, &srkAuth))) { 254 free(newIdKey); 255 goto error; 256 } 257 } 258 259 if ((result = obj_rsakey_set_tcpakey(hIdentityKey, idKeySize, newIdKey))) { 260 free(newIdKey); 261 goto error; 262 } 263 free(newIdKey); 264 if ((result = obj_rsakey_set_tcs_handle(hIdentityKey, 0))) 265 goto error; 266 267 if ((result = obj_rsakey_get_pub_blob(hIdentityKey, &idPubSize, &idPub))) 268 goto error; 269 270 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_EKCERT, &tempCredSize, &tempCred))) 271 goto error; 272 273 if (tempCred != NULL) { 274 free(prgbEndorsementCredential); 275 prgbEndorsementCredential = tempCred; 276 pcEndorsementCredentialSize = tempCredSize; 277 } 278 279 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_TPM_CC, &tempCredSize, &tempCred))) 280 goto error; 281 282 if (tempCred != NULL) { 283 free(prgbConformanceCredential); 284 prgbConformanceCredential = tempCred; 285 pcConformanceCredentialSize = tempCredSize; 286 } 287 288 if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_PLATFORMCERT, &tempCredSize, &tempCred))) 289 goto error; 290 291 if (tempCred != NULL) { 292 free(prgbPlatformCredential); 293 prgbPlatformCredential = tempCred; 294 pcPlatformCredentialSize = tempCredSize; 295 } 296 297 /* set up the TCPA_IDENTITY_PROOF structure */ 298 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 299 /* XXX hash this incrementally using a Trspi_HashCtx */ 300 offset = 0; 301 Trspi_LoadBlob_TSS_VERSION(&offset, hashblob, VERSION_1_1); 302 Trspi_LoadBlob_UINT32(&offset, ulIdentityLabelLength, hashblob); 303 Trspi_LoadBlob_UINT32(&offset, pcIdentityBindingSize, hashblob); 304 Trspi_LoadBlob_UINT32(&offset, pcEndorsementCredentialSize, hashblob); 305 Trspi_LoadBlob_UINT32(&offset, pcPlatformCredentialSize, hashblob); 306 Trspi_LoadBlob_UINT32(&offset, pcConformanceCredentialSize, hashblob); 307 Trspi_LoadBlob(&offset, idPubSize, hashblob, idPub); 308 free_tspi(tspContext, idPub); 309 Trspi_LoadBlob(&offset, ulIdentityLabelLength, hashblob, rgbIdentityLabelData); 310 Trspi_LoadBlob(&offset, pcIdentityBindingSize, hashblob, prgbIdentityBinding); 311 Trspi_LoadBlob(&offset, pcEndorsementCredentialSize, hashblob, prgbEndorsementCredential); 312 Trspi_LoadBlob(&offset, pcPlatformCredentialSize, hashblob, prgbPlatformCredential); 313 Trspi_LoadBlob(&offset, pcConformanceCredentialSize, hashblob, prgbConformanceCredential); 314 315 if (cb && cb->callback) { 316 /* Alloc the space for the callback to copy into. The additional 32 bytes will 317 * attempt to account for padding that the symmetric encryption will do. */ 318 rgbTcpaIdentityReq.asymBlob = calloc(1, (int)offset + 32); 319 rgbTcpaIdentityReq.symBlob = calloc(1, (int)offset + 32); 320 if (rgbTcpaIdentityReq.asymBlob == NULL || 321 rgbTcpaIdentityReq.symBlob == NULL) { 322 free(rgbTcpaIdentityReq.asymBlob); 323 free(rgbTcpaIdentityReq.symBlob); 324 LogError("malloc of %" PRIu64 " bytes failed", offset); 325 free_tspi(tspContext, cb); 326 result = TSPERR(TSS_E_OUTOFMEMORY); 327 goto error; 328 } 329 rgbTcpaIdentityReq.asymSize = (UINT32)offset + 32; 330 rgbTcpaIdentityReq.symSize = (UINT32)offset + 32; 331 332 if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, UINT32 *, BYTE *, 333 UINT32 *, BYTE *))cb->callback)(cb->appData, (UINT32)offset, 334 hashblob, algID, 335 &rgbTcpaIdentityReq.asymSize, 336 rgbTcpaIdentityReq.asymBlob, 337 &rgbTcpaIdentityReq.symSize, 338 rgbTcpaIdentityReq.symBlob))) { 339 LogDebug("CollateIdentityRequest callback returned error 0x%x", result); 340 free_tspi(tspContext, cb); 341 goto error; 342 } 343 } else { 344 /* generate the symmetric key. */ 345 if ((result = get_local_random(tspContext, TRUE, symKey.size, &symKey.data))) 346 goto error; 347 348 /* No symmetric key encryption schemes existed in the 1.1 time frame */ 349 symKey.encScheme = TCPA_ES_NONE; 350 351 /* encrypt the proof */ 352 rgbTcpaIdentityReq.symSize = sizeof(testblob); 353 if ((result = Trspi_SymEncrypt(algID, TR_SYM_MODE_CBC, symKey.data, NULL, hashblob, 354 offset, testblob, &rgbTcpaIdentityReq.symSize))) 355 goto error; 356 357 rgbTcpaIdentityReq.symBlob = testblob; 358 359 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 360 offset = 0; 361 Trspi_LoadBlob_SYMMETRIC_KEY(&offset, hashblob, &symKey); 362 363 if ((result = Trspi_RSA_Public_Encrypt(hashblob, offset, encSymKey, &encSymKeySize, 364 caKey.pubKey.key, caKey.pubKey.keyLength, 365 65537, padding))) 366 goto error; 367 368 rgbTcpaIdentityReq.asymSize = encSymKeySize; 369 rgbTcpaIdentityReq.asymBlob = encSymKey; 370 } 371 372 rgbTcpaIdentityReq.asymAlgorithm = asymParms; 373 rgbTcpaIdentityReq.symAlgorithm = symParms; 374 375 /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ 376 offset = 0; 377 Trspi_LoadBlob_IDENTITY_REQ(&offset, idReqBlob, &rgbTcpaIdentityReq); 378 379 if (cb && cb->callback) { 380 free(rgbTcpaIdentityReq.symBlob); 381 free(rgbTcpaIdentityReq.asymBlob); 382 free_tspi(tspContext, cb); 383 } 384 385 if ((*prgbTcpaIdentityReq = calloc_tspi(tspContext, offset)) == NULL) { 386 result = TSPERR(TSS_E_OUTOFMEMORY); 387 goto error; 388 } 389 390 memcpy(*prgbTcpaIdentityReq, idReqBlob, offset); 391 *pulTcpaIdentityReqLength = offset; 392 error: 393 authsess_free(xsap); 394 free_key_refs(&caKey); 395 free(prgbIdentityBinding); 396 free(prgbEndorsementCredential); 397 free(prgbPlatformCredential); 398 free(prgbConformanceCredential); 399 400 return result; 401 } 402 403 TSS_RESULT 404 Tspi_TPM_ActivateIdentity(TSS_HTPM hTPM, /* in */ 405 TSS_HKEY hIdentKey, /* in */ 406 UINT32 ulAsymCAContentsBlobLength, /* in */ 407 BYTE * rgbAsymCAContentsBlob, /* in */ 408 UINT32 ulSymCAAttestationBlobLength, /* in */ 409 BYTE * rgbSymCAAttestationBlob, /* in */ 410 UINT32 * pulCredentialLength, /* out */ 411 BYTE ** prgbCredential) /* out */ 412 { 413 TPM_AUTH idKeyAuth; 414 TPM_AUTH ownerAuth; 415 TSS_HCONTEXT tspContext; 416 TSS_HPOLICY hIDPolicy, hTPMPolicy; 417 UINT64 offset; 418 BYTE credBlob[0x1000]; 419 TCPA_DIGEST digest; 420 TSS_RESULT result; 421 TCS_KEY_HANDLE tcsKeyHandle; 422 TSS_BOOL usesAuth; 423 TPM_AUTH *pIDKeyAuth; 424 BYTE *symKeyBlob, *credCallback, *cb_var; 425 UINT32 symKeyBlobLen, credLen, tmp; 426 TCPA_SYMMETRIC_KEY symKey; 427 TSS_CALLBACK *cb; 428 Trspi_HashCtx hashCtx; 429 TPM_SYM_CA_ATTESTATION symCAAttestation; 430 431 if (pulCredentialLength == NULL || prgbCredential == NULL) 432 return TSPERR(TSS_E_BAD_PARAMETER); 433 434 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 435 return result; 436 437 if ((result = obj_tpm_get_cb12(hTPM, TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY, &tmp, 438 &cb_var))) 439 return result; 440 441 cb = (TSS_CALLBACK *)cb_var; 442 if (cb->callback == NULL) { 443 free_tspi(tspContext, cb); 444 cb = NULL; 445 } 446 447 if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle))) 448 return result; 449 450 if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, 451 &hIDPolicy, &usesAuth))) 452 return result; 453 454 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hTPMPolicy))) 455 return result; 456 457 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 458 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); 459 result |= Trspi_Hash_UINT32(&hashCtx, ulAsymCAContentsBlobLength); 460 result |= Trspi_HashUpdate(&hashCtx, ulAsymCAContentsBlobLength, rgbAsymCAContentsBlob); 461 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 462 return result; 463 464 if (usesAuth) { 465 if ((result = secret_PerformAuth_OIAP(hIDPolicy, TPM_ORD_ActivateIdentity, 466 hIDPolicy, FALSE, &digest, &idKeyAuth))) 467 return result; 468 pIDKeyAuth = &idKeyAuth; 469 } else { 470 pIDKeyAuth = NULL; 471 } 472 473 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ActivateIdentity, hTPMPolicy, FALSE, 474 &digest, &ownerAuth))) 475 return result; 476 477 if ((result = TCS_API(tspContext)->ActivateTPMIdentity(tspContext, tcsKeyHandle, 478 ulAsymCAContentsBlobLength, 479 rgbAsymCAContentsBlob, pIDKeyAuth, 480 &ownerAuth, &symKeyBlobLen, 481 &symKeyBlob))) 482 return result; 483 484 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 485 result |= Trspi_Hash_UINT32(&hashCtx, result); 486 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); 487 result |= Trspi_HashUpdate(&hashCtx, symKeyBlobLen, symKeyBlob); 488 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 489 return result; 490 491 if (usesAuth) { 492 if ((result = obj_policy_validate_auth_oiap(hIDPolicy, &digest, 493 &idKeyAuth))) { 494 LogDebugFn("Identity key auth validation of the symmetric key failed."); 495 return result; 496 } 497 } 498 499 if ((result = obj_policy_validate_auth_oiap(hTPMPolicy, &digest, 500 &ownerAuth))) { 501 LogDebugFn("Owner auth validation of the symmetric key failed."); 502 return result; 503 } 504 505 offset = 0; 506 if ((result = Trspi_UnloadBlob_SYM_CA_ATTESTATION(&offset, rgbSymCAAttestationBlob, 507 &symCAAttestation))) { 508 LogDebugFn("Error unloading CA's attestation blob."); 509 return result; 510 } 511 512 if (cb && cb->callback) { 513 /* alloc the space for the callback to copy into */ 514 credCallback = calloc(1, ulSymCAAttestationBlobLength); 515 if (credCallback == NULL) { 516 LogDebug("malloc of %u bytes failed", ulSymCAAttestationBlobLength); 517 free(symKeyBlob); 518 free_tspi(tspContext, cb); 519 return TSPERR(TSS_E_INTERNAL_ERROR); 520 } 521 credLen = ulSymCAAttestationBlobLength; 522 523 if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, BYTE *, UINT32 *, 524 BYTE *))cb->callback)(cb->appData, symKeyBlobLen, symKeyBlob, 525 symCAAttestation.credSize, 526 symCAAttestation.credential, 527 &credLen, credCallback))) { 528 LogDebug("ActivateIdentity callback returned error 0x%x", result); 529 free(symCAAttestation.credential); 530 free(symKeyBlob); 531 free_tspi(tspContext, cb); 532 free(credCallback); 533 return TSPERR(TSS_E_INTERNAL_ERROR); 534 } 535 free(symCAAttestation.credential); 536 free_tspi(tspContext, cb); 537 free(symKeyBlob); 538 539 if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { 540 free(credCallback); 541 return TSPERR(TSS_E_OUTOFMEMORY); 542 } 543 544 memcpy(*prgbCredential, credCallback, credLen); 545 *pulCredentialLength = credLen; 546 free(credCallback); 547 548 return TSS_SUCCESS; 549 } 550 551 /* decrypt the symmetric blob using the recovered symmetric key */ 552 offset = 0; 553 if ((result = Trspi_UnloadBlob_SYMMETRIC_KEY(&offset, symKeyBlob, &symKey))) { 554 free(symCAAttestation.credential); 555 free(symKeyBlob); 556 return result; 557 } 558 free(symKeyBlob); 559 560 if ((result = Trspi_SymDecrypt(symKey.algId, symKey.encScheme, symKey.data, NULL, 561 symCAAttestation.credential, symCAAttestation.credSize, 562 credBlob, &credLen))) { 563 free(symCAAttestation.credential); 564 free(symKey.data); 565 return result; 566 } 567 free(symCAAttestation.credential); 568 569 if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { 570 free(symKey.data); 571 return TSPERR(TSS_E_OUTOFMEMORY); 572 } 573 574 free(symKey.data); 575 memcpy(*prgbCredential, credBlob, credLen); 576 *pulCredentialLength = credLen; 577 578 return TSS_SUCCESS; 579 } 580