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 28TSS_RESULT 29obj_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 63void 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 75TSS_RESULT 76obj_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 88TSS_BOOL 89obj_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 101TSS_RESULT 102obj_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 118TSS_RESULT 119obj_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 135TSS_RESULT 136obj_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 150TSS_RESULT 151obj_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 185TSS_RESULT 186obj_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 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 239TSS_RESULT 240obj_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 memset(&policy->Secret, 0, policy->SecretSize); 251 policy->SecretSet = FALSE; 252 253 obj_list_put(&policy_list); 254 255 return TSS_SUCCESS; 256} 257 258TSS_RESULT 259obj_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; 298done: 299 obj_list_put(&policy_list); 300 301 return result; 302} 303 304TSS_RESULT 305obj_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 323TSS_RESULT 324obj_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 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 360TSS_RESULT 361obj_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 399TSS_RESULT 400obj_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 442TSS_RESULT 443obj_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 535TSS_RESULT 536obj_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 } 597done: 598 obj_list_put(&policy_list); 599 600 return result; 601} 602 603TSS_RESULT 604obj_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 620TSS_RESULT 621obj_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 672TSS_RESULT 673obj_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 689TSS_RESULT 690obj_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 711TSS_RESULT 712obj_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 */ 734TSS_RESULT 735obj_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 773done: 774 obj_list_put(&policy_list); 775 776 return result; 777} 778 779TSS_RESULT 780obj_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 799TSS_RESULT 800obj_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 833done: 834 obj_list_put(&policy_list); 835 836 return result; 837} 838 839TSS_RESULT 840policy_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 875TSS_RESULT 876obj_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 894TSS_RESULT 895obj_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; 991done: 992 obj_list_put(&policy_list); 993 994 return result; 995} 996 997TSS_RESULT 998obj_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 1028TSS_RESULT 1029obj_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 1052TSS_RESULT 1053obj_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 1069TSS_RESULT 1070obj_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 1095TSS_RESULT 1096obj_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 1122done: 1123 obj_list_put(&policy_list); 1124 1125 return result; 1126} 1127 1128 1129TSS_RESULT 1130obj_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 1147TSS_RESULT 1148obj_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 1180done: 1181 obj_list_put(&policy_list); 1182 1183 return result; 1184} 1185 1186TSS_RESULT 1187obj_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 1205done: 1206 obj_list_put(&policy_list); 1207 1208 return result; 1209} 1210 1211TSS_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 1229done: 1230 obj_list_put(&policy_list); 1231 1232 return result; 1233} 1234 1235TSS_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 1255done: 1256 obj_list_put(&policy_list); 1257 1258 return result; 1259} 1260 1261TSS_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 1279done: 1280 obj_list_put(&policy_list); 1281 1282 return result; 1283} 1284 1285TSS_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 1305done: 1306 obj_list_put(&policy_list); 1307 1308 return result; 1309} 1310 1311TSS_RESULT 1312obj_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 1363done: 1364 obj_list_put(&policy_list); 1365 1366 return result; 1367} 1368 1369TSS_RESULT 1370obj_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 1400done: 1401 obj_list_put(&policy_list); 1402 1403 return result; 1404} 1405 1406TSS_RESULT 1407obj_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 1427done: 1428 obj_list_put(&policy_list); 1429 1430 return result; 1431} 1432 1433TSS_RESULT 1434obj_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 1454done: 1455 obj_list_put(&policy_list); 1456 1457 return result; 1458} 1459 1460TSS_RESULT 1461obj_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 1481done: 1482 obj_list_put(&policy_list); 1483 1484 return result; 1485} 1486 1487TSS_RESULT 1488obj_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 1508done: 1509 obj_list_put(&policy_list); 1510 1511 return result; 1512} 1513 1514TSS_RESULT 1515obj_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 1542done: 1543 obj_list_put(&policy_list); 1544 1545 return result; 1546} 1547 1548TSS_RESULT 1549obj_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 1581done: 1582 obj_list_put(&policy_list); 1583 1584 return result; 1585} 1586 1587TSS_RESULT 1588obj_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 1605void 1606obj_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 1618TSS_RESULT 1619obj_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