Home | History | Annotate | Line # | Download | only in tspi
      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
     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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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 
   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 
   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 
   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 
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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