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. 2004-2006 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 16 #include "trousers/tss.h" 17 #include "trousers/trousers.h" 18 #include "trousers_types.h" 19 #include "trousers_types.h" 20 #include "spi_utils.h" 21 #include "capabilities.h" 22 #include "tsplog.h" 23 #include "tcs_tsp.h" 24 #include "tspps.h" 25 #include "hosttable.h" 26 #include "tcsd_wrap.h" 27 #include "tcsd.h" 28 #include "obj.h" 29 30 TSS_UUID owner_evict_uuid = {0, 0, 0, 0, 0, {0, 0, 0, 0, 1, 0}}; 31 32 TSS_RESULT 33 Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */ 34 TSS_FLAG persistentStorageType, /* in */ 35 TSS_UUID uuidData, /* in */ 36 TSS_HKEY * phKey) /* out */ 37 { 38 TSS_RESULT result; 39 TSS_UUID parentUUID; 40 UINT32 keyBlobSize, parentPSType; 41 BYTE *keyBlob = NULL; 42 TCS_KEY_HANDLE tcsKeyHandle; 43 TSS_HKEY parentTspHandle; 44 TCS_LOADKEY_INFO info; 45 UINT32 ulPubKeyLength; 46 BYTE *rgbPubKey; 47 48 if (phKey == NULL) 49 return TSPERR(TSS_E_BAD_PARAMETER); 50 51 if ((!obj_is_context(tspContext))) 52 return TSPERR(TSS_E_INVALID_HANDLE); 53 54 /* This key is in the System Persistant storage */ 55 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 56 #if 1 57 memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); 58 59 result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); 60 61 if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { 62 TSS_HKEY keyHandle; 63 TSS_HPOLICY hPolicy; 64 65 /* load failed, due to some key in the chain needing auth 66 * which doesn't yet exist at the TCS level. However, the 67 * auth may already be set in policies at the TSP level. 68 * To find out, get the key handle of the key requiring 69 * auth. First, look at the list of keys in memory. */ 70 if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { 71 /* If that failed, look on disk, in User PS. */ 72 if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, 73 &keyHandle)) 74 return result; 75 } 76 77 if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, 78 &hPolicy, NULL)) 79 return result; 80 81 if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE, 82 &info.paramDigest, &info.authData)) 83 return result; 84 85 if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, 86 &tcsKeyHandle))) 87 return result; 88 } else if (result) 89 return result; 90 91 /*check if provided UUID has an owner evict key UUID prefix */ 92 if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) { 93 if ((result = obj_rsakey_add(tspContext, TSS_RSAKEY_FLAG_OWNEREVICT, 94 phKey))) 95 return result; 96 if ((result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle))) 97 return result; 98 99 //The cached public key portion of the owner evict key is used 100 //further by TPM_KEY_CONTROLOWNER command for sanity check 101 if ((result = Tspi_Key_GetPubKey(*phKey, &ulPubKeyLength, &rgbPubKey))) 102 return result; 103 104 result = obj_rsakey_set_pubkey(*phKey, FALSE, rgbPubKey); 105 106 free(rgbPubKey); 107 if (result != TSS_SUCCESS) 108 return result; 109 } else { 110 if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, 111 &keyBlob))) 112 return result; 113 114 if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, 115 TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { 116 free (keyBlob); 117 return result; 118 } 119 120 result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); 121 122 free (keyBlob); 123 } 124 #else 125 if ((result = load_from_system_ps(tspContext, &uuidData, phKey))) 126 return result; 127 #endif 128 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 129 if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID))) 130 return result; 131 132 /* If the parent is not in memory, recursively call ourselves on it */ 133 if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) { 134 if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType))) 135 return result; 136 137 if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType, 138 parentUUID, &parentTspHandle))) 139 return result; 140 } 141 142 if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) 143 return result; 144 145 /* The parent is loaded and we have the parent key handle, so call the TCS to 146 * actually load the child. */ 147 return Tspi_Key_LoadKey(*phKey, parentTspHandle); 148 } else { 149 return TSPERR(TSS_E_BAD_PARAMETER); 150 } 151 152 return TSS_SUCCESS; 153 } 154 155 TSS_RESULT 156 Tspi_Context_RegisterKey(TSS_HCONTEXT tspContext, /* in */ 157 TSS_HKEY hKey, /* in */ 158 TSS_FLAG persistentStorageType, /* in */ 159 TSS_UUID uuidKey, /* in */ 160 TSS_FLAG persistentStorageTypeParent, /* in */ 161 TSS_UUID uuidParentKey) /* in */ 162 { 163 BYTE *keyBlob; 164 UINT32 keyBlobSize; 165 TSS_RESULT result; 166 TSS_BOOL answer; 167 168 if (!obj_is_context(tspContext) || !obj_is_rsakey(hKey)) 169 return TSPERR(TSS_E_INVALID_HANDLE); 170 171 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 172 if (persistentStorageTypeParent == TSS_PS_TYPE_USER) { 173 return TSPERR(TSS_E_NOTIMPL); 174 } else if (persistentStorageTypeParent == TSS_PS_TYPE_SYSTEM) { 175 if ((result = obj_rsakey_get_blob(hKey, &keyBlobSize, 176 &keyBlob))) 177 return result; 178 179 if ((result = RPC_RegisterKey(tspContext, uuidParentKey, uuidKey, 180 keyBlobSize, keyBlob, 181 strlen(PACKAGE_STRING) + 1, 182 (BYTE *)PACKAGE_STRING))) 183 return result; 184 } else { 185 return TSPERR(TSS_E_BAD_PARAMETER); 186 } 187 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 188 if ((result = ps_is_key_registered(&uuidKey, &answer))) 189 return result; 190 191 if (answer == TRUE) 192 return TSPERR(TSS_E_KEY_ALREADY_REGISTERED); 193 194 if ((result = obj_rsakey_get_blob (hKey, &keyBlobSize, &keyBlob))) 195 return result; 196 197 if ((result = ps_write_key(&uuidKey, &uuidParentKey, 198 persistentStorageTypeParent, 199 keyBlobSize, keyBlob))) 200 return result; 201 } else { 202 return TSPERR(TSS_E_BAD_PARAMETER); 203 } 204 205 if ((result = obj_rsakey_set_uuid(hKey, persistentStorageType, &uuidKey))) 206 return result; 207 208 return TSS_SUCCESS; 209 } 210 211 TSS_RESULT 212 Tspi_Context_UnregisterKey(TSS_HCONTEXT tspContext, /* in */ 213 TSS_FLAG persistentStorageType, /* in */ 214 TSS_UUID uuidKey, /* in */ 215 TSS_HKEY *phKey) /* out */ 216 { 217 BYTE *keyBlob = NULL; 218 UINT32 keyBlobSize; 219 TSS_RESULT result; 220 221 if (phKey == NULL) 222 return TSPERR(TSS_E_BAD_PARAMETER); 223 224 if ((!obj_is_context(tspContext))) 225 return TSPERR(TSS_E_INVALID_HANDLE); 226 227 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 228 /* get the key first, so it doesn't disappear when we 229 * unregister it */ 230 if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidKey, &keyBlobSize, 231 &keyBlob))) 232 return result; 233 234 if ((obj_rsakey_add_by_key(tspContext, &uuidKey, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, 235 phKey))) { 236 free(keyBlob); 237 return result; 238 } 239 240 free(keyBlob); 241 242 /* now unregister it */ 243 if ((result = RPC_UnregisterKey(tspContext, uuidKey))) 244 return result; 245 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 246 /* get the key first, so it doesn't disappear when we 247 * unregister it */ 248 if ((result = ps_get_key_by_uuid(tspContext, &uuidKey, phKey))) 249 return result; 250 251 /* now unregister it */ 252 if ((result = ps_remove_key(&uuidKey))) 253 return result; 254 } else { 255 return TSPERR(TSS_E_BAD_PARAMETER); 256 } 257 258 return TSS_SUCCESS; 259 } 260 261 TSS_RESULT 262 Tspi_Context_GetKeyByUUID(TSS_HCONTEXT tspContext, /* in */ 263 TSS_FLAG persistentStorageType, /* in */ 264 TSS_UUID uuidData, /* in */ 265 TSS_HKEY * phKey) /* out */ 266 { 267 TCPA_RESULT result; 268 UINT32 keyBlobSize = 0; 269 BYTE *keyBlob = NULL; 270 271 if (phKey == NULL) 272 return TSPERR(TSS_E_BAD_PARAMETER); 273 274 if ((!obj_is_context(tspContext))) 275 return TSPERR(TSS_E_INVALID_HANDLE); 276 277 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 278 if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, 279 &keyBlob))) 280 return result; 281 282 if ((obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, 283 phKey))) { 284 free(keyBlob); 285 return result; 286 } 287 288 free(keyBlob); 289 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 290 if (!obj_is_context(tspContext)) 291 return TSPERR(TSS_E_INVALID_HANDLE); 292 293 if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) 294 return result; 295 } else 296 return TSPERR(TSS_E_BAD_PARAMETER); 297 298 return TSS_SUCCESS; 299 } 300 301 TSS_RESULT 302 Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext, /* in */ 303 TSS_FLAG persistentStorageType, /* in */ 304 TSS_ALGORITHM_ID algID, /* in */ 305 UINT32 ulPublicInfoLength, /* in */ 306 BYTE * rgbPublicInfo, /* in */ 307 TSS_HKEY * phKey) /* out */ 308 { 309 TCPA_ALGORITHM_ID tcsAlgID; 310 UINT32 keyBlobSize; 311 BYTE *keyBlob; 312 TSS_RESULT result; 313 TSS_HKEY keyOutHandle; 314 UINT32 flag = 0; 315 TSS_KEY keyContainer; 316 UINT64 offset; 317 318 if (phKey == NULL) 319 return TSPERR(TSS_E_BAD_PARAMETER); 320 321 if (!obj_is_context(tspContext)) 322 return TSPERR(TSS_E_INVALID_HANDLE); 323 324 switch (algID) { 325 case TSS_ALG_RSA: 326 tcsAlgID = TCPA_ALG_RSA; 327 break; 328 default: 329 LogError("Algorithm ID was not type RSA."); 330 return TSPERR(TSS_E_BAD_PARAMETER); 331 } 332 333 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 334 if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID, 335 ulPublicInfoLength, rgbPublicInfo, 336 &keyBlobSize, &keyBlob))) 337 return result; 338 339 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 340 return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo, 341 phKey); 342 } else 343 return TSPERR(TSS_E_BAD_PARAMETER); 344 345 /* need to setup the init flags of the create object based on 346 * the size of the blob's pubkey */ 347 offset = 0; 348 if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) { 349 free(keyBlob); 350 return result; 351 } 352 353 /* begin setting up the key object */ 354 switch (keyContainer.pubKey.keyLength) { 355 case 16384/8: 356 flag |= TSS_KEY_SIZE_16384; 357 break; 358 case 8192/8: 359 flag |= TSS_KEY_SIZE_8192; 360 break; 361 case 4096/8: 362 flag |= TSS_KEY_SIZE_4096; 363 break; 364 case 2048/8: 365 flag |= TSS_KEY_SIZE_2048; 366 break; 367 case 1024/8: 368 flag |= TSS_KEY_SIZE_1024; 369 break; 370 case 512/8: 371 flag |= TSS_KEY_SIZE_512; 372 break; 373 default: 374 LogError("Key was not a known keylength."); 375 free(keyBlob); 376 free_key_refs(&keyContainer); 377 return TSPERR(TSS_E_INTERNAL_ERROR); 378 } 379 380 if (keyContainer.keyUsage == TPM_KEY_SIGNING) 381 flag |= TSS_KEY_TYPE_SIGNING; 382 else if (keyContainer.keyUsage == TPM_KEY_STORAGE) 383 flag |= TSS_KEY_TYPE_STORAGE; 384 else if (keyContainer.keyUsage == TPM_KEY_IDENTITY) 385 flag |= TSS_KEY_TYPE_IDENTITY; 386 else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE) 387 flag |= TSS_KEY_TYPE_AUTHCHANGE; 388 else if (keyContainer.keyUsage == TPM_KEY_BIND) 389 flag |= TSS_KEY_TYPE_BIND; 390 else if (keyContainer.keyUsage == TPM_KEY_LEGACY) 391 flag |= TSS_KEY_TYPE_LEGACY; 392 393 if (keyContainer.authDataUsage == TPM_AUTH_NEVER) 394 flag |= TSS_KEY_NO_AUTHORIZATION; 395 else 396 flag |= TSS_KEY_AUTHORIZATION; 397 398 if (keyContainer.keyFlags & TPM_MIGRATABLE) 399 flag |= TSS_KEY_MIGRATABLE; 400 else 401 flag |= TSS_KEY_NOT_MIGRATABLE; 402 403 if (keyContainer.keyFlags & TPM_VOLATILE) 404 flag |= TSS_KEY_VOLATILE; 405 else 406 flag |= TSS_KEY_NON_VOLATILE; 407 408 #ifdef TSS_BUILD_CMK 409 if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY) 410 flag |= TSS_KEY_CERTIFIED_MIGRATABLE; 411 else 412 flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE; 413 #endif 414 415 /* Create a new Key Object */ 416 if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) { 417 free(keyBlob); 418 free_key_refs(&keyContainer); 419 return result; 420 } 421 /* Stick the info into this net KeyObject */ 422 if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) { 423 free(keyBlob); 424 free_key_refs(&keyContainer); 425 return result; 426 } 427 428 free(keyBlob); 429 free_key_refs(&keyContainer); 430 *phKey = keyOutHandle; 431 432 return TSS_SUCCESS; 433 } 434 435 TSS_RESULT 436 Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext, /* in */ 437 TSS_FLAG persistentStorageType, /* in */ 438 TSS_UUID * pUuidData, /* in */ 439 UINT32 * pulKeyHierarchySize, /* out */ 440 TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */ 441 { 442 TSS_RESULT result; 443 TSS_KM_KEYINFO *tcsHier, *tspHier; 444 UINT32 tcsHierSize, tspHierSize; 445 TSS_UUID tcs_uuid; 446 447 if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) 448 return TSPERR(TSS_E_BAD_PARAMETER); 449 450 if (!obj_is_context(tspContext)) 451 return TSPERR(TSS_E_INVALID_HANDLE); 452 453 if (pUuidData) { 454 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 455 if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, 456 pulKeyHierarchySize, 457 ppKeyHierarchy))) 458 return result; 459 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 460 if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid, 461 &tspHierSize, &tspHier))) 462 return result; 463 464 if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize, 465 &tcsHier))) { 466 free(tspHier); 467 return result; 468 } 469 470 result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, 471 tcsHierSize, tcsHier, pulKeyHierarchySize, 472 ppKeyHierarchy); 473 free(tcsHier); 474 free(tspHier); 475 } else 476 return TSPERR(TSS_E_BAD_PARAMETER); 477 } else { 478 if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize, 479 &tcsHier))) 480 return result; 481 482 if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) { 483 free(tcsHier); 484 return result; 485 } 486 487 result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize, 488 tcsHier, pulKeyHierarchySize, ppKeyHierarchy); 489 free(tcsHier); 490 free(tspHier); 491 } 492 493 if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { 494 free(*ppKeyHierarchy); 495 *ppKeyHierarchy = NULL; 496 *pulKeyHierarchySize = 0; 497 } 498 499 return result; 500 } 501 502 TSS_RESULT 503 Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext, /* in */ 504 TSS_FLAG persistentStorageType, /* in */ 505 TSS_UUID * pUuidData, /* in */ 506 UINT32 * pulKeyHierarchySize, /* out */ 507 TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */ 508 { 509 TSS_RESULT result; 510 TSS_KM_KEYINFO2 *tcsHier, *tspHier; 511 UINT32 tcsHierSize, tspHierSize; 512 TSS_UUID tcs_uuid; 513 514 /* If out parameters are NULL, return error */ 515 if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) 516 return TSPERR(TSS_E_BAD_PARAMETER); 517 518 if (!obj_is_context(tspContext)) 519 return TSPERR(TSS_E_INVALID_HANDLE); 520 521 if (pUuidData) { 522 /* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of 523 * TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key 524 * hierarchy regarding that key. The first array entry is the key addressed by the 525 * given UUID followed by its parent key up to and including the root key. */ 526 if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { 527 if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, 528 pulKeyHierarchySize, ppKeyHierarchy))) 529 return result; 530 } else if (persistentStorageType == TSS_PS_TYPE_USER) { 531 if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize, 532 &tspHier))) 533 return result; 534 /* The tcs_uuid returned by ps_get_registered_key2 will always be a parent 535 * of some key into the system ps of a user key into the user ps. This key 536 * needs to be searched for in the system ps to be merged */ 537 if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize, 538 &tcsHier))) { 539 free(tspHier); 540 return result; 541 } 542 543 result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, 544 tcsHierSize, tcsHier, pulKeyHierarchySize, 545 ppKeyHierarchy); 546 free(tcsHier); 547 free(tspHier); 548 } else 549 return TSPERR(TSS_E_BAD_PARAMETER); 550 } else { 551 /* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures 552 * contains data reflecting the entire key hierarchy starting with root key. The 553 * array will include keys from both the user and the system TSS key store. The 554 * persistentStorageType field will be ignored. */ 555 if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize, 556 &tcsHier))) 557 return result; 558 559 if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) { 560 free(tcsHier); 561 return result; 562 } 563 564 result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize, 565 tcsHier, pulKeyHierarchySize, ppKeyHierarchy); 566 free(tcsHier); 567 free(tspHier); 568 } 569 570 if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { 571 free(*ppKeyHierarchy); 572 *ppKeyHierarchy = NULL; 573 *pulKeyHierarchySize = 0; 574 } 575 576 return result; 577 } 578