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