/*
* Licensed Materials - Property of IBM
*
* trousers - An open source TCG Software Stack
*
* (C) Copyright International Business Machines Corp. 2004-2007
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"
TSS_RESULT
TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hUnwrappingKey, /* in */
UINT32 cWrappedKeyBlobSize, /* in */
BYTE * rgbWrappedKeyBlob, /* in */
TPM_AUTH * pAuth, /* in, out */
TCS_KEY_HANDLE * phKeyTCSI, /* out */
TCS_KEY_HANDLE * phKeyHMAC) /* out */
{
return LoadKeyByBlob_Internal(TPM_ORD_LoadKey, hContext, hUnwrappingKey,
cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
phKeyHMAC);
}
TSS_RESULT
TCSP_LoadKey2ByBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hUnwrappingKey, /* in */
UINT32 cWrappedKeyBlobSize, /* in */
BYTE * rgbWrappedKeyBlob, /* in */
TPM_AUTH * pAuth, /* in, out */
TCS_KEY_HANDLE * phKeyTCSI) /* out */
{
return LoadKeyByBlob_Internal(TPM_ORD_LoadKey2, hContext, hUnwrappingKey,
cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
NULL);
}
TSS_RESULT
LoadKeyByBlob_Internal(UINT32 ord, /* The ordinal to use, LoadKey or LoadKey2 */
TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hUnwrappingKey, /* in */
UINT32 cWrappedKeyBlobSize, /* in */
BYTE * rgbWrappedKeyBlob, /* in */
TPM_AUTH * pAuth, /* in, out */
TCS_KEY_HANDLE * phKeyTCSI, /* out */
TCS_KEY_HANDLE * phKeyHMAC) /* out */
{
UINT64 offset;
TSS_RESULT result;
UINT32 paramSize;
TPM_KEY_HANDLE parentSlot, newSlot;
TCS_KEY_HANDLE newHandle = NULL_TCS_HANDLE;
TSS_BOOL canLoad;
TSS_KEY key;
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
if ((result = ctx_verify_context(hContext)))
return result;
LogDebugFn("Enter");
LogDebugUnrollKey(rgbWrappedKeyBlob);
if ((result = get_slot(hContext, hUnwrappingKey, &parentSlot)))
return result;
offset = 0;
memset(&key, 0, sizeof(TSS_KEY));
if ((result = UnloadBlob_TSS_KEY(&offset, rgbWrappedKeyBlob, &key)))
return result;
if (!pAuth) {
LogDebugFn("Checking if LoadKeyByBlob can be avoided by using existing key");
if ((newHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey))) {
LogDebugFn("tcs key handle exists");
newSlot = mc_get_slot_by_handle(newHandle);
if (newSlot && (isKeyLoaded(newSlot) == TRUE)) {
LogDebugFn("Don't need to reload this key.");
*phKeyTCSI = newHandle;
if (phKeyHMAC)
*phKeyHMAC = newSlot;
return TSS_SUCCESS;
}
}
}
LogDebugFn("calling canILoadThisKey");
if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad)))
goto error;
if (canLoad == FALSE) {
LogDebugFn("calling evictFirstKey");
/* Evict a key that isn't the parent */
if ((result = evictFirstKey(hUnwrappingKey)))
goto error;
}
offset = 0;
if ((result = tpm_rqu_build(ord, &offset, txBlob, parentSlot, cWrappedKeyBlobSize,
rgbWrappedKeyBlob, pAuth, NULL)))
goto error;
LogDebugFn("Submitting request to the TPM");
if ((result = req_mgr_submit_req(txBlob)))
goto error;
if ((result = UnloadBlob_Header(txBlob, ¶mSize))) {
LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
goto error;
}
if ((result = tpm_rsp_parse(ord, txBlob, paramSize, &newSlot, pAuth)))
goto error;
if ((result = load_key_final(hContext, hUnwrappingKey, &newHandle, rgbWrappedKeyBlob,
newSlot)))
goto error;
/* Setup the outHandles */
*phKeyTCSI = newHandle;
if (phKeyHMAC)
*phKeyHMAC = newSlot;
LogDebugFn("Key handles for loadKeyByBlob slot:%.8X tcshandle:%.8X", newSlot, newHandle);
error:
auth_mgr_release_auth(pAuth, NULL, hContext);
return result;
}
TSS_RESULT
TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hKey) /* in */
{
TSS_RESULT result;
TCPA_KEY_HANDLE tpm_handle;
if ((result = ctx_verify_context(hContext)))
return result;
tpm_handle = mc_get_slot_by_handle(hKey);
if (tpm_handle == NULL_TPM_HANDLE)
return TSS_SUCCESS; /*let's call this success if the key is already evicted */
if ((result = internal_EvictByKeySlot(tpm_handle)))
return result;
result = mc_set_slot_by_slot(tpm_handle, NULL_TPM_HANDLE);
return result;
}
TSS_RESULT
TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hWrappingKey, /* in */
TCPA_ENCAUTH KeyUsageAuth, /* in */
TCPA_ENCAUTH KeyMigrationAuth, /* in */
UINT32 keyInfoSize, /* in */
BYTE * keyInfo, /* in */
UINT32 * keyDataSize, /* out */
BYTE ** keyData, /* out */
TPM_AUTH * pAuth) /* in, out */
{
UINT64 offset = 0;
UINT32 paramSize;
TSS_RESULT result;
TCPA_KEY_HANDLE parentSlot;
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
LogDebug("Entering Create Wrap Key");
if ((result = ctx_verify_context(hContext)))
goto done;
if (pAuth) {
if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
goto done;
}
/* Since hWrappingKey must already be loaded, we can fail immediately if
* mc_get_slot_by_handle_lock() fails.*/
parentSlot = mc_get_slot_by_handle_lock(hWrappingKey);
if (parentSlot == NULL_TPM_HANDLE) {
result = TCSERR(TSS_E_FAIL);
goto done;
}
if ((result = tpm_rqu_build(TPM_ORD_CreateWrapKey, &offset, txBlob, parentSlot,
KeyUsageAuth.authdata, KeyMigrationAuth.authdata, keyInfoSize,
keyInfo, pAuth)))
goto done;
if ((result = req_mgr_submit_req(txBlob)))
goto done;
result = UnloadBlob_Header(txBlob, ¶mSize);
if (!result) {
result = tpm_rsp_parse(TPM_ORD_CreateWrapKey, txBlob, paramSize, keyDataSize,
keyData, pAuth);
}
LogResult("Create Wrap Key", result);
done:
auth_mgr_release_auth(pAuth, NULL, hContext);
return result;
}
TSS_RESULT
TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hKey, /* in */
TPM_AUTH * pAuth, /* in, out */
UINT32 * pcPubKeySize, /* out */
BYTE ** prgbPubKey) /* out */
{
UINT64 offset = 0;
UINT32 paramSize;
TSS_RESULT result;
TCPA_KEY_HANDLE keySlot;
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
LogDebug("Entering Get pub key");
if ((result = ctx_verify_context(hContext)))
goto done;
if (pAuth != NULL) {
LogDebug("Auth Used");
if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
goto done;
} else {
LogDebug("No Auth");
}
if (ensureKeyIsLoaded(hContext, hKey, &keySlot)) {
result = TCSERR(TCS_E_KM_LOADFAILED);
goto done;
}
LogDebug("GetPubKey: handle: 0x%x, slot: 0x%x", hKey, keySlot);
if ((result = tpm_rqu_build(TPM_ORD_GetPubKey, &offset, txBlob, keySlot, pAuth)))
goto done;
if ((result = req_mgr_submit_req(txBlob)))
goto done;
offset = 10;
result = UnloadBlob_Header(txBlob, ¶mSize);
if (!result) {
result = tpm_rsp_parse(TPM_ORD_GetPubKey, txBlob, paramSize, pcPubKeySize,
prgbPubKey, pAuth);
}
LogResult("Get Public Key", result);
done:
auth_mgr_release_auth(pAuth, NULL, hContext);
return result;
}
TSS_RESULT
TCSP_OwnerReadInternalPub_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hKey, /* in */
TPM_AUTH * pOwnerAuth, /* in, out */
UINT32 * punPubKeySize, /* out */
BYTE ** ppbPubKeyData) /* out */
{
UINT64 offset = 0;
UINT32 paramSize;
TSS_RESULT result;
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
LogDebug("Entering OwnerReadInternalPub");
if ((result = ctx_verify_context(hContext)))
goto done;
LogDebug("OwnerReadInternalPub: handle: 0x%x", hKey);
if (hKey != TPM_KH_SRK && hKey != TPM_KH_EK) {
result = TCSERR(TSS_E_FAIL);
LogDebug("OwnerReadInternalPub - Unsupported Key Handle");
goto done;
}
if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
goto done;
if ((result = tpm_rqu_build(TPM_ORD_OwnerReadInternalPub, &offset, txBlob, hKey,
pOwnerAuth)))
goto done;
if ((result = req_mgr_submit_req(txBlob)))
goto done;
result = UnloadBlob_Header(txBlob, ¶mSize);
if (!result) {
result = tpm_rsp_parse(TPM_ORD_OwnerReadInternalPub, txBlob, paramSize,
punPubKeySize, ppbPubKeyData, pOwnerAuth);
}
LogResult("OwnerReadInternalPub", result);
done:
auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
return result;
}
TSS_RESULT
TCSP_KeyControlOwner_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
TCS_KEY_HANDLE hTcsKey, /* in */
UINT32 ulPubKeyLength, /* in */
BYTE* rgbPubKey, /* in */
UINT32 attribName, /* in */
TSS_BOOL attribValue, /* in */
TPM_AUTH* pOwnerAuth, /* in,out */
TSS_UUID* pUuidData) /* out */
{
UINT64 offset = 0;
UINT32 paramSize;
TSS_RESULT result;
TPM_KEY_HANDLE hTpmKey;
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
LogDebugFn("Enter");
if ((result = ctx_verify_context(hContext))) {
LogDebug("Invalid TSS Context");
goto done;
}
if ((result = get_slot_lite(hContext, hTcsKey, &hTpmKey))) {
LogDebug("Can't get TPM Keyhandle for TCS key 0x%x", hTcsKey);
goto done;
}
LogDebugFn("TCS hKey=0x%x, TPM hKey=0x%x", hTcsKey, hTpmKey);
if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle))) {
LogDebug("Owner Authentication failed");
goto done;
}
if ((result = mc_find_next_ownerevict_uuid(pUuidData))) {
LogDebugFn("mc_find_next_ownerevict_uuid failed: rc=0x%x", result);
goto done;
}
if ((result = tpm_rqu_build(TPM_ORD_KeyControlOwner, &offset, txBlob, hTpmKey,
ulPubKeyLength, rgbPubKey, attribName, attribValue,
pOwnerAuth))) {
LogDebugFn("rqu build failed");
goto done;
}
if ((result = req_mgr_submit_req(txBlob))) {
LogDebugFn("Request submission failed");
goto done;
}
if ((result = UnloadBlob_Header(txBlob, ¶mSize))) {
LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
goto done;
}
if ((result = tpm_rsp_parse(TPM_ORD_KeyControlOwner, txBlob, paramSize, pOwnerAuth))) {
LogDebugFn("tpm_rsp_parse failed: rc=0x%x", result);
goto done;
}
if ((result = mc_set_uuid(hTcsKey, pUuidData))){
LogDebugFn("mc_set_uuid failed: rc=0x%x", result);
goto done;
}
LogResult("KeyControlOwner", result);
done:
auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
return result;
}