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. 2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "spi_utils.h"
20 #include "obj.h"
21 #include "tsplog.h"
22 #include "tsp_delegate.h"
23 #include "authsess.h"
24 
25 
26 TSS_RESULT
do_delegate_manage(TSS_HTPM hTpm,UINT32 familyID,UINT32 opFlag,UINT32 opDataSize,BYTE * opData,UINT32 * outDataSize,BYTE ** outData)27 do_delegate_manage(TSS_HTPM hTpm, UINT32 familyID, UINT32 opFlag,
28                        UINT32 opDataSize, BYTE *opData, UINT32 *outDataSize, BYTE **outData)
29 {
30           TSS_HCONTEXT hContext;
31           TSS_HPOLICY hPolicy;
32           UINT32 secretMode = TSS_SECRET_MODE_NONE;
33           Trspi_HashCtx hashCtx;
34           TCPA_DIGEST digest;
35           TPM_AUTH ownerAuth, *pAuth;
36           UINT32 retDataSize;
37           BYTE *retData = NULL;
38           TSS_RESULT result;
39 
40           if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
41                     return result;
42 
43           if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
44                     return result;
45 
46           if (hPolicy != NULL_HPOLICY) {
47                     if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
48                               return result;
49           }
50 
51           if (secretMode != TSS_SECRET_MODE_NONE) {
52                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
53                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
54                     result |= Trspi_Hash_UINT32(&hashCtx, familyID);
55                     result |= Trspi_Hash_UINT32(&hashCtx, opFlag);
56                     result |= Trspi_Hash_UINT32(&hashCtx, opDataSize);
57                     result |= Trspi_HashUpdate(&hashCtx, opDataSize, opData);
58                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
59                               return result;
60 
61                     pAuth = &ownerAuth;
62                     if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_Manage, hPolicy, FALSE,
63                                                                   &digest, pAuth)))
64                               return result;
65           } else
66                     pAuth = NULL;
67 
68           /* Perform the delegation operation */
69           if ((result = TCS_API(hContext)->Delegate_Manage(hContext, familyID, opFlag, opDataSize,
70                                                                        opData, pAuth, &retDataSize, &retData)))
71                     return result;
72 
73           if (pAuth) {
74                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
75                     result |= Trspi_Hash_UINT32(&hashCtx, result);
76                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
77                     result |= Trspi_Hash_UINT32(&hashCtx, retDataSize);
78                     result |= Trspi_HashUpdate(&hashCtx, retDataSize, retData);
79                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
80                               free(retData);
81                               goto done;
82                     }
83 
84                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
85                               free(retData);
86                               goto done;
87                     }
88           }
89 
90           *outDataSize = retDataSize;
91           *outData = retData;
92 
93 done:
94           return result;
95 }
96 
97 TSS_RESULT
create_owner_delegation(TSS_HTPM hTpm,BYTE bLabel,UINT32 ulFlags,TSS_HPCRS hPcrs,TSS_HDELFAMILY hFamily,TSS_HPOLICY hDelegation)98 create_owner_delegation(TSS_HTPM       hTpm,
99                               BYTE           bLabel,
100                               UINT32         ulFlags,
101                               TSS_HPCRS      hPcrs,
102                               TSS_HDELFAMILY hFamily,
103                               TSS_HPOLICY    hDelegation)
104 {
105           TSS_HCONTEXT hContext;
106           TSS_BOOL incrementCount = FALSE;
107           UINT32 type;
108           UINT32 publicInfoSize;
109           BYTE *publicInfo = NULL;
110           Trspi_HashCtx hashCtx;
111           TCPA_DIGEST digest;
112           UINT32 blobSize;
113           BYTE *blob = NULL;
114           TSS_RESULT result;
115           struct authsess *xsap = NULL;
116 
117           if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
118                     return result;
119 
120           if ((ulFlags & ~TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT) > 0)
121                     return TSPERR(TSS_E_BAD_PARAMETER);
122 
123           if (ulFlags & TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT)
124                     incrementCount = TRUE;
125 
126           if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
127                     return result;
128 
129           if (type != TSS_DELEGATIONTYPE_OWNER)
130                     return TSPERR(TSS_E_BAD_PARAMETER);
131 
132           if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
133                               &publicInfoSize, &publicInfo)))
134                     return result;
135 
136           if ((result = authsess_xsap_init(hContext, hTpm, hDelegation, TSS_AUTH_POLICY_NOT_REQUIRED,
137                                                    TPM_ORD_Delegate_CreateOwnerDelegation, TPM_ET_OWNER,
138                                                    &xsap))) {
139                     free(publicInfo);
140                     return result;
141           }
142 
143           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
144           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
145           result |= Trspi_Hash_BOOL(&hashCtx, incrementCount);
146           result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
147           result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
148           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
149                     goto done;
150 
151           if ((result = authsess_xsap_hmac(xsap, &digest)))
152                     goto done;
153 
154           /* Create the delegation */
155           if ((result = TCS_API(hContext)->Delegate_CreateOwnerDelegation(hContext, incrementCount,
156                                                                                           publicInfoSize, publicInfo,
157                                                                                           &xsap->encAuthUse,
158                                                                                           xsap->pAuth, &blobSize,
159                                                                                           &blob)))
160                     goto done;
161 
162           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
163           result |= Trspi_Hash_UINT32(&hashCtx, result);
164           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
165           result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
166           result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
167           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
168                     goto done;
169 
170           if (authsess_xsap_verify(xsap, &digest)) {
171                     result = TSPERR(TSS_E_TSP_AUTHFAIL);
172                     goto done;
173           }
174 
175           result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER,
176                               blobSize, blob);
177 
178 done:
179           authsess_free(xsap);
180           free(publicInfo);
181           free(blob);
182 
183           return result;
184 }
185 
186 TSS_RESULT
create_key_delegation(TSS_HKEY hKey,BYTE bLabel,UINT32 ulFlags,TSS_HPCRS hPcrs,TSS_HDELFAMILY hFamily,TSS_HPOLICY hDelegation)187 create_key_delegation(TSS_HKEY       hKey,
188                           BYTE           bLabel,
189                           UINT32         ulFlags,
190                           TSS_HPCRS      hPcrs,
191                           TSS_HDELFAMILY hFamily,
192                           TSS_HPOLICY    hDelegation)
193 {
194           TSS_HCONTEXT hContext;
195           UINT32 type;
196           TCS_KEY_HANDLE tcsKeyHandle;
197           UINT32 publicInfoSize;
198           BYTE *publicInfo = NULL;
199           Trspi_HashCtx hashCtx;
200           TCPA_DIGEST digest;
201           UINT32 blobSize;
202           BYTE *blob = NULL;
203           TSS_RESULT result;
204           struct authsess *xsap = NULL;
205 
206           if ((result = obj_rsakey_get_tsp_context(hKey, &hContext)))
207                     return result;
208 
209           if (ulFlags != 0)
210                     return TSPERR(TSS_E_BAD_PARAMETER);
211 
212           if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
213                     return result;
214 
215           if (type != TSS_DELEGATIONTYPE_KEY)
216                     return TSPERR(TSS_E_BAD_PARAMETER);
217 
218           if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
219                     return result;
220 
221           if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
222                               &publicInfoSize, &publicInfo)))
223                     return result;
224 
225           if ((result = authsess_xsap_init(hContext, hKey, hDelegation, TSS_AUTH_POLICY_REQUIRED,
226                                                    TPM_ORD_Delegate_CreateKeyDelegation, TPM_ET_KEYHANDLE,
227                                                    &xsap))) {
228                     free(publicInfo);
229                     return result;
230           }
231 
232           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
233           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
234           result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
235           result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
236           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
237                     goto done;
238 
239           if ((result = authsess_xsap_hmac(xsap, &digest)))
240                     goto done;
241 
242           /* Create the delegation */
243           if ((result = TCS_API(hContext)->Delegate_CreateKeyDelegation(hContext, tcsKeyHandle,
244                                                                                       publicInfoSize, publicInfo,
245                                                                                       &xsap->encAuthUse,
246                                                                                       xsap->pAuth, &blobSize,
247                                                                                       &blob)))
248                     goto done;
249 
250           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
251           result |= Trspi_Hash_UINT32(&hashCtx, result);
252           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
253           result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
254           result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
255           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
256                     goto done;
257 
258           if (authsess_xsap_verify(xsap, &digest)) {
259                     result = TSPERR(TSS_E_TSP_AUTHFAIL);
260                     goto done;
261           }
262 
263           result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_KEY, blobSize,
264                                                             blob);
265 
266 done:
267           free(blob);
268           authsess_free(xsap);
269           free(publicInfo);
270 
271           return result;
272 }
273 
274 TSS_RESULT
update_delfamily_object(TSS_HTPM hTpm,UINT32 familyID)275 update_delfamily_object(TSS_HTPM hTpm, UINT32 familyID)
276 {
277           TSS_HCONTEXT hContext;
278           UINT32 familyTableSize, delegateTableSize;
279           BYTE *familyTable = NULL, *delegateTable = NULL;
280           UINT64 offset;
281           TPM_FAMILY_TABLE_ENTRY familyTableEntry;
282           TSS_BOOL familyState;
283           TSS_HDELFAMILY hFamily;
284           TSS_RESULT result;
285 
286           if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
287                     return result;
288 
289           if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
290                                                                           &familyTable, &delegateTableSize,
291                                                                           &delegateTable)))
292                     return result;
293 
294           for (offset = 0; offset < familyTableSize;) {
295                     Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&offset, familyTable, &familyTableEntry);
296                     if (familyTableEntry.familyID == familyID) {
297                               obj_delfamily_find_by_familyid(hContext, familyID, &hFamily);
298                               if (hFamily == NULL_HDELFAMILY) {
299                                         if ((result = obj_delfamily_add(hContext, &hFamily)))
300                                                   goto done;
301                                         if ((result = obj_delfamily_set_familyid(hFamily,
302                                                                                            familyTableEntry.familyID)))
303                                                   goto done;
304                                         if ((result = obj_delfamily_set_label(hFamily,
305                                                                                       familyTableEntry.label.label)))
306                                                   goto done;
307                               }
308 
309                               /* Set/Update the family attributes */
310                               familyState = (familyTableEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ?
311                                               TRUE : FALSE;
312                               if ((result = obj_delfamily_set_locked(hFamily, familyState, FALSE)))
313                                         goto done;
314                               familyState = (familyTableEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE;
315                               if ((result = obj_delfamily_set_enabled(hFamily, familyState, FALSE)))
316                                         goto done;
317                               if ((result = obj_delfamily_set_vercount(hFamily,
318                                                                                  familyTableEntry.verificationCount)))
319                                         goto done;
320 
321                               break;
322                     }
323           }
324 
325 done:
326           free(familyTable);
327           free(delegateTable);
328 
329           return result;
330 }
331 
332 TSS_RESULT
get_delegate_index(TSS_HCONTEXT hContext,UINT32 index,TPM_DELEGATE_PUBLIC * public)333 get_delegate_index(TSS_HCONTEXT hContext, UINT32 index, TPM_DELEGATE_PUBLIC *public)
334 {
335           UINT32 familyTableSize, delegateTableSize;
336           BYTE *familyTable = NULL, *delegateTable = NULL;
337           UINT64 offset;
338           UINT32 tpmIndex;
339           TPM_DELEGATE_PUBLIC tempPublic;
340           TSS_RESULT result;
341 
342           if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
343                                                                           &familyTable, &delegateTableSize,
344                                                                           &delegateTable)))
345                     goto done;
346 
347           for (offset = 0; offset < delegateTableSize;) {
348                     Trspi_UnloadBlob_UINT32(&offset, &tpmIndex, delegateTable);
349                     if (tpmIndex == index) {
350                               result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, public);
351                               goto done;
352                     } else {
353                               if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, &tempPublic)))
354                                         goto done;
355                     }
356 
357                     free(tempPublic.pcrInfo.pcrSelection.pcrSelect);
358           }
359 
360           /* Didn't find a matching index */
361           result = TSPERR(TSS_E_BAD_PARAMETER);
362 
363 done:
364           free(familyTable);
365           free(delegateTable);
366 
367           return result;
368 }
369 
370 TSS_RESULT
__tspi_build_delegate_public_info(BYTE bLabel,TSS_HPCRS hPcrs,TSS_HDELFAMILY hFamily,TSS_HPOLICY hDelegation,UINT32 * publicInfoSize,BYTE ** publicInfo)371 __tspi_build_delegate_public_info(BYTE           bLabel,
372                                  TSS_HPCRS      hPcrs,
373                                  TSS_HDELFAMILY hFamily,
374                                  TSS_HPOLICY    hDelegation,
375                                  UINT32        *publicInfoSize,
376                                  BYTE         **publicInfo)
377 {
378           TPM_DELEGATE_PUBLIC public;
379           UINT32 delegateType;
380           UINT32 pcrInfoSize;
381           BYTE *pcrInfo = NULL;
382           UINT64 offset;
383           TSS_RESULT result = TSS_SUCCESS;
384 
385           if (hDelegation == NULL_HPOLICY)
386                     return TSPERR(TSS_E_BAD_PARAMETER);
387 
388           if ((result = obj_policy_get_delegation_type(hDelegation, &delegateType)))
389                     return result;
390 
391           /* This call will create a "null" PCR_INFO_SHORT if hPcrs is null */
392           if ((result = obj_pcrs_create_info_short(hPcrs, &pcrInfoSize, &pcrInfo)))
393                     return result;
394 
395           __tspi_memset(&public, 0, sizeof(public));
396           public.tag = TPM_TAG_DELEGATE_PUBLIC;
397           public.label.label = bLabel;
398           offset = 0;
399           if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrInfo, &public.pcrInfo)))
400                     goto done;
401           public.permissions.tag = TPM_TAG_DELEGATIONS;
402           public.permissions.delegateType =
403                     (delegateType == TSS_DELEGATIONTYPE_OWNER) ? TPM_DEL_OWNER_BITS : TPM_DEL_KEY_BITS;
404           if ((result = obj_policy_get_delegation_per1(hDelegation, &public.permissions.per1)))
405                     goto done;
406           if ((result = obj_policy_get_delegation_per2(hDelegation, &public.permissions.per2)))
407                     goto done;
408           if ((result = obj_delfamily_get_familyid(hFamily, &public.familyID)))
409                     goto done;
410           if ((result = obj_delfamily_get_vercount(hFamily, &public.verificationCount)))
411                     goto done;
412 
413           offset = 0;
414           Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, NULL, &public);
415           *publicInfoSize = offset;
416           *publicInfo = malloc(*publicInfoSize);
417           if (*publicInfo == NULL) {
418                     LogError("malloc of %u bytes failed.", *publicInfoSize);
419                     result = TSPERR(TSS_E_OUTOFMEMORY);
420                     goto done;
421           }
422           offset = 0;
423           Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, *publicInfo, &public);
424 
425 done:
426           free(pcrInfo);
427           free(public.pcrInfo.pcrSelection.pcrSelect);
428 
429           return result;
430 }
431 
432 #ifdef TSS_BUILD_TRANSPORT
433 TSS_RESULT
Transport_Delegate_Manage(TSS_HCONTEXT tspContext,TPM_FAMILY_ID familyID,TPM_FAMILY_OPERATION opFlag,UINT32 opDataSize,BYTE * opData,TPM_AUTH * ownerAuth,UINT32 * retDataSize,BYTE ** retData)434 Transport_Delegate_Manage(TSS_HCONTEXT tspContext,              /* in */
435                                 TPM_FAMILY_ID familyID,             /* in */
436                                 TPM_FAMILY_OPERATION opFlag,        /* in */
437                                 UINT32 opDataSize,                  /* in */
438                                 BYTE *opData,                       /* in */
439                                 TPM_AUTH *ownerAuth,                /* in, out */
440                                 UINT32 *retDataSize,                /* out */
441                                 BYTE **retData)                     /* out */
442 {
443           TSS_RESULT result;
444           UINT32 handlesLen = 0, decLen, dataLen;
445           UINT64 offset;
446           BYTE *data, *dec = NULL;
447 
448 
449           if ((result = obj_context_transport_init(tspContext)))
450                     return result;
451 
452           LogDebugFn("Executing in a transport session");
453 
454           dataLen = sizeof(TPM_FAMILY_ID)
455                       + sizeof(TPM_FAMILY_OPERATION)
456                       + sizeof(UINT32)
457                       + opDataSize;
458           if ((data = malloc(dataLen)) == NULL) {
459                     LogError("malloc of %u bytes failed", dataLen);
460                     return TSPERR(TSS_E_OUTOFMEMORY);
461           }
462 
463           offset = 0;
464           Trspi_LoadBlob_UINT32(&offset, familyID, data);
465           Trspi_LoadBlob_UINT32(&offset, opFlag, data);
466           Trspi_LoadBlob_UINT32(&offset, opDataSize, data);
467           Trspi_LoadBlob(&offset, opDataSize, data, opData);
468 
469           if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_Manage, dataLen,
470                                                                 data, NULL, &handlesLen, NULL, ownerAuth,
471                                                                 NULL, &decLen, &dec))) {
472                     free(data);
473                     return result;
474           }
475           free(data);
476 
477           offset = 0;
478           Trspi_UnloadBlob_UINT32(&offset, retDataSize, dec);
479 
480           if ((*retData = malloc(*retDataSize)) == NULL) {
481                     free(dec);
482                     LogError("malloc of %u bytes failed", *retDataSize);
483                     *retDataSize = 0;
484                     return TSPERR(TSS_E_OUTOFMEMORY);
485           }
486           Trspi_UnloadBlob(&offset, *retDataSize, dec, *retData);
487 
488           free(dec);
489 
490           return result;
491 }
492 
493 TSS_RESULT
Transport_Delegate_CreateKeyDelegation(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey,UINT32 publicInfoSize,BYTE * publicInfo,TPM_ENCAUTH * encDelAuth,TPM_AUTH * keyAuth,UINT32 * blobSize,BYTE ** blob)494 Transport_Delegate_CreateKeyDelegation(TSS_HCONTEXT tspContext,         /* in */
495                                                TCS_KEY_HANDLE hKey,           /* in */
496                                                UINT32 publicInfoSize,         /* in */
497                                                BYTE *publicInfo,              /* in */
498                                                TPM_ENCAUTH *encDelAuth,        /* in */
499                                                TPM_AUTH *keyAuth,             /* in, out */
500                                                UINT32 *blobSize,              /* out */
501                                                BYTE **blob)                   /* out */
502 {
503           TSS_RESULT result;
504           UINT32 handlesLen, decLen, dataLen;
505           TCS_HANDLE *handles, handle;
506           TPM_DIGEST pubKeyHash;
507           Trspi_HashCtx hashCtx;
508           UINT64 offset;
509           BYTE *data, *dec = NULL;
510 
511           if ((result = obj_context_transport_init(tspContext)))
512                     return result;
513 
514           LogDebugFn("Executing in a transport session");
515 
516           if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
517                     return result;
518 
519           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
520           result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
521           if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
522                     return result;
523 
524           handlesLen = 1;
525           handle = hKey;
526           handles = &handle;
527 
528           dataLen = publicInfoSize + sizeof(TPM_ENCAUTH);
529           if ((data = malloc(dataLen)) == NULL) {
530                     LogError("malloc of %u bytes failed", dataLen);
531                     return TSPERR(TSS_E_OUTOFMEMORY);
532           }
533 
534           offset = 0;
535           Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
536           Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
537 
538           if ((result = obj_context_transport_execute(tspContext,
539                                                                 TPM_ORD_Delegate_CreateKeyDelegation, dataLen,
540                                                                 data, &pubKeyHash, &handlesLen, &handles,
541                                                                 keyAuth, NULL, &decLen, &dec))) {
542                     free(data);
543                     return result;
544           }
545           free(data);
546 
547           offset = 0;
548           Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
549 
550           if ((*blob = malloc(*blobSize)) == NULL) {
551                     free(dec);
552                     LogError("malloc of %u bytes failed", *blobSize);
553                     *blobSize = 0;
554                     return TSPERR(TSS_E_OUTOFMEMORY);
555           }
556           Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
557 
558           free(dec);
559 
560           return result;
561 }
562 
563 TSS_RESULT
Transport_Delegate_CreateOwnerDelegation(TSS_HCONTEXT tspContext,TSS_BOOL increment,UINT32 publicInfoSize,BYTE * publicInfo,TPM_ENCAUTH * encDelAuth,TPM_AUTH * ownerAuth,UINT32 * blobSize,BYTE ** blob)564 Transport_Delegate_CreateOwnerDelegation(TSS_HCONTEXT tspContext,       /* in */
565                                                    TSS_BOOL increment,          /* in */
566                                                    UINT32 publicInfoSize,       /* in */
567                                                    BYTE *publicInfo,            /* in */
568                                                    TPM_ENCAUTH *encDelAuth,      /* in */
569                                                    TPM_AUTH *ownerAuth,         /* in, out */
570                                                    UINT32 *blobSize,            /* out */
571                                                    BYTE **blob)                 /* out */
572 {
573           TSS_RESULT result;
574           UINT32 handlesLen = 0, decLen, dataLen;
575           UINT64 offset;
576           BYTE *data, *dec = NULL;
577 
578           if ((result = obj_context_transport_init(tspContext)))
579                     return result;
580 
581           LogDebugFn("Executing in a transport session");
582 
583           dataLen = sizeof(TSS_BOOL) + publicInfoSize + sizeof(TPM_ENCAUTH);
584           if ((data = malloc(dataLen)) == NULL) {
585                     LogError("malloc of %u bytes failed", dataLen);
586                     return TSPERR(TSS_E_OUTOFMEMORY);
587           }
588 
589           offset = 0;
590           Trspi_LoadBlob_BOOL(&offset, increment, data);
591           Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
592           Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
593 
594           if ((result = obj_context_transport_execute(tspContext,
595                                                                 TPM_ORD_Delegate_CreateOwnerDelegation, dataLen,
596                                                                 data, NULL, &handlesLen, NULL, ownerAuth,
597                                                                 NULL, &decLen, &dec))) {
598                     free(data);
599                     return result;
600           }
601           free(data);
602 
603           offset = 0;
604           Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
605 
606           if ((*blob = malloc(*blobSize)) == NULL) {
607                     free(dec);
608                     LogError("malloc of %u bytes failed", *blobSize);
609                     *blobSize = 0;
610                     return TSPERR(TSS_E_OUTOFMEMORY);
611           }
612           Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
613 
614           free(dec);
615 
616           return result;
617 }
618 
619 TSS_RESULT
Transport_Delegate_LoadOwnerDelegation(TSS_HCONTEXT tspContext,TPM_DELEGATE_INDEX index,UINT32 blobSize,BYTE * blob,TPM_AUTH * ownerAuth)620 Transport_Delegate_LoadOwnerDelegation(TSS_HCONTEXT tspContext, /* in */
621                                                TPM_DELEGATE_INDEX index,      /* in */
622                                                UINT32 blobSize,               /* in */
623                                                BYTE *blob,                    /* in */
624                                                TPM_AUTH *ownerAuth)           /* in, out */
625 {
626           TSS_RESULT result;
627           UINT32 handlesLen = 0, dataLen, decLen;
628           UINT64 offset;
629           BYTE *data, *dec = NULL;
630 
631           if ((result = obj_context_transport_init(tspContext)))
632                     return result;
633 
634           LogDebugFn("Executing in a transport session");
635 
636           dataLen = sizeof(TPM_DELEGATE_INDEX) + sizeof(UINT32) + blobSize;
637           if ((data = malloc(dataLen)) == NULL) {
638                     LogError("malloc of %u bytes failed", dataLen);
639                     return TSPERR(TSS_E_OUTOFMEMORY);
640           }
641 
642           offset = 0;
643           Trspi_LoadBlob_UINT32(&offset, index, data);
644           Trspi_LoadBlob_UINT32(&offset, blobSize, data);
645           Trspi_LoadBlob(&offset, blobSize, data, blob);
646 
647           if ((result = obj_context_transport_execute(tspContext,
648                                                                 TPM_ORD_Delegate_LoadOwnerDelegation, dataLen,
649                                                                 data, NULL, &handlesLen, NULL, ownerAuth,
650                                                                 NULL, &decLen, &dec))) {
651                     free(data);
652                     return result;
653           }
654           free(data);
655           free(dec);
656 
657           return result;
658 }
659 
660 TSS_RESULT
Transport_Delegate_ReadTable(TSS_HCONTEXT tspContext,UINT32 * familyTableSize,BYTE ** familyTable,UINT32 * delegateTableSize,BYTE ** delegateTable)661 Transport_Delegate_ReadTable(TSS_HCONTEXT tspContext,           /* in */
662                                    UINT32 *familyTableSize,         /* out */
663                                    BYTE **familyTable,              /* out */
664                                    UINT32 *delegateTableSize,       /* out */
665                                    BYTE **delegateTable)            /* out */
666 {
667           TSS_RESULT result;
668           UINT32 handlesLen = 0, decLen;
669           UINT64 offset;
670           BYTE *dec = NULL;
671 
672           if ((result = obj_context_transport_init(tspContext)))
673                     return result;
674 
675           LogDebugFn("Executing in a transport session");
676 
677           if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_ReadTable, 0, NULL,
678                                                                 NULL, &handlesLen, NULL, NULL, NULL, &decLen,
679                                                                 &dec)))
680                     return result;
681 
682           offset = 0;
683           Trspi_UnloadBlob_UINT32(&offset, familyTableSize, dec);
684 
685           if ((*familyTable = malloc(*familyTableSize)) == NULL) {
686                     free(dec);
687                     LogError("malloc of %u bytes failed", *familyTableSize);
688                     *familyTableSize = 0;
689                     return TSPERR(TSS_E_OUTOFMEMORY);
690           }
691           Trspi_UnloadBlob(&offset, *familyTableSize, dec, *familyTable);
692 
693           Trspi_UnloadBlob_UINT32(&offset, delegateTableSize, dec);
694 
695           if ((*delegateTable = malloc(*delegateTableSize)) == NULL) {
696                     free(dec);
697                     free(*familyTable);
698                     *familyTable = NULL;
699                     *familyTableSize = 0;
700                     LogError("malloc of %u bytes failed", *delegateTableSize);
701                     *delegateTableSize = 0;
702                     return TSPERR(TSS_E_OUTOFMEMORY);
703           }
704           Trspi_UnloadBlob(&offset, *delegateTableSize, dec, *delegateTable);
705 
706           free(dec);
707 
708           return result;
709 }
710 
711 TSS_RESULT
Transport_Delegate_UpdateVerificationCount(TSS_HCONTEXT tspContext,UINT32 inputSize,BYTE * input,TPM_AUTH * ownerAuth,UINT32 * outputSize,BYTE ** output)712 Transport_Delegate_UpdateVerificationCount(TSS_HCONTEXT tspContext,     /* in */
713                                                      UINT32 inputSize,          /* in */
714                                                      BYTE *input,               /* in */
715                                                      TPM_AUTH *ownerAuth,       /* in, out */
716                                                      UINT32 *outputSize,        /* out */
717                                                      BYTE **output)             /* out */
718 {
719           TSS_RESULT result;
720           UINT32 handlesLen = 0, decLen, dataLen;
721           UINT64 offset;
722           BYTE *data, *dec = NULL;
723 
724 
725           if ((result = obj_context_transport_init(tspContext)))
726                     return result;
727 
728           LogDebugFn("Executing in a transport session");
729 
730           dataLen = sizeof(UINT32) + inputSize;
731           if ((data = malloc(dataLen)) == NULL) {
732                     LogError("malloc of %u bytes failed", dataLen);
733                     return TSPERR(TSS_E_OUTOFMEMORY);
734           }
735 
736           offset = 0;
737           Trspi_LoadBlob_UINT32(&offset, inputSize, data);
738           Trspi_LoadBlob(&offset, inputSize, data, input);
739 
740           if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_UpdateVerification,
741                                                                 dataLen, data, NULL, &handlesLen, NULL,
742                                                                 ownerAuth, NULL, &decLen, &dec))) {
743                     free(data);
744                     return result;
745           }
746           free(data);
747 
748           offset = 0;
749           Trspi_UnloadBlob_UINT32(&offset, outputSize, dec);
750 
751           if ((*output = malloc(*outputSize)) == NULL) {
752                     free(dec);
753                     LogError("malloc of %u bytes failed", *outputSize);
754                     *outputSize = 0;
755                     return TSPERR(TSS_E_OUTOFMEMORY);
756           }
757           Trspi_UnloadBlob(&offset, *outputSize, dec, *output);
758 
759           free(dec);
760 
761           return result;
762 }
763 
764 TSS_RESULT
Transport_Delegate_VerifyDelegation(TSS_HCONTEXT tspContext,UINT32 delegateSize,BYTE * delegate)765 Transport_Delegate_VerifyDelegation(TSS_HCONTEXT tspContext,    /* in */
766                                             UINT32 delegateSize,      /* in */
767                                             BYTE *delegate)           /* in */
768 {
769           TSS_RESULT result;
770           UINT32 handlesLen = 0, dataLen, decLen;
771           UINT64 offset;
772           BYTE *data, *dec = NULL;
773 
774 
775           if ((result = obj_context_transport_init(tspContext)))
776                     return result;
777 
778           LogDebugFn("Executing in a transport session");
779 
780           dataLen = + sizeof(UINT32) + delegateSize;
781           if ((data = malloc(dataLen)) == NULL) {
782                     LogError("malloc of %u bytes failed", dataLen);
783                     return TSPERR(TSS_E_OUTOFMEMORY);
784           }
785 
786           offset = 0;
787           Trspi_LoadBlob_UINT32(&offset, delegateSize, data);
788           Trspi_LoadBlob(&offset, delegateSize, data, delegate);
789 
790           result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_VerifyDelegation,
791                                                          dataLen, data, NULL, &handlesLen, NULL, NULL, NULL,
792                                                          &decLen, &dec);
793           free(data);
794           free(dec);
795 
796           return result;
797 }
798 
799 TSS_RESULT
Transport_DSAP(TSS_HCONTEXT tspContext,TPM_ENTITY_TYPE entityType,TCS_KEY_HANDLE keyHandle,TPM_NONCE * nonceOddDSAP,UINT32 entityValueSize,BYTE * entityValue,TCS_AUTHHANDLE * authHandle,TPM_NONCE * nonceEven,TPM_NONCE * nonceEvenDSAP)800 Transport_DSAP(TSS_HCONTEXT tspContext,           /* in */
801                  TPM_ENTITY_TYPE entityType,      /* in */
802                  TCS_KEY_HANDLE keyHandle,        /* in */
803                  TPM_NONCE *nonceOddDSAP,                   /* in */
804                  UINT32 entityValueSize,                    /* in */
805                  BYTE * entityValue,              /* in */
806                  TCS_AUTHHANDLE *authHandle,      /* out */
807                  TPM_NONCE *nonceEven,            /* out */
808                  TPM_NONCE *nonceEvenDSAP)        /* out */
809 {
810           TSS_RESULT result;
811           UINT32 handlesLen, dataLen, decLen;
812           TCS_HANDLE *handles, handle;
813           TPM_DIGEST pubKeyHash;
814           Trspi_HashCtx hashCtx;
815           UINT64 offset;
816           BYTE *data, *dec = NULL;
817 
818           if ((result = obj_context_transport_init(tspContext)))
819                     return result;
820 
821           LogDebugFn("Executing in a transport session");
822 
823           if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
824                     return result;
825 
826           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
827           result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
828           if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
829                     return result;
830 
831           dataLen = sizeof(TPM_ENTITY_TYPE) + sizeof(TPM_KEY_HANDLE)
832                                                     + sizeof(TPM_NONCE)
833                                                     + sizeof(UINT32)
834                                                     + entityValueSize;
835           if ((data = malloc(dataLen)) == NULL) {
836                     LogError("malloc of %u bytes failed", dataLen);
837                     return TSPERR(TSS_E_OUTOFMEMORY);
838           }
839 
840           handlesLen = 1;
841           handle = keyHandle;
842           handles = &handle;
843 
844           offset = 0;
845           Trspi_LoadBlob_UINT32(&offset, entityType, data);
846           Trspi_LoadBlob_UINT32(&offset, keyHandle, data);
847           Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), data, nonceEvenDSAP->nonce);
848           Trspi_LoadBlob_UINT32(&offset, entityValueSize, data);
849           Trspi_LoadBlob(&offset, entityValueSize, data, entityValue);
850 
851           if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DSAP, dataLen, data,
852                                                                 &pubKeyHash, &handlesLen, &handles, NULL, NULL,
853                                                                 &decLen, &dec))) {
854                     free(data);
855                     return result;
856           }
857           free(data);
858 
859           offset = 0;
860           Trspi_UnloadBlob_UINT32(&offset, authHandle, dec);
861 
862           Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEven->nonce);
863           Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEvenDSAP->nonce);
864 
865           free(dec);
866 
867           return result;
868 }
869 #endif
870