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