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-2007 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_types.h" 18#include "tcs_tsp.h" 19#include "tcs_utils.h" 20#include "tcs_int_literals.h" 21#include "capabilities.h" 22#include "tcslog.h" 23#include "tcsps.h" 24#include "req_mgr.h" 25 26 27TSS_RESULT 28TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 29 TCS_KEY_HANDLE hUnwrappingKey, /* in */ 30 UINT32 cWrappedKeyBlobSize, /* in */ 31 BYTE * rgbWrappedKeyBlob, /* in */ 32 TPM_AUTH * pAuth, /* in, out */ 33 TCS_KEY_HANDLE * phKeyTCSI, /* out */ 34 TCS_KEY_HANDLE * phKeyHMAC) /* out */ 35{ 36 return LoadKeyByBlob_Internal(TPM_ORD_LoadKey, hContext, hUnwrappingKey, 37 cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI, 38 phKeyHMAC); 39} 40 41TSS_RESULT 42TCSP_LoadKey2ByBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 43 TCS_KEY_HANDLE hUnwrappingKey, /* in */ 44 UINT32 cWrappedKeyBlobSize, /* in */ 45 BYTE * rgbWrappedKeyBlob, /* in */ 46 TPM_AUTH * pAuth, /* in, out */ 47 TCS_KEY_HANDLE * phKeyTCSI) /* out */ 48{ 49 return LoadKeyByBlob_Internal(TPM_ORD_LoadKey2, hContext, hUnwrappingKey, 50 cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI, 51 NULL); 52} 53 54TSS_RESULT 55LoadKeyByBlob_Internal(UINT32 ord, /* The ordinal to use, LoadKey or LoadKey2 */ 56 TCS_CONTEXT_HANDLE hContext, /* in */ 57 TCS_KEY_HANDLE hUnwrappingKey, /* in */ 58 UINT32 cWrappedKeyBlobSize, /* in */ 59 BYTE * rgbWrappedKeyBlob, /* in */ 60 TPM_AUTH * pAuth, /* in, out */ 61 TCS_KEY_HANDLE * phKeyTCSI, /* out */ 62 TCS_KEY_HANDLE * phKeyHMAC) /* out */ 63{ 64 UINT64 offset; 65 TSS_RESULT result; 66 UINT32 paramSize; 67 TPM_KEY_HANDLE parentSlot, newSlot; 68 TCS_KEY_HANDLE newHandle = NULL_TCS_HANDLE; 69 TSS_BOOL canLoad; 70 TSS_KEY key; 71 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 72 73 if ((result = ctx_verify_context(hContext))) 74 return result; 75 76 LogDebugFn("Enter"); 77 LogDebugUnrollKey(rgbWrappedKeyBlob); 78 79 if ((result = get_slot(hContext, hUnwrappingKey, &parentSlot))) 80 return result; 81 82 offset = 0; 83 memset(&key, 0, sizeof(TSS_KEY)); 84 if ((result = UnloadBlob_TSS_KEY(&offset, rgbWrappedKeyBlob, &key))) 85 return result; 86 87 if (!pAuth) { 88 LogDebugFn("Checking if LoadKeyByBlob can be avoided by using existing key"); 89 90 if ((newHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey))) { 91 LogDebugFn("tcs key handle exists"); 92 93 newSlot = mc_get_slot_by_handle(newHandle); 94 if (newSlot && (isKeyLoaded(newSlot) == TRUE)) { 95 LogDebugFn("Don't need to reload this key."); 96 *phKeyTCSI = newHandle; 97 if (phKeyHMAC) 98 *phKeyHMAC = newSlot; 99 return TSS_SUCCESS; 100 } 101 } 102 } 103 104 LogDebugFn("calling canILoadThisKey"); 105 if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad))) 106 goto error; 107 108 if (canLoad == FALSE) { 109 LogDebugFn("calling evictFirstKey"); 110 /* Evict a key that isn't the parent */ 111 if ((result = evictFirstKey(hUnwrappingKey))) 112 goto error; 113 } 114 115 offset = 0; 116 if ((result = tpm_rqu_build(ord, &offset, txBlob, parentSlot, cWrappedKeyBlobSize, 117 rgbWrappedKeyBlob, pAuth, NULL))) 118 goto error; 119 120 LogDebugFn("Submitting request to the TPM"); 121 if ((result = req_mgr_submit_req(txBlob))) 122 goto error; 123 124 if ((result = UnloadBlob_Header(txBlob, ¶mSize))) { 125 LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result); 126 goto error; 127 } 128 129 if ((result = tpm_rsp_parse(ord, txBlob, paramSize, &newSlot, pAuth))) 130 goto error; 131 132 if ((result = load_key_final(hContext, hUnwrappingKey, &newHandle, rgbWrappedKeyBlob, 133 newSlot))) 134 goto error; 135 136 /* Setup the outHandles */ 137 *phKeyTCSI = newHandle; 138 if (phKeyHMAC) 139 *phKeyHMAC = newSlot; 140 141 LogDebugFn("Key handles for loadKeyByBlob slot:%.8X tcshandle:%.8X", newSlot, newHandle); 142error: 143 auth_mgr_release_auth(pAuth, NULL, hContext); 144 return result; 145} 146 147TSS_RESULT 148TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 149 TCS_KEY_HANDLE hKey) /* in */ 150{ 151 TSS_RESULT result; 152 TCPA_KEY_HANDLE tpm_handle; 153 154 if ((result = ctx_verify_context(hContext))) 155 return result; 156 157 tpm_handle = mc_get_slot_by_handle(hKey); 158 if (tpm_handle == NULL_TPM_HANDLE) 159 return TSS_SUCCESS; /*let's call this success if the key is already evicted */ 160 161 if ((result = internal_EvictByKeySlot(tpm_handle))) 162 return result; 163 164 result = mc_set_slot_by_slot(tpm_handle, NULL_TPM_HANDLE); 165 166 return result; 167} 168 169TSS_RESULT 170TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 171 TCS_KEY_HANDLE hWrappingKey, /* in */ 172 TCPA_ENCAUTH KeyUsageAuth, /* in */ 173 TCPA_ENCAUTH KeyMigrationAuth, /* in */ 174 UINT32 keyInfoSize, /* in */ 175 BYTE * keyInfo, /* in */ 176 UINT32 * keyDataSize, /* out */ 177 BYTE ** keyData, /* out */ 178 TPM_AUTH * pAuth) /* in, out */ 179{ 180 UINT64 offset = 0; 181 UINT32 paramSize; 182 TSS_RESULT result; 183 TCPA_KEY_HANDLE parentSlot; 184 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 185 186 LogDebug("Entering Create Wrap Key"); 187 188 if ((result = ctx_verify_context(hContext))) 189 goto done; 190 191 if (pAuth) { 192 if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle))) 193 goto done; 194 } 195 196 /* Since hWrappingKey must already be loaded, we can fail immediately if 197 * mc_get_slot_by_handle_lock() fails.*/ 198 parentSlot = mc_get_slot_by_handle_lock(hWrappingKey); 199 if (parentSlot == NULL_TPM_HANDLE) { 200 result = TCSERR(TSS_E_FAIL); 201 goto done; 202 } 203 204 if ((result = tpm_rqu_build(TPM_ORD_CreateWrapKey, &offset, txBlob, parentSlot, 205 KeyUsageAuth.authdata, KeyMigrationAuth.authdata, keyInfoSize, 206 keyInfo, pAuth))) 207 goto done; 208 209 if ((result = req_mgr_submit_req(txBlob))) 210 goto done; 211 212 result = UnloadBlob_Header(txBlob, ¶mSize); 213 if (!result) { 214 result = tpm_rsp_parse(TPM_ORD_CreateWrapKey, txBlob, paramSize, keyDataSize, 215 keyData, pAuth); 216 } 217 LogResult("Create Wrap Key", result); 218 219done: 220 auth_mgr_release_auth(pAuth, NULL, hContext); 221 return result; 222} 223 224TSS_RESULT 225TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 226 TCS_KEY_HANDLE hKey, /* in */ 227 TPM_AUTH * pAuth, /* in, out */ 228 UINT32 * pcPubKeySize, /* out */ 229 BYTE ** prgbPubKey) /* out */ 230{ 231 UINT64 offset = 0; 232 UINT32 paramSize; 233 TSS_RESULT result; 234 TCPA_KEY_HANDLE keySlot; 235 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 236 237 LogDebug("Entering Get pub key"); 238 if ((result = ctx_verify_context(hContext))) 239 goto done; 240 241 if (pAuth != NULL) { 242 LogDebug("Auth Used"); 243 if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle))) 244 goto done; 245 } else { 246 LogDebug("No Auth"); 247 } 248 249 if (ensureKeyIsLoaded(hContext, hKey, &keySlot)) { 250 result = TCSERR(TCS_E_KM_LOADFAILED); 251 goto done; 252 } 253 254 LogDebug("GetPubKey: handle: 0x%x, slot: 0x%x", hKey, keySlot); 255 if ((result = tpm_rqu_build(TPM_ORD_GetPubKey, &offset, txBlob, keySlot, pAuth))) 256 goto done; 257 258 if ((result = req_mgr_submit_req(txBlob))) 259 goto done; 260 261 offset = 10; 262 result = UnloadBlob_Header(txBlob, ¶mSize); 263 264 if (!result) { 265 result = tpm_rsp_parse(TPM_ORD_GetPubKey, txBlob, paramSize, pcPubKeySize, 266 prgbPubKey, pAuth); 267 } 268 LogResult("Get Public Key", result); 269done: 270 auth_mgr_release_auth(pAuth, NULL, hContext); 271 return result; 272} 273 274TSS_RESULT 275TCSP_OwnerReadInternalPub_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 276 TCS_KEY_HANDLE hKey, /* in */ 277 TPM_AUTH * pOwnerAuth, /* in, out */ 278 UINT32 * punPubKeySize, /* out */ 279 BYTE ** ppbPubKeyData) /* out */ 280{ 281 UINT64 offset = 0; 282 UINT32 paramSize; 283 TSS_RESULT result; 284 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 285 286 LogDebug("Entering OwnerReadInternalPub"); 287 if ((result = ctx_verify_context(hContext))) 288 goto done; 289 290 LogDebug("OwnerReadInternalPub: handle: 0x%x", hKey); 291 if (hKey != TPM_KH_SRK && hKey != TPM_KH_EK) { 292 result = TCSERR(TSS_E_FAIL); 293 LogDebug("OwnerReadInternalPub - Unsupported Key Handle"); 294 goto done; 295 } 296 297 if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle))) 298 goto done; 299 300 if ((result = tpm_rqu_build(TPM_ORD_OwnerReadInternalPub, &offset, txBlob, hKey, 301 pOwnerAuth))) 302 goto done; 303 304 if ((result = req_mgr_submit_req(txBlob))) 305 goto done; 306 307 result = UnloadBlob_Header(txBlob, ¶mSize); 308 if (!result) { 309 result = tpm_rsp_parse(TPM_ORD_OwnerReadInternalPub, txBlob, paramSize, 310 punPubKeySize, ppbPubKeyData, pOwnerAuth); 311 } 312 LogResult("OwnerReadInternalPub", result); 313done: 314 auth_mgr_release_auth(pOwnerAuth, NULL, hContext); 315 return result; 316} 317 318TSS_RESULT 319TCSP_KeyControlOwner_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 320 TCS_KEY_HANDLE hTcsKey, /* in */ 321 UINT32 ulPubKeyLength, /* in */ 322 BYTE* rgbPubKey, /* in */ 323 UINT32 attribName, /* in */ 324 TSS_BOOL attribValue, /* in */ 325 TPM_AUTH* pOwnerAuth, /* in,out */ 326 TSS_UUID* pUuidData) /* out */ 327{ 328 UINT64 offset = 0; 329 UINT32 paramSize; 330 TSS_RESULT result; 331 TPM_KEY_HANDLE hTpmKey; 332 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 333 334 LogDebugFn("Enter"); 335 if ((result = ctx_verify_context(hContext))) { 336 LogDebug("Invalid TSS Context"); 337 goto done; 338 } 339 340 if ((result = get_slot_lite(hContext, hTcsKey, &hTpmKey))) { 341 LogDebug("Can't get TPM Keyhandle for TCS key 0x%x", hTcsKey); 342 goto done; 343 } 344 LogDebugFn("TCS hKey=0x%x, TPM hKey=0x%x", hTcsKey, hTpmKey); 345 346 if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle))) { 347 LogDebug("Owner Authentication failed"); 348 goto done; 349 } 350 351 if ((result = mc_find_next_ownerevict_uuid(pUuidData))) { 352 LogDebugFn("mc_find_next_ownerevict_uuid failed: rc=0x%x", result); 353 goto done; 354 } 355 356 if ((result = tpm_rqu_build(TPM_ORD_KeyControlOwner, &offset, txBlob, hTpmKey, 357 ulPubKeyLength, rgbPubKey, attribName, attribValue, 358 pOwnerAuth))) { 359 LogDebugFn("rqu build failed"); 360 goto done; 361 } 362 363 if ((result = req_mgr_submit_req(txBlob))) { 364 LogDebugFn("Request submission failed"); 365 goto done; 366 } 367 368 if ((result = UnloadBlob_Header(txBlob, ¶mSize))) { 369 LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result); 370 goto done; 371 } 372 373 if ((result = tpm_rsp_parse(TPM_ORD_KeyControlOwner, txBlob, paramSize, pOwnerAuth))) { 374 LogDebugFn("tpm_rsp_parse failed: rc=0x%x", result); 375 goto done; 376 } 377 378 if ((result = mc_set_uuid(hTcsKey, pUuidData))){ 379 LogDebugFn("mc_set_uuid failed: rc=0x%x", result); 380 goto done; 381 } 382 383 LogResult("KeyControlOwner", result); 384done: 385 auth_mgr_release_auth(pOwnerAuth, NULL, hContext); 386 return result; 387} 388 389