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
30 TSS_RESULT
secret_PerformAuth_OIAP(TSS_HOBJECT hAuthorizedObject,UINT32 ulPendingFn,TSS_HPOLICY hPolicy,TSS_BOOL cas,TCPA_DIGEST * hashDigest,TPM_AUTH * auth)31 secret_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
125 TSS_RESULT
126 secret_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
225 TSS_RESULT
226 secret_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
287 TSS_RESULT
288 secret_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
339 TSS_RESULT
Init_AuthNonce(TSS_HCONTEXT tspContext,TSS_BOOL cas,TPM_AUTH * auth)340 Init_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
354 TSS_BOOL
validateReturnAuth(BYTE * secret,BYTE * hash,TPM_AUTH * auth)355 validateReturnAuth(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
365 void
HMAC_Auth(BYTE * secret,BYTE * Digest,TPM_AUTH * auth)366 HMAC_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
380 TSS_RESULT
OSAP_Calc(TSS_HCONTEXT tspContext,UINT16 EntityType,UINT32 EntityValue,BYTE * authSecret,BYTE * usageSecret,BYTE * migSecret,TCPA_ENCAUTH * encAuthUsage,TCPA_ENCAUTH * encAuthMig,BYTE * sharedSecret,TPM_AUTH * auth)381 OSAP_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
449 TSS_RESULT
obj_policy_validate_auth_oiap(TSS_HPOLICY hPolicy,TCPA_DIGEST * hashDigest,TPM_AUTH * auth)450 obj_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
498 TSS_RESULT
499 authsess_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
604 TSS_RESULT
605 authsess_oiap_put(TPM_AUTH *auth)
606 {
607 }
608 #endif
609
610 #ifdef TSS_BUILD_DELEGATION
611 TSS_RESULT
authsess_do_dsap(struct authsess * sess)612 authsess_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
647 TSS_RESULT
authsess_do_osap(struct authsess * sess)648 authsess_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
679 TSS_RESULT
authsess_callback_xor(PVOID lpAppData,TSS_HOBJECT hOSAPObject,TSS_HOBJECT hObject,TSS_FLAG PurposeSecret,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeEncAuth,BYTE * rgbEncAuthUsage,BYTE * rgbEncAuthMigration)680 authsess_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
723 TSS_RESULT
authsess_callback_hmac(PVOID lpAppData,TSS_HOBJECT hAuthorizedObject,TSS_BOOL ReturnOrVerify,UINT32 ulPendingFunction,TSS_BOOL ContinueUse,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeDigestHmac,BYTE * rgbParamDigest,BYTE * rgbHmacData)724 authsess_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 */
767 TSS_RESULT
authsess_xsap_init(TSS_HCONTEXT tspContext,TSS_HOBJECT obj_parent,TSS_HOBJECT obj_child,TSS_BOOL requirements,TPM_COMMAND_CODE command,TPM_ENTITY_TYPE entity_type,struct authsess ** xsess)768 authsess_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
1026 done:
1027 *xsess = sess;
1028
1029 return TSS_SUCCESS;
1030 error:
1031 free(sess);
1032 return result;
1033 }
1034
1035 TSS_RESULT
authsess_xsap_hmac(struct authsess * sess,TPM_DIGEST * digest)1036 authsess_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
1074 TSS_RESULT
authsess_xsap_verify(struct authsess * sess,TPM_DIGEST * digest)1075 authsess_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
1094 TSS_RESULT
__tspi_free_resource(TSS_HCONTEXT tspContext,UINT32 handle,UINT32 resourceType)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
1126 void
authsess_free(struct authsess * xsap)1127 authsess_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
1140 TSS_RESULT
Transport_OIAP(TSS_HCONTEXT tspContext,TCS_AUTHHANDLE * authHandle,TPM_NONCE * nonce0)1141 Transport_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
1170 TSS_RESULT
Transport_OSAP(TSS_HCONTEXT tspContext,TPM_ENTITY_TYPE entityType,UINT32 entityValue,TPM_NONCE * nonceOddOSAP,TCS_AUTHHANDLE * authHandle,TPM_NONCE * nonceEven,TPM_NONCE * nonceEvenOSAP)1171 Transport_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
1209 TSS_RESULT
Transport_TerminateHandle(TSS_HCONTEXT tspContext,TCS_AUTHHANDLE handle)1210 Transport_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