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
Tspi_TPM_CollateIdentityRequest(TSS_HTPM hTPM,TSS_HKEY hKeySRK,TSS_HKEY hCAPubKey,UINT32 ulIdentityLabelLength,BYTE * rgbIdentityLabelData,TSS_HKEY hIdentityKey,TSS_ALGORITHM_ID algID,UINT32 * pulTcpaIdentityReqLength,BYTE ** prgbTcpaIdentityReq)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
Tspi_TPM_ActivateIdentity(TSS_HTPM hTPM,TSS_HKEY hIdentKey,UINT32 ulAsymCAContentsBlobLength,BYTE * rgbAsymCAContentsBlob,UINT32 ulSymCAAttestationBlobLength,BYTE * rgbSymCAAttestationBlob,UINT32 * pulCredentialLength,BYTE ** prgbCredential)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