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. 2005, 2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers/trousers.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "capabilities.h"
22 #include "tsplog.h"
23 #include "obj.h"
24 #include "tsp_delegate.h"
25 #include "authsess.h"
26 
27 
28 TSS_RESULT
obj_policy_add(TSS_HCONTEXT tsp_context,UINT32 type,TSS_HOBJECT * phObject)29 obj_policy_add(TSS_HCONTEXT tsp_context, UINT32 type, TSS_HOBJECT *phObject)
30 {
31           struct tr_policy_obj *policy;
32           TSS_RESULT result;
33 
34           if ((policy = calloc(1, sizeof(struct tr_policy_obj))) == NULL) {
35                     LogError("malloc of %zd bytes failed", sizeof(struct tr_policy_obj));
36                     return TSPERR(TSS_E_OUTOFMEMORY);
37           }
38 
39           policy->type = type;
40 #ifndef TSS_SPEC_COMPLIANCE
41           policy->SecretMode = TSS_SECRET_MODE_NONE;
42 #else
43           policy->SecretMode = TSS_SECRET_MODE_POPUP;
44 #endif
45           /* The policy object will inherit this attribute from the context */
46           if ((result = obj_context_get_hash_mode(tsp_context, &policy->hashMode))) {
47                     free(policy);
48                     return result;
49           }
50           policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
51 #ifdef TSS_BUILD_DELEGATION
52           policy->delegationType = TSS_DELEGATIONTYPE_NONE;
53 #endif
54 
55           if ((result = obj_list_add(&policy_list, tsp_context, 0, policy, phObject))) {
56                     free(policy);
57                     return result;
58           }
59 
60           return TSS_SUCCESS;
61 }
62 
63 void
__tspi_policy_free(void * data)64 __tspi_policy_free(void *data)
65 {
66           struct tr_policy_obj *policy = (struct tr_policy_obj *)data;
67 
68           free(policy->popupString);
69 #ifdef TSS_BUILD_DELEGATION
70           free(policy->delegationBlob);
71 #endif
72           free(policy);
73 }
74 
75 TSS_RESULT
obj_policy_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)76 obj_policy_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
77 {
78           TSS_RESULT result;
79 
80           if ((result = obj_list_remove(&policy_list, &__tspi_policy_free, hObject, tspContext)))
81                     return result;
82 
83           obj_lists_remove_policy_refs(hObject, tspContext);
84 
85           return TSS_SUCCESS;
86 }
87 
88 TSS_BOOL
obj_is_policy(TSS_HOBJECT hObject)89 obj_is_policy(TSS_HOBJECT hObject)
90 {
91           TSS_BOOL answer = FALSE;
92 
93           if ((obj_list_get_obj(&policy_list, hObject))) {
94                     answer = TRUE;
95                     obj_list_put(&policy_list);
96           }
97 
98           return answer;
99 }
100 
101 TSS_RESULT
obj_policy_get_type(TSS_HPOLICY hPolicy,UINT32 * type)102 obj_policy_get_type(TSS_HPOLICY hPolicy, UINT32 *type)
103 {
104           struct tsp_object *obj;
105           struct tr_policy_obj *policy;
106 
107           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
108                     return TSPERR(TSS_E_INVALID_HANDLE);
109 
110           policy = (struct tr_policy_obj *)obj->data;
111           *type = policy->type;
112 
113           obj_list_put(&policy_list);
114 
115           return TSS_SUCCESS;
116 }
117 
118 TSS_RESULT
obj_policy_set_type(TSS_HPOLICY hPolicy,UINT32 type)119 obj_policy_set_type(TSS_HPOLICY hPolicy, UINT32 type)
120 {
121           struct tsp_object *obj;
122           struct tr_policy_obj *policy;
123 
124           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
125                     return TSPERR(TSS_E_INVALID_HANDLE);
126 
127           policy = (struct tr_policy_obj *)obj->data;
128           policy->type = type;
129 
130           obj_list_put(&policy_list);
131 
132           return TSS_SUCCESS;
133 }
134 
135 TSS_RESULT
obj_policy_get_tsp_context(TSS_HPOLICY hPolicy,TSS_HCONTEXT * tspContext)136 obj_policy_get_tsp_context(TSS_HPOLICY hPolicy, TSS_HCONTEXT *tspContext)
137 {
138           struct tsp_object *obj;
139 
140           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
141                     return TSPERR(TSS_E_INVALID_HANDLE);
142 
143           *tspContext = obj->tspContext;
144 
145           obj_list_put(&policy_list);
146 
147           return TSS_SUCCESS;
148 }
149 
150 TSS_RESULT
obj_policy_do_hmac(TSS_HPOLICY hPolicy,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)151 obj_policy_do_hmac(TSS_HPOLICY hPolicy, TSS_HOBJECT hAuthorizedObject,
152                        TSS_BOOL returnOrVerify, UINT32 ulPendingFunction,
153                        TSS_BOOL continueUse, UINT32 ulSizeNonces,
154                        BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
155                        BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
156                        UINT32 ulSizeDigestHmac, BYTE *rgbParamDigest,
157                        BYTE *rgbHmacData)
158 {
159           struct tsp_object *obj;
160           struct tr_policy_obj *policy;
161           TSS_RESULT result = TSS_SUCCESS;
162 
163           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
164                     return TSPERR(TSS_E_INVALID_HANDLE);
165 
166           policy = (struct tr_policy_obj *)obj->data;
167 
168           result = policy->Tspicb_CallbackHMACAuth(
169                               policy->hmacAppData, hAuthorizedObject,
170                               returnOrVerify,
171                               ulPendingFunction,
172                               continueUse,
173                               ulSizeNonces,
174                               rgbNonceEven,
175                               rgbNonceOdd,
176                               rgbNonceEvenOSAP, rgbNonceOddOSAP, ulSizeDigestHmac,
177                               rgbParamDigest,
178                               rgbHmacData);
179 
180           obj_list_put(&policy_list);
181 
182           return result;
183 }
184 
185 TSS_RESULT
obj_policy_get_secret(TSS_HPOLICY hPolicy,TSS_BOOL ctx,TCPA_SECRET * secret)186 obj_policy_get_secret(TSS_HPOLICY hPolicy, TSS_BOOL ctx, TCPA_SECRET *secret)
187 {
188           struct tsp_object *obj;
189           struct tr_policy_obj *policy;
190           TSS_RESULT result = TSS_SUCCESS;
191           TCPA_SECRET null_secret;
192 
193           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
194                     return TSPERR(TSS_E_INVALID_HANDLE);
195 
196           policy = (struct tr_policy_obj *)obj->data;
197 
198           __tspi_memset(&null_secret, 0, sizeof(TCPA_SECRET));
199 
200           switch (policy->SecretMode) {
201                     case TSS_SECRET_MODE_POPUP:
202                               /* if the secret is still NULL, grab it using the GUI */
203                               if (policy->SecretSet == FALSE) {
204                                         if ((result = popup_GetSecret(ctx,
205                                                                             policy->hashMode,
206                                                                             policy->popupString,
207                                                                             policy->Secret)))
208                                                   break;
209                               }
210                               policy->SecretSet = TRUE;
211                               /* fall through */
212                     case TSS_SECRET_MODE_PLAIN:
213                     case TSS_SECRET_MODE_SHA1:
214                               if (policy->SecretSet == FALSE) {
215                                         result = TSPERR(TSS_E_POLICY_NO_SECRET);
216                                         break;
217                               }
218 
219                               memcpy(secret, policy->Secret, sizeof(TCPA_SECRET));
220                               break;
221                     case TSS_SECRET_MODE_NONE:
222                               memcpy(secret, &null_secret, sizeof(TCPA_SECRET));
223                               break;
224                     default:
225                               result = TSPERR(TSS_E_POLICY_NO_SECRET);
226                               break;
227           }
228 #ifdef TSS_DEBUG
229           if (!result) {
230                     LogDebug("Got a secret:");
231                     LogDebugData(20, (BYTE *)secret);
232           }
233 #endif
234           obj_list_put(&policy_list);
235 
236           return result;
237 }
238 
239 TSS_RESULT
obj_policy_flush_secret(TSS_HPOLICY hPolicy)240 obj_policy_flush_secret(TSS_HPOLICY hPolicy)
241 {
242           struct tsp_object *obj;
243           struct tr_policy_obj *policy;
244 
245           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
246                     return TSPERR(TSS_E_INVALID_HANDLE);
247 
248           policy = (struct tr_policy_obj *)obj->data;
249 
250           __tspi_memset(&policy->Secret, 0, policy->SecretSize);
251           policy->SecretSet = FALSE;
252 
253           obj_list_put(&policy_list);
254 
255           return TSS_SUCCESS;
256 }
257 
258 TSS_RESULT
obj_policy_set_secret_object(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,TCPA_DIGEST * digest,TSS_BOOL set)259 obj_policy_set_secret_object(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size,
260                                    TCPA_DIGEST *digest, TSS_BOOL set)
261 {
262           struct tsp_object *obj;
263           struct tr_policy_obj *policy;
264           TSS_RESULT result = TSS_SUCCESS;
265 
266           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
267                     return TSPERR(TSS_E_INVALID_HANDLE);
268 
269           policy = (struct tr_policy_obj *)obj->data;
270 
271           /* if this is going to be a callback policy, the
272            * callbacks need to already be set. (See TSS 1.1b
273            * spec pg. 62). */
274           if (mode == TSS_SECRET_MODE_CALLBACK) {
275                     if (policy->Tspicb_CallbackHMACAuth == NULL) {
276                               result = TSPERR(TSS_E_FAIL);
277                               goto done;
278                     }
279           }
280 
281           if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) {
282                     policy->SecretCounter = policy->SecretTimeStamp;
283           } else if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
284                     time_t t = time(NULL);
285                     if (t == ((time_t)-1)) {
286                               LogError("time failed: %s", strerror(errno));
287                               result = TSPERR(TSS_E_INTERNAL_ERROR);
288                               goto done;
289                     }
290 
291                     policy->SecretTimeStamp = t;
292           }
293 
294           memcpy(policy->Secret, digest, size);
295           policy->SecretMode = mode;
296           policy->SecretSize = size;
297           policy->SecretSet = set;
298 done:
299           obj_list_put(&policy_list);
300 
301           return result;
302 }
303 
304 TSS_RESULT
obj_policy_is_secret_set(TSS_HPOLICY hPolicy,TSS_BOOL * secretSet)305 obj_policy_is_secret_set(TSS_HPOLICY hPolicy, TSS_BOOL *secretSet)
306 {
307           struct tsp_object *obj;
308           struct tr_policy_obj *policy;
309           TSS_RESULT result = TSS_SUCCESS;
310 
311           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
312                     return TSPERR(TSS_E_INVALID_HANDLE);
313 
314           policy = (struct tr_policy_obj *)obj->data;
315 
316           *secretSet = policy->SecretSet;
317           obj_list_put(&policy_list);
318 
319           return result;
320 }
321 
322 
323 TSS_RESULT
obj_policy_set_secret(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,BYTE * data)324 obj_policy_set_secret(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size, BYTE *data)
325 {
326           TCPA_DIGEST digest;
327           UINT32 secret_size = 0;
328           TSS_BOOL secret_set = TRUE;
329           TSS_RESULT result;
330 
331           __tspi_memset(&digest.digest, 0, sizeof(TCPA_DIGEST));
332 
333           switch (mode) {
334                     case TSS_SECRET_MODE_PLAIN:
335                               if ((result = Trspi_Hash(TSS_HASH_SHA1, size, data,
336                                                              (BYTE *)&digest.digest)))
337                                         return result;
338                               secret_size = TCPA_SHA1_160_HASH_LEN;
339                               break;
340                     case TSS_SECRET_MODE_SHA1:
341                               if (size != TCPA_SHA1_160_HASH_LEN)
342                                         return TSPERR(TSS_E_BAD_PARAMETER);
343 
344                               memcpy(&digest.digest, data, size);
345                               secret_size = TCPA_SHA1_160_HASH_LEN;
346                               break;
347                     case TSS_SECRET_MODE_POPUP:
348                     case TSS_SECRET_MODE_NONE:
349                               secret_set = FALSE;
350                     case TSS_SECRET_MODE_CALLBACK:
351                               break;
352                     default:
353                               return TSPERR(TSS_E_BAD_PARAMETER);
354           }
355 
356           return obj_policy_set_secret_object(hPolicy, mode, secret_size,
357                                                       &digest, secret_set);
358 }
359 
360 TSS_RESULT
obj_policy_get_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,UINT32 * cb)361 obj_policy_get_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, UINT32 *cb)
362 {
363 #ifndef __LP64__
364           struct tsp_object *obj;
365           struct tr_policy_obj *policy;
366           TSS_RESULT result = TSS_SUCCESS;
367 
368           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
369                     return TSPERR(TSS_E_INVALID_HANDLE);
370 
371           policy = (struct tr_policy_obj *)obj->data;
372 
373           switch (type) {
374                     case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
375                               *cb = (UINT32)policy->Tspicb_CallbackHMACAuth;
376                               break;
377                     case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
378                               *cb = (UINT32)policy->Tspicb_CallbackXorEnc;
379                               break;
380                     case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
381                               *cb = (UINT32)policy->Tspicb_CallbackTakeOwnership;
382                               break;
383                     case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
384                               *cb = (UINT32)policy->Tspicb_CallbackChangeAuthAsym;
385                               break;
386                     default:
387                               result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
388                               break;
389           }
390 
391           obj_list_put(&policy_list);
392 
393           return result;
394 #else
395           return TSPERR(TSS_E_FAIL);
396 #endif
397 }
398 
399 TSS_RESULT
obj_policy_set_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,TSS_FLAG app_data,UINT32 cb)400 obj_policy_set_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, TSS_FLAG app_data, UINT32 cb)
401 {
402 #ifndef __LP64__
403           struct tsp_object *obj;
404           struct tr_policy_obj *policy;
405           TSS_RESULT result = TSS_SUCCESS;
406 
407           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
408                     return TSPERR(TSS_E_INVALID_HANDLE);
409 
410           policy = (struct tr_policy_obj *)obj->data;
411 
412           switch (type) {
413                     case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
414                               policy->Tspicb_CallbackHMACAuth = (PVOID)cb;
415                               policy->hmacAppData = (PVOID)app_data;
416                               break;
417                     case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
418                               policy->Tspicb_CallbackXorEnc = (PVOID)cb;
419                               policy->xorAppData = (PVOID)app_data;
420                               break;
421                     case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
422                               policy->Tspicb_CallbackTakeOwnership = (PVOID)cb;
423                               policy->takeownerAppData = (PVOID)app_data;
424                               break;
425                     case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
426                               policy->Tspicb_CallbackChangeAuthAsym = (PVOID)cb;
427                               policy->changeauthAppData = (PVOID)app_data;
428                               break;
429                     default:
430                               result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
431                               break;
432           }
433 
434           obj_list_put(&policy_list);
435 
436           return result;
437 #else
438           return TSPERR(TSS_E_FAIL);
439 #endif
440 }
441 
442 TSS_RESULT
obj_policy_set_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,BYTE * in)443 obj_policy_set_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, BYTE *in)
444 {
445           struct tsp_object *obj;
446           struct tr_policy_obj *policy;
447           TSS_RESULT result = TSS_SUCCESS;
448           TSS_CALLBACK *cb = (TSS_CALLBACK *)in;
449 
450           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
451                     return TSPERR(TSS_E_INVALID_HANDLE);
452 
453           policy = (struct tr_policy_obj *)obj->data;
454 
455           switch (flag) {
456                     case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
457                               if (!cb) {
458                                         policy->Tspicb_CallbackHMACAuth = NULL;
459                                         break;
460                               }
461 
462                               policy->Tspicb_CallbackHMACAuth =
463                                         (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL,
464                                         UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *,
465                                         BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
466                                         cb->callback;
467                               policy->hmacAppData = cb->appData;
468                               policy->hmacAlg = cb->alg;
469                               break;
470                     case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
471                               if (!cb) {
472                                         policy->Tspicb_CallbackXorEnc = NULL;
473                                         break;
474                               }
475 
476                               policy->Tspicb_CallbackXorEnc =
477                                         (TSS_RESULT (*)(PVOID, TSS_HOBJECT,
478                                         TSS_HOBJECT, TSS_FLAG, UINT32, BYTE *, BYTE *,
479                                         BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
480                                         cb->callback;
481                               policy->xorAppData = cb->appData;
482                               policy->xorAlg = cb->alg;
483                               break;
484                     case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
485                               if (!cb) {
486                                         policy->Tspicb_CallbackTakeOwnership = NULL;
487                                         break;
488                               }
489 
490                               policy->Tspicb_CallbackTakeOwnership =
491                                         (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
492                                         UINT32, BYTE *))cb->callback;
493                               policy->takeownerAppData = cb->appData;
494                               policy->takeownerAlg = cb->alg;
495                               break;
496                     case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
497                               if (!cb) {
498                                         policy->Tspicb_CallbackChangeAuthAsym = NULL;
499                                         break;
500                               }
501 
502                               policy->Tspicb_CallbackChangeAuthAsym =
503                                         (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
504                                         UINT32, UINT32, BYTE *, BYTE *))cb->callback;
505                               policy->changeauthAppData = cb->appData;
506                               policy->changeauthAlg = cb->alg;
507                               break;
508 #ifdef TSS_BUILD_SEALX
509                     case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
510                               if (!cb) {
511                                         policy->Tspicb_CallbackSealxMask = NULL;
512                                         policy->sealxAppData = NULL;
513                                         policy->sealxAlg = 0;
514                                         break;
515                               }
516 
517                               policy->Tspicb_CallbackSealxMask =
518                                         (TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA,
519                                         TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *,
520                                         UINT32, BYTE *, BYTE *))cb->callback;
521                               policy->sealxAppData = cb->appData;
522                               policy->sealxAlg = cb->alg;
523                               break;
524 #endif
525                     default:
526                               result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
527                               break;
528           }
529 
530           obj_list_put(&policy_list);
531 
532           return result;
533 }
534 
535 TSS_RESULT
obj_policy_get_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,UINT32 * size,BYTE ** out)536 obj_policy_get_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, UINT32 *size, BYTE **out)
537 {
538           struct tsp_object *obj;
539           struct tr_policy_obj *policy;
540           TSS_RESULT result = TSS_SUCCESS;
541           TSS_CALLBACK *cb;
542 
543           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
544                     return TSPERR(TSS_E_INVALID_HANDLE);
545 
546           policy = (struct tr_policy_obj *)obj->data;
547 
548           if ((cb = calloc_tspi(obj->tspContext, sizeof(TSS_CALLBACK))) == NULL) {
549                     LogError("malloc of %zd bytes failed.", sizeof(TSS_CALLBACK));
550                     result = TSPERR(TSS_E_OUTOFMEMORY);
551                     goto done;
552           }
553 
554           switch (flag) {
555                     case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
556                               cb->callback = policy->Tspicb_CallbackHMACAuth;
557                               cb->appData = policy->hmacAppData;
558                               cb->alg = policy->hmacAlg;
559                               *size = sizeof(TSS_CALLBACK);
560                               *out = (BYTE *)cb;
561                               break;
562                     case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
563                               cb->callback = policy->Tspicb_CallbackXorEnc;
564                               cb->appData = policy->xorAppData;
565                               cb->alg = policy->xorAlg;
566                               *size = sizeof(TSS_CALLBACK);
567                               *out = (BYTE *)cb;
568                               break;
569                     case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
570                               cb->callback = policy->Tspicb_CallbackTakeOwnership;
571                               cb->appData = policy->takeownerAppData;
572                               cb->alg = policy->takeownerAlg;
573                               *size = sizeof(TSS_CALLBACK);
574                               *out = (BYTE *)cb;
575                               break;
576                     case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
577                               cb->callback = policy->Tspicb_CallbackChangeAuthAsym;
578                               cb->appData = policy->changeauthAppData;
579                               cb->alg = policy->changeauthAlg;
580                               *size = sizeof(TSS_CALLBACK);
581                               *out = (BYTE *)cb;
582                               break;
583 #ifdef TSS_BUILD_SEALX
584                     case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
585                               cb->callback = policy->Tspicb_CallbackSealxMask;
586                               cb->appData = policy->sealxAppData;
587                               cb->alg = policy->sealxAlg;
588                               *size = sizeof(TSS_CALLBACK);
589                               *out = (BYTE *)cb;
590                               break;
591 #endif
592                     default:
593                               free_tspi(obj->tspContext, cb);
594                               result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
595                               break;
596           }
597 done:
598           obj_list_put(&policy_list);
599 
600           return result;
601 }
602 
603 TSS_RESULT
obj_policy_get_lifetime(TSS_HPOLICY hPolicy,UINT32 * lifetime)604 obj_policy_get_lifetime(TSS_HPOLICY hPolicy, UINT32 *lifetime)
605 {
606           struct tsp_object *obj;
607           struct tr_policy_obj *policy;
608 
609           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
610                     return TSPERR(TSS_E_INVALID_HANDLE);
611 
612           policy = (struct tr_policy_obj *)obj->data;
613           *lifetime = policy->SecretLifetime;
614 
615           obj_list_put(&policy_list);
616 
617           return TSS_SUCCESS;
618 }
619 
620 TSS_RESULT
obj_policy_set_lifetime(TSS_HPOLICY hPolicy,UINT32 type,UINT32 value)621 obj_policy_set_lifetime(TSS_HPOLICY hPolicy, UINT32 type, UINT32 value)
622 {
623           struct tsp_object *obj;
624           struct tr_policy_obj *policy;
625           TSS_RESULT result = TSS_SUCCESS;
626           time_t t;
627 
628           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
629                     return TSPERR(TSS_E_INVALID_HANDLE);
630 
631           policy = (struct tr_policy_obj *)obj->data;
632 
633           switch (type) {
634                     case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
635                               policy->SecretCounter = 0;
636                               policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
637                               policy->SecretTimeStamp = 0;
638                               break;
639                     case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
640                               /* Both SecretCounter and SecretTimeStamp will receive value. Every time the
641                                * policy is used, SecretCounter will be decremented. Each time SetSecret is
642                                * called, SecretCounter will get the value stored in SecretTimeStamp */
643                               policy->SecretCounter = value;
644                               policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER;
645                               policy->SecretTimeStamp = value;
646                               break;
647                     case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
648                               t = time(NULL);
649                               if (t == ((time_t)-1)) {
650                                         LogError("time failed: %s", strerror(errno));
651                                         result = TSPERR(TSS_E_INTERNAL_ERROR);
652                                         break;
653                               }
654 
655                               /* For mode time, we'll use the SecretCounter variable to hold the number
656                                * of seconds we're valid and the SecretTimeStamp var to record the current
657                                * timestamp. This should protect against overflows. */
658                               policy->SecretCounter = value;
659                               policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER;
660                               policy->SecretTimeStamp = t;
661                               break;
662                     default:
663                               result = TSPERR(TSS_E_BAD_PARAMETER);
664                               break;
665           }
666 
667           obj_list_put(&policy_list);
668 
669           return result;
670 }
671 
672 TSS_RESULT
obj_policy_get_mode(TSS_HPOLICY hPolicy,UINT32 * mode)673 obj_policy_get_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
674 {
675           struct tsp_object *obj;
676           struct tr_policy_obj *policy;
677 
678           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
679                     return TSPERR(TSS_E_INVALID_HANDLE);
680 
681           policy = (struct tr_policy_obj *)obj->data;
682           *mode = policy->SecretMode;
683 
684           obj_list_put(&policy_list);
685 
686           return TSS_SUCCESS;
687 }
688 
689 TSS_RESULT
obj_policy_get_counter(TSS_HPOLICY hPolicy,UINT32 * counter)690 obj_policy_get_counter(TSS_HPOLICY hPolicy, UINT32 *counter)
691 {
692           struct tsp_object *obj;
693           struct tr_policy_obj *policy;
694           TSS_RESULT result = TSS_SUCCESS;
695 
696           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
697                     return TSPERR(TSS_E_INVALID_HANDLE);
698 
699           policy = (struct tr_policy_obj *)obj->data;
700 
701           if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER)
702                     *counter = policy->SecretCounter;
703           else
704                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
705 
706           obj_list_put(&policy_list);
707 
708           return result;
709 }
710 
711 TSS_RESULT
obj_policy_dec_counter(TSS_HPOLICY hPolicy)712 obj_policy_dec_counter(TSS_HPOLICY hPolicy)
713 {
714           struct tsp_object *obj;
715           struct tr_policy_obj *policy;
716 
717           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
718                     return TSPERR(TSS_E_INVALID_HANDLE);
719 
720           policy = (struct tr_policy_obj *)obj->data;
721 
722           /* Only decrement if SecretCounter > 0, otherwise it could loop and become valid again */
723           if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER &&
724               policy->SecretCounter > 0) {
725                     policy->SecretCounter--;
726           }
727 
728           obj_list_put(&policy_list);
729 
730           return TSS_SUCCESS;
731 }
732 
733 /* return a unicode string to the Tspi_GetAttribData function */
734 TSS_RESULT
obj_policy_get_string(TSS_HPOLICY hPolicy,UINT32 * size,BYTE ** data)735 obj_policy_get_string(TSS_HPOLICY hPolicy, UINT32 *size, BYTE **data)
736 {
737           TSS_RESULT result = TSS_SUCCESS;
738           BYTE *utf_string;
739           UINT32 utf_size;
740           struct tsp_object *obj;
741           struct tr_policy_obj *policy;
742 
743           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
744                     return TSPERR(TSS_E_INVALID_HANDLE);
745 
746           policy = (struct tr_policy_obj *)obj->data;
747 
748           *size = policy->popupStringLength;
749           if (policy->popupStringLength == 0) {
750                     *data = NULL;
751           } else {
752                     utf_size = policy->popupStringLength;
753                     utf_string = Trspi_Native_To_UNICODE(policy->popupString,
754                                                                  &utf_size);
755                     if (utf_string == NULL) {
756                               result = TSPERR(TSS_E_INTERNAL_ERROR);
757                               goto done;
758                     }
759 
760                     *data = calloc_tspi(obj->tspContext, utf_size);
761                     if (*data == NULL) {
762                               free(utf_string);
763                               LogError("malloc of %d bytes failed.", utf_size);
764                               result = TSPERR(TSS_E_OUTOFMEMORY);
765                               goto done;
766                     }
767 
768                     *size = utf_size;
769                     memcpy(*data, utf_string, utf_size);
770                     free(utf_string);
771           }
772 
773 done:
774           obj_list_put(&policy_list);
775 
776           return result;
777 }
778 
779 TSS_RESULT
obj_policy_set_string(TSS_HPOLICY hPolicy,UINT32 size,BYTE * data)780 obj_policy_set_string(TSS_HPOLICY hPolicy, UINT32 size, BYTE *data)
781 {
782           struct tsp_object *obj;
783           struct tr_policy_obj *policy;
784 
785           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
786                     return TSPERR(TSS_E_INVALID_HANDLE);
787 
788           policy = (struct tr_policy_obj *)obj->data;
789 
790           free(policy->popupString);
791           policy->popupString = data;
792           policy->popupStringLength = size;
793 
794           obj_list_put(&policy_list);
795 
796           return TSS_SUCCESS;
797 }
798 
799 TSS_RESULT
obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy,UINT32 * secs)800 obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy, UINT32 *secs)
801 {
802           TSS_RESULT result = TSS_SUCCESS;
803           struct tsp_object *obj;
804           struct tr_policy_obj *policy;
805           int seconds_elapsed;
806           time_t t;
807 
808           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
809                     return TSPERR(TSS_E_INVALID_HANDLE);
810 
811           policy = (struct tr_policy_obj *)obj->data;
812 
813           if (policy->SecretLifetime != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
814                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
815                     goto done;
816           }
817 
818           if ((t = time(NULL)) == ((time_t)-1)) {
819                     LogError("time failed: %s", strerror(errno));
820                     result = TSPERR(TSS_E_INTERNAL_ERROR);
821                     goto done;
822           }
823           /* curtime - SecretTimeStamp is the number of seconds elapsed since we started the timer.
824            * SecretCounter is the number of seconds the secret is valid.  If
825            * seconds_elspased > SecretCounter, we've expired. */
826           seconds_elapsed = t - policy->SecretTimeStamp;
827           if ((UINT32)seconds_elapsed >= policy->SecretCounter) {
828                     *secs = 0;
829           } else {
830                     *secs = policy->SecretCounter - seconds_elapsed;
831           }
832 
833 done:
834           obj_list_put(&policy_list);
835 
836           return result;
837 }
838 
839 TSS_RESULT
policy_has_expired(struct tr_policy_obj * policy,TSS_BOOL * answer)840 policy_has_expired(struct tr_policy_obj *policy, TSS_BOOL *answer)
841 {
842           switch (policy->SecretLifetime) {
843           case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
844                     *answer = FALSE;
845                     break;
846           case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
847                     *answer = (policy->SecretCounter == 0 ? TRUE : FALSE);
848                     break;
849           case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
850           {
851                     int seconds_elapsed;
852                     time_t t = time(NULL);
853 
854                     if (t == ((time_t)-1)) {
855                               LogError("time failed: %s", strerror(errno));
856                               return TSPERR(TSS_E_INTERNAL_ERROR);
857                     }
858                     /* curtime - SecretTimer is the number of seconds elapsed since we
859                      * started the timer. SecretCounter is the number of seconds the
860                      * secret is valid.  If seconds_elspased > SecretCounter, we've
861                      * expired.
862                      */
863                     seconds_elapsed = t - policy->SecretTimeStamp;
864                     *answer = ((UINT32)seconds_elapsed >= policy->SecretCounter ? TRUE : FALSE);
865                     break;
866           }
867           default:
868                     LogError("policy has an undefined secret lifetime!");
869                     return TSPERR(TSS_E_INVALID_OBJ_ACCESS);
870           }
871 
872           return TSS_SUCCESS;
873 }
874 
875 TSS_RESULT
obj_policy_has_expired(TSS_HPOLICY hPolicy,TSS_BOOL * answer)876 obj_policy_has_expired(TSS_HPOLICY hPolicy, TSS_BOOL *answer)
877 {
878           struct tsp_object *obj;
879           struct tr_policy_obj *policy;
880           TSS_RESULT result;
881 
882           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
883                     return TSPERR(TSS_E_INVALID_HANDLE);
884 
885           policy = (struct tr_policy_obj *)obj->data;
886 
887           result = policy_has_expired(policy, answer);
888 
889           obj_list_put(&policy_list);
890 
891           return result;
892 }
893 
894 TSS_RESULT
obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,TPM_COMMAND_CODE command,TPM_ENTITY_TYPE * et,UINT32 * entity_value_size,BYTE ** entity_value,BYTE * secret,TSS_CALLBACK * cb_xor,TSS_CALLBACK * cb_hmac,TSS_CALLBACK * cb_sealx,UINT32 * mode,TSS_BOOL new_secret)895 obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,
896                                  TPM_COMMAND_CODE command,
897                                  TPM_ENTITY_TYPE *et,
898                                  UINT32 *entity_value_size,
899                                  BYTE **entity_value,
900                                  BYTE *secret,
901                                  TSS_CALLBACK *cb_xor,
902                                  TSS_CALLBACK *cb_hmac,
903                                  TSS_CALLBACK *cb_sealx,
904                                  UINT32 *mode,
905                                  TSS_BOOL new_secret)
906 {
907           struct tsp_object *obj;
908           struct tr_policy_obj *policy;
909           TSS_RESULT result;
910           TSS_BOOL answer = FALSE;
911 
912           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
913                     return TSPERR(TSS_E_INVALID_HANDLE);
914 
915           policy = (struct tr_policy_obj *)obj->data;
916 
917           if ((result = policy_has_expired(policy, &answer)))
918                     goto done;
919 
920           if (answer) {
921                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
922                     goto done;
923           }
924 #ifdef TSS_BUILD_DELEGATION
925           /* if the delegation index or blob is set, check to see if the command is delegated, if so,
926            * return the blob or index as the secret data */
927           if (command && (policy->delegationType != TSS_DELEGATIONTYPE_NONE)) {
928                     if (policy->delegationBlob) {
929                               if ((*entity_value = malloc(policy->delegationBlobLength)) == NULL) {
930                                         LogError("malloc of %u bytes failed.",
931                                                    policy->delegationBlobLength);
932                                         result = TSPERR(TSS_E_OUTOFMEMORY);
933                                         goto done;
934                               }
935 
936                               memcpy(*entity_value, policy->delegationBlob, policy->delegationBlobLength);
937                               *entity_value_size = policy->delegationBlobLength;
938                               if (policy->delegationType == TSS_DELEGATIONTYPE_OWNER)
939                                         *et = TPM_ET_DEL_OWNER_BLOB;
940                               else
941                                         *et = TPM_ET_DEL_KEY_BLOB;
942                     } else {
943                               if ((*entity_value = malloc(sizeof(UINT32))) == NULL) {
944                                         LogError("malloc of %zd bytes failed.", sizeof(UINT32));
945                                         result = TSPERR(TSS_E_OUTOFMEMORY);
946                                         goto done;
947                               }
948 
949                               *(UINT32 *)entity_value = policy->delegationIndex;
950                               *entity_value_size = sizeof(UINT32);
951                               *et = TPM_ET_DEL_ROW;
952                     }
953           }
954 #endif
955           /* Either this is a policy set to mode callback, in which case both xor and hmac addresses
956            * must be set, or this is an encrypted data object's policy, where its mode is independent
957            * of whether a sealx callback is set */
958           if (policy->SecretMode == TSS_SECRET_MODE_CALLBACK && cb_xor && cb_hmac) {
959                     if ((policy->Tspicb_CallbackXorEnc && !policy->Tspicb_CallbackHMACAuth) ||
960                         (!policy->Tspicb_CallbackXorEnc && policy->Tspicb_CallbackHMACAuth)) {
961                               result = TSPERR(TSS_E_INTERNAL_ERROR);
962                               goto done;
963                     }
964 
965                     cb_xor->callback = policy->Tspicb_CallbackXorEnc;
966                     cb_xor->appData = policy->xorAppData;
967                     cb_xor->alg = policy->xorAlg;
968 
969                     cb_hmac->callback = policy->Tspicb_CallbackHMACAuth;
970                     cb_hmac->appData = policy->hmacAppData;
971                     cb_hmac->alg = policy->hmacAlg;
972 #ifdef TSS_BUILD_SEALX
973           } else if (cb_sealx && policy->Tspicb_CallbackSealxMask) {
974                     cb_sealx->callback = policy->Tspicb_CallbackSealxMask;
975                     cb_sealx->appData = policy->sealxAppData;
976                     cb_sealx->alg = policy->sealxAlg;
977 #endif
978           }
979 
980           if ((policy->SecretMode == TSS_SECRET_MODE_POPUP) &&
981               (policy->SecretSet == FALSE)) {
982                     if ((result = popup_GetSecret(new_secret,
983                                                         policy->hashMode,
984                                                         policy->popupString,
985                                                         policy->Secret)))
986                               goto done;
987                               policy->SecretSet = TRUE;
988           }
989           memcpy(secret, policy->Secret, TPM_SHA1_160_HASH_LEN);
990           *mode = policy->SecretMode;
991 done:
992           obj_list_put(&policy_list);
993 
994           return result;
995 }
996 
997 TSS_RESULT
obj_policy_do_xor(TSS_HPOLICY hPolicy,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)998 obj_policy_do_xor(TSS_HPOLICY hPolicy,
999                       TSS_HOBJECT hOSAPObject, TSS_HOBJECT hObject,
1000                       TSS_FLAG PurposeSecret, UINT32 ulSizeNonces,
1001                       BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
1002                       BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
1003                       UINT32 ulSizeEncAuth, BYTE *rgbEncAuthUsage,
1004                       BYTE *rgbEncAuthMigration)
1005 {
1006           TSS_RESULT result;
1007           struct tsp_object *obj;
1008           struct tr_policy_obj *policy;
1009 
1010           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1011                     return TSPERR(TSS_E_INVALID_HANDLE);
1012 
1013           policy = (struct tr_policy_obj *)obj->data;
1014 
1015           result = policy->Tspicb_CallbackXorEnc(policy->xorAppData,
1016                               hOSAPObject, hObject,
1017                               PurposeSecret, ulSizeNonces,
1018                               rgbNonceEven, rgbNonceOdd,
1019                               rgbNonceEvenOSAP, rgbNonceOddOSAP,
1020                               ulSizeEncAuth,
1021                               rgbEncAuthUsage, rgbEncAuthMigration);
1022 
1023           obj_list_put(&policy_list);
1024 
1025           return result;
1026 }
1027 
1028 TSS_RESULT
obj_policy_do_takeowner(TSS_HPOLICY hPolicy,TSS_HOBJECT hObject,TSS_HKEY hObjectPubKey,UINT32 ulSizeEncAuth,BYTE * rgbEncAuth)1029 obj_policy_do_takeowner(TSS_HPOLICY hPolicy,
1030                               TSS_HOBJECT hObject, TSS_HKEY hObjectPubKey,
1031                               UINT32 ulSizeEncAuth, BYTE *rgbEncAuth)
1032 {
1033           TSS_RESULT result;
1034           struct tsp_object *obj;
1035           struct tr_policy_obj *policy;
1036 
1037           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1038                     return TSPERR(TSS_E_INVALID_HANDLE);
1039 
1040           policy = (struct tr_policy_obj *)obj->data;
1041 
1042           result = policy->Tspicb_CallbackTakeOwnership(
1043                               policy->takeownerAppData,
1044                               hObject, hObjectPubKey, ulSizeEncAuth,
1045                               rgbEncAuth);
1046 
1047           obj_list_put(&policy_list);
1048 
1049           return result;
1050 }
1051 
1052 TSS_RESULT
obj_policy_get_hash_mode(TSS_HPOLICY hPolicy,UINT32 * mode)1053 obj_policy_get_hash_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
1054 {
1055           struct tsp_object *obj;
1056           struct tr_policy_obj *policy;
1057 
1058           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1059                     return TSPERR(TSS_E_INVALID_HANDLE);
1060 
1061           policy = (struct tr_policy_obj *)obj->data;
1062           *mode = policy->hashMode;
1063 
1064           obj_list_put(&policy_list);
1065 
1066           return TSS_SUCCESS;
1067 }
1068 
1069 TSS_RESULT
obj_policy_set_hash_mode(TSS_HPOLICY hPolicy,UINT32 mode)1070 obj_policy_set_hash_mode(TSS_HPOLICY hPolicy, UINT32 mode)
1071 {
1072           struct tsp_object *obj;
1073           struct tr_policy_obj *policy;
1074 
1075           switch (mode) {
1076                     case TSS_TSPATTRIB_HASH_MODE_NULL:
1077                     case TSS_TSPATTRIB_HASH_MODE_NOT_NULL:
1078                               break;
1079                     default:
1080                               return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
1081           }
1082 
1083           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1084                     return TSPERR(TSS_E_INVALID_HANDLE);
1085 
1086           policy = (struct tr_policy_obj *)obj->data;
1087           policy->hashMode = mode;
1088 
1089           obj_list_put(&policy_list);
1090 
1091           return TSS_SUCCESS;
1092 }
1093 
1094 #ifdef TSS_BUILD_DELEGATION
1095 TSS_RESULT
obj_policy_set_delegation_type(TSS_HPOLICY hPolicy,UINT32 type)1096 obj_policy_set_delegation_type(TSS_HPOLICY hPolicy, UINT32 type)
1097 {
1098           struct tsp_object *obj;
1099           struct tr_policy_obj *policy;
1100           TSS_RESULT result = TSS_SUCCESS;
1101 
1102           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1103                     return TSPERR(TSS_E_INVALID_HANDLE);
1104 
1105           policy = (struct tr_policy_obj *)obj->data;
1106 
1107           switch (type) {
1108           case TSS_DELEGATIONTYPE_NONE:
1109                     obj_policy_clear_delegation(policy);
1110                     break;
1111           case TSS_DELEGATIONTYPE_OWNER:
1112           case TSS_DELEGATIONTYPE_KEY:
1113                     if (policy->delegationIndexSet || policy->delegationBlob) {
1114                               result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1115                               goto done;
1116                     }
1117                     break;
1118           }
1119 
1120           policy->delegationType = type;
1121 
1122 done:
1123           obj_list_put(&policy_list);
1124 
1125           return result;
1126 }
1127 
1128 
1129 TSS_RESULT
obj_policy_get_delegation_type(TSS_HPOLICY hPolicy,UINT32 * type)1130 obj_policy_get_delegation_type(TSS_HPOLICY hPolicy, UINT32 *type)
1131 {
1132           struct tsp_object *obj;
1133           struct tr_policy_obj *policy;
1134 
1135           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1136                     return TSPERR(TSS_E_INVALID_HANDLE);
1137 
1138           policy = (struct tr_policy_obj *)obj->data;
1139 
1140           *type = policy->delegationType;
1141 
1142           obj_list_put(&policy_list);
1143 
1144           return TSS_SUCCESS;
1145 }
1146 
1147 TSS_RESULT
obj_policy_set_delegation_index(TSS_HPOLICY hPolicy,UINT32 index)1148 obj_policy_set_delegation_index(TSS_HPOLICY hPolicy, UINT32 index)
1149 {
1150           struct tsp_object *obj;
1151           struct tr_policy_obj *policy;
1152           TPM_DELEGATE_PUBLIC public;
1153           TSS_RESULT result;
1154 
1155           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1156                     return TSPERR(TSS_E_INVALID_HANDLE);
1157 
1158           policy = (struct tr_policy_obj *)obj->data;
1159 
1160           if ((result = get_delegate_index(obj->tspContext, index, &public)))
1161                     goto done;
1162 
1163           free(public.pcrInfo.pcrSelection.pcrSelect);
1164 
1165           obj_policy_clear_delegation(policy);
1166           switch (public.permissions.delegateType) {
1167           case TPM_DEL_OWNER_BITS:
1168                     policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1169                     break;
1170           case TPM_DEL_KEY_BITS:
1171                     policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1172                     break;
1173           default:
1174                     result = TSPERR(TSS_E_BAD_PARAMETER);
1175                     goto done;
1176           }
1177           policy->delegationIndex = index;
1178           policy->delegationIndexSet = TRUE;
1179 
1180 done:
1181           obj_list_put(&policy_list);
1182 
1183           return result;
1184 }
1185 
1186 TSS_RESULT
obj_policy_get_delegation_index(TSS_HPOLICY hPolicy,UINT32 * index)1187 obj_policy_get_delegation_index(TSS_HPOLICY hPolicy, UINT32 *index)
1188 {
1189           struct tsp_object *obj;
1190           struct tr_policy_obj *policy;
1191           TSS_RESULT result = TSS_SUCCESS;
1192 
1193           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1194                     return TSPERR(TSS_E_INVALID_HANDLE);
1195 
1196           policy = (struct tr_policy_obj *)obj->data;
1197 
1198           if (!policy->delegationIndexSet) {
1199                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1200                     goto done;
1201           }
1202 
1203           *index = policy->delegationIndex;
1204 
1205 done:
1206           obj_list_put(&policy_list);
1207 
1208           return result;
1209 }
1210 
obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy,UINT32 per1)1211 TSS_RESULT obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy, UINT32 per1)
1212 {
1213           struct tsp_object *obj;
1214           struct tr_policy_obj *policy;
1215           TSS_RESULT result = TSS_SUCCESS;
1216 
1217           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1218                     return TSPERR(TSS_E_INVALID_HANDLE);
1219 
1220           policy = (struct tr_policy_obj *)obj->data;
1221 
1222           if (policy->delegationIndexSet || policy->delegationBlob) {
1223                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1224                     goto done;
1225           }
1226 
1227           policy->delegationPer1 = per1;
1228 
1229 done:
1230           obj_list_put(&policy_list);
1231 
1232           return result;
1233 }
1234 
obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy,UINT32 * per1)1235 TSS_RESULT obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy, UINT32 *per1)
1236 {
1237           struct tsp_object *obj;
1238           struct tr_policy_obj *policy;
1239           TPM_DELEGATE_PUBLIC public;
1240           TSS_RESULT result = TSS_SUCCESS;
1241 
1242           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1243                     return TSPERR(TSS_E_INVALID_HANDLE);
1244 
1245           policy = (struct tr_policy_obj *)obj->data;
1246 
1247           if (policy->delegationIndexSet || policy->delegationBlob) {
1248                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1249                               goto done;
1250                     *per1 = public.permissions.per1;
1251                     free(public.pcrInfo.pcrSelection.pcrSelect);
1252           } else
1253                     *per1 = policy->delegationPer1;
1254 
1255 done:
1256           obj_list_put(&policy_list);
1257 
1258           return result;
1259 }
1260 
obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy,UINT32 per2)1261 TSS_RESULT obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy, UINT32 per2)
1262 {
1263           struct tsp_object *obj;
1264           struct tr_policy_obj *policy;
1265           TSS_RESULT result = TSS_SUCCESS;
1266 
1267           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1268                     return TSPERR(TSS_E_INVALID_HANDLE);
1269 
1270           policy = (struct tr_policy_obj *)obj->data;
1271 
1272           if (policy->delegationIndexSet || policy->delegationBlob) {
1273                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1274                     goto done;
1275           }
1276 
1277           policy->delegationPer2 = per2;
1278 
1279 done:
1280           obj_list_put(&policy_list);
1281 
1282           return result;
1283 }
1284 
obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy,UINT32 * per2)1285 TSS_RESULT obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy, UINT32 *per2)
1286 {
1287           struct tsp_object *obj;
1288           struct tr_policy_obj *policy;
1289           TPM_DELEGATE_PUBLIC public;
1290           TSS_RESULT result = TSS_SUCCESS;
1291 
1292           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1293                     return TSPERR(TSS_E_INVALID_HANDLE);
1294 
1295           policy = (struct tr_policy_obj *)obj->data;
1296 
1297           if (policy->delegationIndexSet || policy->delegationBlob) {
1298                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1299                               goto done;
1300                     *per2 = public.permissions.per2;
1301                     free(public.pcrInfo.pcrSelection.pcrSelect);
1302           } else
1303                     *per2 = policy->delegationPer2;
1304 
1305 done:
1306           obj_list_put(&policy_list);
1307 
1308           return result;
1309 }
1310 
1311 TSS_RESULT
obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 blobLength,BYTE * blob)1312 obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 blobLength, BYTE *blob)
1313 {
1314           struct tsp_object *obj;
1315           struct tr_policy_obj *policy;
1316           UINT16 tag;
1317           UINT64 offset;
1318           TSS_RESULT result = TSS_SUCCESS;
1319 
1320           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1321                     return TSPERR(TSS_E_INVALID_HANDLE);
1322 
1323           policy = (struct tr_policy_obj *)obj->data;
1324 
1325           obj_policy_clear_delegation(policy);
1326 
1327           if (blobLength == 0) {
1328                     result = TSPERR(TSS_E_BAD_PARAMETER);
1329                     goto done;
1330           }
1331 
1332           offset = 0;
1333           Trspi_UnloadBlob_UINT16(&offset, &tag, blob);
1334           switch (tag) {
1335           case TPM_TAG_DELEGATE_OWNER_BLOB:
1336                     if (type && (type != TSS_DELEGATIONTYPE_OWNER)) {
1337                               result = TSPERR(TSS_E_BAD_PARAMETER);
1338                               goto done;
1339                     }
1340                     policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1341                     break;
1342           case TPM_TAG_DELG_KEY_BLOB:
1343                     if (type && (type != TSS_DELEGATIONTYPE_KEY)) {
1344                               result = TSPERR(TSS_E_BAD_PARAMETER);
1345                               goto done;
1346                     }
1347                     policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1348                     break;
1349           default:
1350                     result = TSPERR(TSS_E_BAD_PARAMETER);
1351                     goto done;
1352           }
1353 
1354           if ((policy->delegationBlob = malloc(blobLength)) == NULL) {
1355                     LogError("malloc of %u bytes failed.", blobLength);
1356                     result = TSPERR(TSS_E_OUTOFMEMORY);
1357                     goto done;
1358           }
1359 
1360           policy->delegationBlobLength = blobLength;
1361           memcpy(policy->delegationBlob, blob, blobLength);
1362 
1363 done:
1364           obj_list_put(&policy_list);
1365 
1366           return result;
1367 }
1368 
1369 TSS_RESULT
obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 * blobLength,BYTE ** blob)1370 obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 *blobLength, BYTE **blob)
1371 {
1372           struct tsp_object *obj;
1373           struct tr_policy_obj *policy;
1374           TSS_RESULT result = TSS_SUCCESS;
1375 
1376           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1377                     return TSPERR(TSS_E_INVALID_HANDLE);
1378 
1379           policy = (struct tr_policy_obj *)obj->data;
1380 
1381           if (policy->delegationBlobLength == 0) {
1382                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1383                     goto done;
1384           }
1385 
1386           if (type && (type != policy->delegationType)) {
1387                     result = TSPERR(TSS_E_BAD_PARAMETER);
1388                     goto done;
1389           }
1390 
1391           if ((*blob = calloc_tspi(obj->tspContext, policy->delegationBlobLength)) == NULL) {
1392                     LogError("malloc of %u bytes failed.", policy->delegationBlobLength);
1393                     result = TSPERR(TSS_E_OUTOFMEMORY);
1394                     goto done;
1395           }
1396 
1397           memcpy(*blob, policy->delegationBlob, policy->delegationBlobLength);
1398           *blobLength = policy->delegationBlobLength;
1399 
1400 done:
1401           obj_list_put(&policy_list);
1402 
1403           return result;
1404 }
1405 
1406 TSS_RESULT
obj_policy_get_delegation_label(TSS_HPOLICY hPolicy,BYTE * label)1407 obj_policy_get_delegation_label(TSS_HPOLICY hPolicy, BYTE *label)
1408 {
1409           struct tsp_object *obj;
1410           struct tr_policy_obj *policy;
1411           TPM_DELEGATE_PUBLIC public;
1412           TSS_RESULT result = TSS_SUCCESS;
1413 
1414           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1415                     return TSPERR(TSS_E_INVALID_HANDLE);
1416 
1417           policy = (struct tr_policy_obj *)obj->data;
1418 
1419           if (policy->delegationIndexSet || policy->delegationBlob) {
1420                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1421                               goto done;
1422                     *label = public.label.label;
1423                     free(public.pcrInfo.pcrSelection.pcrSelect);
1424           } else
1425                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1426 
1427 done:
1428           obj_list_put(&policy_list);
1429 
1430           return result;
1431 }
1432 
1433 TSS_RESULT
obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy,UINT32 * familyID)1434 obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy, UINT32 *familyID)
1435 {
1436           struct tsp_object *obj;
1437           struct tr_policy_obj *policy;
1438           TPM_DELEGATE_PUBLIC public;
1439           TSS_RESULT result = TSS_SUCCESS;
1440 
1441           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1442                     return TSPERR(TSS_E_INVALID_HANDLE);
1443 
1444           policy = (struct tr_policy_obj *)obj->data;
1445 
1446           if (policy->delegationIndexSet || policy->delegationBlob) {
1447                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1448                               goto done;
1449                     *familyID = public.familyID;
1450                     free(public.pcrInfo.pcrSelection.pcrSelect);
1451           } else
1452                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1453 
1454 done:
1455           obj_list_put(&policy_list);
1456 
1457           return result;
1458 }
1459 
1460 TSS_RESULT
obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy,UINT32 * verCount)1461 obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy, UINT32 *verCount)
1462 {
1463           struct tsp_object *obj;
1464           struct tr_policy_obj *policy;
1465           TPM_DELEGATE_PUBLIC public;
1466           TSS_RESULT result = TSS_SUCCESS;
1467 
1468           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1469                     return TSPERR(TSS_E_INVALID_HANDLE);
1470 
1471           policy = (struct tr_policy_obj *)obj->data;
1472 
1473           if (policy->delegationIndexSet || policy->delegationBlob) {
1474                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1475                               goto done;
1476                     *verCount = public.verificationCount;
1477                     free(public.pcrInfo.pcrSelection.pcrSelect);
1478           } else
1479                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1480 
1481 done:
1482           obj_list_put(&policy_list);
1483 
1484           return result;
1485 }
1486 
1487 TSS_RESULT
obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy,UINT32 * locality)1488 obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy, UINT32 *locality)
1489 {
1490           struct tsp_object *obj;
1491           struct tr_policy_obj *policy;
1492           TPM_DELEGATE_PUBLIC public;
1493           TSS_RESULT result = TSS_SUCCESS;
1494 
1495           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1496                     return TSPERR(TSS_E_INVALID_HANDLE);
1497 
1498           policy = (struct tr_policy_obj *)obj->data;
1499 
1500           if (policy->delegationIndexSet || policy->delegationBlob) {
1501                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1502                               goto done;
1503                     *locality = public.pcrInfo.localityAtRelease;
1504                     free(public.pcrInfo.pcrSelection.pcrSelect);
1505           } else
1506                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1507 
1508 done:
1509           obj_list_put(&policy_list);
1510 
1511           return result;
1512 }
1513 
1514 TSS_RESULT
obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy,UINT32 * digestLength,BYTE ** digest)1515 obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy, UINT32 *digestLength, BYTE **digest)
1516 {
1517           struct tsp_object *obj;
1518           struct tr_policy_obj *policy;
1519           TPM_DELEGATE_PUBLIC public;
1520           TSS_RESULT result = TSS_SUCCESS;
1521 
1522           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1523                     return TSPERR(TSS_E_INVALID_HANDLE);
1524 
1525           policy = (struct tr_policy_obj *)obj->data;
1526 
1527           if (policy->delegationIndexSet || policy->delegationBlob) {
1528                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1529                               goto done;
1530                     *digest = calloc_tspi(obj->tspContext, TPM_SHA1_160_HASH_LEN);
1531                     if (*digest == NULL) {
1532                               LogError("malloc of %u bytes failed.", TPM_SHA1_160_HASH_LEN);
1533                               result = TSPERR(TSS_E_OUTOFMEMORY);
1534                               goto done;
1535                     }
1536                     memcpy(*digest, &public.pcrInfo.digestAtRelease.digest, TPM_SHA1_160_HASH_LEN);
1537                     *digestLength = TPM_SHA1_160_HASH_LEN;
1538                     free(public.pcrInfo.pcrSelection.pcrSelect);
1539           } else
1540                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1541 
1542 done:
1543           obj_list_put(&policy_list);
1544 
1545           return result;
1546 }
1547 
1548 TSS_RESULT
obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy,UINT32 * selectionLength,BYTE ** selection)1549 obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy, UINT32 *selectionLength,
1550                                                   BYTE **selection)
1551 {
1552           struct tsp_object *obj;
1553           struct tr_policy_obj *policy;
1554           TPM_DELEGATE_PUBLIC public;
1555           UINT64 offset;
1556           TSS_RESULT result = TSS_SUCCESS;
1557 
1558           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1559                     return TSPERR(TSS_E_INVALID_HANDLE);
1560 
1561           policy = (struct tr_policy_obj *)obj->data;
1562 
1563           if (policy->delegationIndexSet || policy->delegationBlob) {
1564                     if ((result = obj_policy_get_delegate_public(obj, &public)))
1565                               goto done;
1566                     offset = 0;
1567                     Trspi_LoadBlob_PCR_SELECTION(&offset, NULL, &public.pcrInfo.pcrSelection);
1568                     *selection = calloc_tspi(obj->tspContext, offset);
1569                     if (*selection == NULL) {
1570                               LogError("malloc of %u bytes failed.", (UINT32)offset);
1571                               result = TSPERR(TSS_E_OUTOFMEMORY);
1572                               goto done;
1573                     }
1574                     offset = 0;
1575                     Trspi_LoadBlob_PCR_SELECTION(&offset, *selection, &public.pcrInfo.pcrSelection);
1576                     *selectionLength = offset;
1577                     free(public.pcrInfo.pcrSelection.pcrSelect);
1578           } else
1579                     result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1580 
1581 done:
1582           obj_list_put(&policy_list);
1583 
1584           return result;
1585 }
1586 
1587 TSS_RESULT
obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy,TSS_BOOL * indexSet)1588 obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy, TSS_BOOL *indexSet)
1589 {
1590           struct tsp_object *obj;
1591           struct tr_policy_obj *policy;
1592 
1593           if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1594                     return TSPERR(TSS_E_INVALID_HANDLE);
1595 
1596           policy = (struct tr_policy_obj *)obj->data;
1597 
1598           *indexSet = policy->delegationIndexSet;
1599 
1600           obj_list_put(&policy_list);
1601 
1602           return TSS_SUCCESS;
1603 }
1604 
1605 void
obj_policy_clear_delegation(struct tr_policy_obj * policy)1606 obj_policy_clear_delegation(struct tr_policy_obj *policy)
1607 {
1608           free(policy->delegationBlob);
1609           policy->delegationType = TSS_DELEGATIONTYPE_NONE;
1610           policy->delegationPer1 = 0;
1611           policy->delegationPer2 = 0;
1612           policy->delegationIndexSet = FALSE;
1613           policy->delegationIndex = 0;
1614           policy->delegationBlobLength = 0;
1615           policy->delegationBlob = NULL;
1616 }
1617 
1618 TSS_RESULT
obj_policy_get_delegate_public(struct tsp_object * obj,TPM_DELEGATE_PUBLIC * public)1619 obj_policy_get_delegate_public(struct tsp_object *obj, TPM_DELEGATE_PUBLIC *public)
1620 {
1621           struct tr_policy_obj *policy;
1622           UINT16 tag;
1623           TPM_DELEGATE_OWNER_BLOB ownerBlob;
1624           TPM_DELEGATE_KEY_BLOB keyBlob;
1625           UINT64 offset;
1626           TSS_RESULT result;
1627 
1628           policy = (struct tr_policy_obj *)obj->data;
1629 
1630           if (policy->delegationIndexSet) {
1631                     if ((result = get_delegate_index(obj->tspContext, policy->delegationIndex,
1632                                         public)))
1633                               return result;
1634           } else if (policy->delegationBlob) {
1635                     offset = 0;
1636                     Trspi_UnloadBlob_UINT16(&offset, &tag, policy->delegationBlob);
1637 
1638                     offset = 0;
1639                     switch (tag) {
1640                     case TPM_TAG_DELEGATE_OWNER_BLOB:
1641                               if ((result = Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(&offset,
1642                                                                                           policy->delegationBlob,
1643                                                                                           &ownerBlob)))
1644                                         return result;
1645                               *public = ownerBlob.pub;
1646                               free(ownerBlob.additionalArea);
1647                               free(ownerBlob.sensitiveArea);
1648                               break;
1649                     case TPM_TAG_DELG_KEY_BLOB:
1650                               if ((result = Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(&offset,
1651                                                                                                policy->delegationBlob,
1652                                                                                                &keyBlob)))
1653                                         return result;
1654                               *public = keyBlob.pub;
1655                               free(keyBlob.additionalArea);
1656                               free(keyBlob.sensitiveArea);
1657                               break;
1658                     default:
1659                               return TSPERR(TSS_E_INTERNAL_ERROR);
1660                     }
1661           } else
1662                     return TSPERR(TSS_E_INTERNAL_ERROR);
1663 
1664           return TSS_SUCCESS;
1665 }
1666 #endif
1667 
1668