TSS_RESULT TCS_GetRegisteredKeyBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ TSS_UUID *KeyUUID, /* in */ UINT32 * pcKeySize, /* out */ BYTE ** prgbKey) /* out */ { UINT16 keySize; BYTE buffer[4096]; TSS_RESULT result; if ((result = ctx_verify_context(hContext))) return result; keySize = sizeof(buffer); if ((result = ps_get_key_by_uuid(KeyUUID, buffer, &keySize))) return TCSERR(TSS_E_PS_KEY_NOTFOUND); *prgbKey = calloc(1, keySize); if (*prgbKey == NULL) { LogError("malloc of %d bytes failed.", keySize); return TCSERR(TSS_E_OUTOFMEMORY); } else { memcpy(*prgbKey, buffer, keySize); } *pcKeySize = keySize; return TSS_SUCCESS; }
TSS_RESULT TCS_GetRegisteredKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ TSS_UUID *KeyUUID, /* in */ TSS_KM_KEYINFO ** ppKeyInfo) /* out */ { TSS_RESULT result; UINT64 offset; BYTE tcpaKeyBlob[1024]; TSS_KEY tcpaKey; UINT16 keySize = sizeof (tcpaKeyBlob); TSS_UUID parentUUID; /* This should be set in case we return before the malloc */ *ppKeyInfo = NULL; if ((result = ctx_verify_context(hContext))) return result; if ((result = ps_get_key_by_uuid(KeyUUID, tcpaKeyBlob, &keySize))) { return TCSERR(TSS_E_PS_KEY_NOTFOUND); } if ((result = getParentUUIDByUUID(KeyUUID, &parentUUID))) return TCSERR(TSS_E_FAIL); *ppKeyInfo = malloc(sizeof(TSS_KM_KEYINFO)); if (*ppKeyInfo == NULL) { LogError("malloc of %zd bytes failed.", sizeof(TSS_KM_KEYINFO)); return TCSERR(TSS_E_OUTOFMEMORY); } offset = 0; UnloadBlob_TSS_KEY(&offset, tcpaKeyBlob, &tcpaKey); (*ppKeyInfo)->bAuthDataUsage = tcpaKey.authDataUsage; (*ppKeyInfo)->fIsLoaded = FALSE; if (tcpaKey.hdr.key12.tag == TPM_TAG_KEY12) { (*ppKeyInfo)->versionInfo.bMajor = TSS_SPEC_MAJOR; (*ppKeyInfo)->versionInfo.bMinor = TSS_SPEC_MINOR; (*ppKeyInfo)->versionInfo.bRevMajor = 0; (*ppKeyInfo)->versionInfo.bRevMinor = 0; } else { (*ppKeyInfo)->versionInfo.bMajor = tcpaKey.hdr.key11.ver.major; (*ppKeyInfo)->versionInfo.bMinor = tcpaKey.hdr.key11.ver.minor; (*ppKeyInfo)->versionInfo.bRevMajor = tcpaKey.hdr.key11.ver.revMajor; (*ppKeyInfo)->versionInfo.bRevMinor = tcpaKey.hdr.key11.ver.revMinor; } memcpy(&((*ppKeyInfo)->keyUUID), KeyUUID, sizeof(TSS_UUID)); (*ppKeyInfo)->ulVendorDataLength = 0; (*ppKeyInfo)->rgbVendorData = 0; memcpy(&((*ppKeyInfo)->parentKeyUUID), &parentUUID, sizeof(TSS_UUID)); return TSS_SUCCESS; }
TSS_RESULT Tspi_Context_UnregisterKey(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID uuidKey, /* in */ TSS_HKEY *phKey) /* out */ { BYTE *keyBlob = NULL; UINT32 keyBlobSize; TSS_RESULT result; if (phKey == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((!obj_is_context(tspContext))) return TSPERR(TSS_E_INVALID_HANDLE); if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { /* get the key first, so it doesn't disappear when we * unregister it */ if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidKey, &keyBlobSize, &keyBlob))) return result; if ((obj_rsakey_add_by_key(tspContext, &uuidKey, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { free(keyBlob); return result; } free(keyBlob); /* now unregister it */ if ((result = RPC_UnregisterKey(tspContext, uuidKey))) return result; } else if (persistentStorageType == TSS_PS_TYPE_USER) { /* get the key first, so it doesn't disappear when we * unregister it */ if ((result = ps_get_key_by_uuid(tspContext, &uuidKey, phKey))) return result; /* now unregister it */ if ((result = ps_remove_key(&uuidKey))) return result; } else { return TSPERR(TSS_E_BAD_PARAMETER); } return TSS_SUCCESS; }
TSS_RESULT Tspi_Context_GetKeyByUUID(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID uuidData, /* in */ TSS_HKEY * phKey) /* out */ { TCPA_RESULT result; UINT32 keyBlobSize = 0; BYTE *keyBlob = NULL; if (phKey == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((!obj_is_context(tspContext))) return TSPERR(TSS_E_INVALID_HANDLE); if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, &keyBlob))) return result; if ((obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { free(keyBlob); return result; } free(keyBlob); } else if (persistentStorageType == TSS_PS_TYPE_USER) { if (!obj_is_context(tspContext)) return TSPERR(TSS_E_INVALID_HANDLE); if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) return result; } else return TSPERR(TSS_E_BAD_PARAMETER); return TSS_SUCCESS; }
TSS_RESULT Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID uuidData, /* in */ TSS_HKEY * phKey) /* out */ { TSS_RESULT result; TSS_UUID parentUUID; UINT32 keyBlobSize, parentPSType; BYTE *keyBlob = NULL; TCS_KEY_HANDLE tcsKeyHandle; TSS_HKEY parentTspHandle; TCS_LOADKEY_INFO info; UINT32 ulPubKeyLength; BYTE *rgbPubKey; if (phKey == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((!obj_is_context(tspContext))) return TSPERR(TSS_E_INVALID_HANDLE); /* This key is in the System Persistant storage */ if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { #if 1 memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { TSS_HKEY keyHandle; TSS_HPOLICY hPolicy; /* load failed, due to some key in the chain needing auth * which doesn't yet exist at the TCS level. However, the * auth may already be set in policies at the TSP level. * To find out, get the key handle of the key requiring * auth. First, look at the list of keys in memory. */ if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { /* If that failed, look on disk, in User PS. */ if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, &keyHandle)) return result; } if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, &hPolicy, NULL)) return result; if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE, &info.paramDigest, &info.authData)) return result; if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle))) return result; } else if (result) return result; /*check if provided UUID has an owner evict key UUID prefix */ if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) { if ((result = obj_rsakey_add(tspContext, TSS_RSAKEY_FLAG_OWNEREVICT, phKey))) return result; if ((result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle))) return result; //The cached public key portion of the owner evict key is used //further by TPM_KEY_CONTROLOWNER command for sanity check if ((result = Tspi_Key_GetPubKey(*phKey, &ulPubKeyLength, &rgbPubKey))) return result; result = obj_rsakey_set_pubkey(*phKey, FALSE, rgbPubKey); free(rgbPubKey); if (result != TSS_SUCCESS) return result; } else { if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, &keyBlob))) return result; if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { free (keyBlob); return result; } result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); free (keyBlob); } #else if ((result = load_from_system_ps(tspContext, &uuidData, phKey))) return result; #endif } else if (persistentStorageType == TSS_PS_TYPE_USER) { if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID))) return result; /* If the parent is not in memory, recursively call ourselves on it */ if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) { if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType))) return result; if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType, parentUUID, &parentTspHandle))) return result; } if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) return result; /* The parent is loaded and we have the parent key handle, so call the TCS to * actually load the child. */ return Tspi_Key_LoadKey(*phKey, parentTspHandle); } else { return TSPERR(TSS_E_BAD_PARAMETER); } return TSS_SUCCESS; }
TSS_RESULT TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ TSS_UUID *KeyUUID, /* in */ TCS_LOADKEY_INFO * pLoadKeyInfo, /* in, out */ TCS_KEY_HANDLE * phKeyTCSI) /* out */ { UINT32 keyslot = 0, keySize; UINT32 ordinal; TSS_RESULT result; TSS_UUID parentUuid; BYTE keyBlob[0x1000]; UINT16 blobSize = sizeof(keyBlob); UINT64 offset; TCS_KEY_HANDLE parentTCSKeyHandle; if (TPM_VERSION_IS(1,2)) ordinal = TPM_ORD_LoadKey2; else ordinal = TPM_ORD_LoadKey; LogDebugFn("Enter: uuid: 0x%lx auth? 0x%x ***********", (unsigned long)KeyUUID, pLoadKeyInfo == NULL ? 0xdeadbeef : pLoadKeyInfo->authData.AuthHandle); if ((result = ctx_verify_context(hContext))) return result; memset(&parentUuid, 0, sizeof(TSS_UUID)); if (pLoadKeyInfo && memcmp(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID))) { if (ps_get_key_by_uuid(&pLoadKeyInfo->keyUUID, keyBlob, &blobSize)) return TCSERR(TSS_E_PS_KEY_NOTFOUND); if (mc_get_handles_by_uuid(&pLoadKeyInfo->parentKeyUUID, &parentTCSKeyHandle, &keyslot)) return TCSERR(TCS_E_KM_LOADFAILED); return LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle, blobSize, keyBlob, &pLoadKeyInfo->authData, phKeyTCSI, &keyslot); } /* if KeyUUID is already loaded, increment the ref count and return */ if (mc_get_handles_by_uuid(KeyUUID, phKeyTCSI, &keyslot) == TSS_SUCCESS) { if (keyslot) { if (ctx_mark_key_loaded(hContext, *phKeyTCSI)) { LogError("Error marking key as loaded"); return TCSERR(TSS_E_INTERNAL_ERROR); } return TSS_SUCCESS; } } /********************************************************************* * The first thing to do in this func is setup all the info and make sure * that we get it all from either the keyfile or the keyCache * also, it's important to return if the key is already loaded ***********************************************************************/ LogDebugFn("calling ps_get_key_by_uuid"); if (ps_get_key_by_uuid(KeyUUID, keyBlob, &blobSize)) return TCSERR(TSS_E_PS_KEY_NOTFOUND); /* convert UINT16 to UIN32 */ keySize = blobSize; LogDebugFn("calling getParentUUIDByUUID"); /*--- Get my parent's UUID. Since My key is registered, my parent should be as well. */ if ((result = getParentUUIDByUUID(KeyUUID, &parentUuid))) return TCSERR(TCS_E_KM_LOADFAILED); if ((result = TCSP_LoadKeyByUUID_Internal(hContext, &parentUuid, pLoadKeyInfo, &parentTCSKeyHandle))) return result; LogDebugFn("calling LoadKeyByBlob_Internal"); /******************************************************* * If no errors have happend up till now, then the parent is loaded and ready for use. * The parent's TCS Handle should be in parentTCSKeyHandle. ******************************************************/ if ((result = LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle, keySize, keyBlob, NULL, phKeyTCSI, &keyslot))) { LogDebugFn("LoadKeyByBlob_Internal returned 0x%x", result); if (result == TCPA_E_AUTHFAIL && pLoadKeyInfo) { BYTE blob[1000]; /* set up a load key info struct */ memcpy(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID)); memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, sizeof(TSS_UUID)); /* calculate the paramDigest */ offset = 0; LoadBlob_UINT32(&offset, ordinal, blob); LoadBlob(&offset, keySize, blob, keyBlob); if (Hash(TSS_HASH_SHA1, offset, blob, (BYTE *)&pLoadKeyInfo->paramDigest.digest)) result = TCSERR(TSS_E_INTERNAL_ERROR); result = TCSERR(TCS_E_KM_LOADFAILED); } } return result; }