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