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