/* * Licensed Materials - Property of IBM * * trousers - An open source TCG Software Stack * * (C) Copyright International Business Machines Corp. 2004-2007 * */ #include #include #include "trousers/tss.h" #include "trousers/trousers.h" #include "trousers_types.h" #include "spi_utils.h" #include "capabilities.h" #include "tsplog.h" #include "obj.h" void free_key_refs(TSS_KEY *key) { free(key->algorithmParms.parms); key->algorithmParms.parms = NULL; key->algorithmParms.parmSize = 0; free(key->pubKey.key); key->pubKey.key = NULL; key->pubKey.keyLength = 0; free(key->encData); key->encData = NULL; key->encSize = 0; free(key->PCRInfo); key->PCRInfo = NULL; key->PCRInfoSize = 0; } void LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) { if (key->hdr.key12.tag == TPM_TAG_KEY12) Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); else Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key); } TSS_RESULT UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) { UINT16 tag; UINT64 keyOffset = *offset; TSS_RESULT result; Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob); if (tag == TPM_TAG_KEY12) result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); else result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key); return result; } TSS_RESULT Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key) { TSS_RESULT result; if (key->hdr.key12.tag == TPM_TAG_KEY12) result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key); else result = Trspi_Hash_KEY(c, (TCPA_KEY *)key); return result; } void LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key) { if (key->hdr.key12.tag == TPM_TAG_KEY12) Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key); else Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key); } TSS_RESULT Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key) { TSS_RESULT result; if (key->hdr.key12.tag == TPM_TAG_KEY12) result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key); else result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key); return result; } #ifdef TSS_BUILD_TRANSPORT TSS_RESULT Transport_EvictKey(TSS_HCONTEXT tspContext, TCS_KEY_HANDLE hKey) { TSS_RESULT result; UINT32 handlesLen; TCS_HANDLE *handles, handle; TPM_DIGEST pubKeyHash; Trspi_HashCtx hashCtx; if ((result = obj_context_transport_init(tspContext))) return result; LogDebugFn("Executing in a transport session"); if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) return result; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) return result; handlesLen = 1; handle = hKey; handles = &handle; result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash, &handlesLen, &handles, NULL, NULL, NULL, NULL); return result; } TSS_RESULT Transport_GetPubKey(TSS_HCONTEXT tspContext, TCS_KEY_HANDLE hKey, TPM_AUTH *pAuth, UINT32 *pcPubKeySize, BYTE **prgbPubKey) { TSS_RESULT result; UINT32 handlesLen, decLen; TCS_HANDLE *handles, handle; BYTE *dec = NULL; TPM_DIGEST pubKeyHash; Trspi_HashCtx hashCtx; if ((result = obj_context_transport_init(tspContext))) return result; LogDebugFn("Executing in a transport session"); if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) return result; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) return result; handlesLen = 1; handle = hKey; handles = &handle; if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL, &pubKeyHash, &handlesLen, &handles, pAuth, NULL, &decLen, &dec))) return result; *prgbPubKey = dec; *pcPubKeySize = decLen; return result; } TSS_RESULT Transport_CreateWrapKey(TSS_HCONTEXT tspContext, /* in */ TCS_KEY_HANDLE hWrappingKey, /* in */ TPM_ENCAUTH *KeyUsageAuth, /* in */ TPM_ENCAUTH *KeyMigrationAuth, /* in */ UINT32 keyInfoSize, /* in */ BYTE * keyInfo, /* in */ UINT32 * keyDataSize, /* out */ BYTE ** keyData, /* out */ TPM_AUTH * pAuth) /* in, out */ { TSS_RESULT result; UINT32 handlesLen, decLen; TCS_HANDLE *handles, handle; BYTE *dec = NULL; TPM_DIGEST pubKeyHash; Trspi_HashCtx hashCtx; UINT64 offset; BYTE *data; if ((result = obj_context_transport_init(tspContext))) return result; LogDebugFn("Executing in a transport session"); if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest))) return result; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) return result; handlesLen = 1; handle = hWrappingKey; handles = &handle; if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) { LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize); return TSPERR(TSS_E_OUTOFMEMORY); } offset = 0; Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata); Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata); Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo); if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey, (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data, &pubKeyHash, &handlesLen, &handles, pAuth, NULL, &decLen, &dec))) goto done; *keyDataSize = decLen; *keyData = dec; done: free(data); return result; } TSS_RESULT Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext, TCS_KEY_HANDLE hParentKey, UINT32 ulBlobLength, BYTE* rgbBlobData, TPM_AUTH* pAuth, TCS_KEY_HANDLE* phKey, TPM_KEY_HANDLE* phSlot) { TSS_RESULT result; UINT32 handlesLen, decLen; TCS_HANDLE *handles, handle; BYTE *dec = NULL; TPM_DIGEST pubKeyHash; Trspi_HashCtx hashCtx; if ((result = obj_context_transport_init(tspContext))) return result; LogDebugFn("Executing in a transport session"); if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest))) return result; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) return result; handlesLen = 1; handle = hParentKey; handles = &handle; if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength, rgbBlobData, &pubKeyHash, &handlesLen, &handles, pAuth, NULL, &decLen, &dec))) return result; if (handlesLen == 1) *phKey = *(TCS_KEY_HANDLE *)handles; else result = TSPERR(TSS_E_INTERNAL_ERROR); free(dec); return result; } /* This function both encrypts the handle of the pubkey being requested and requires the hash * of that pubkey for the transport log when logging is enabled. */ TSS_RESULT Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext, /* in */ TCS_KEY_HANDLE hKey, /* in */ TPM_AUTH* pOwnerAuth, /* in, out */ UINT32* punPubKeySize, /* out */ BYTE** ppbPubKeyData) /* out */ { UINT64 offset; TSS_RESULT result; UINT32 handlesLen = 0, decLen; TPM_DIGEST pubKeyHash; Trspi_HashCtx hashCtx; BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)]; if ((result = obj_context_transport_init(tspContext))) return result; LogDebugFn("Executing in a transport session"); if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) return result; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) return result; offset = 0; Trspi_LoadBlob_UINT32(&offset, hKey, data); if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub, sizeof(data), data, &pubKeyHash, &handlesLen, NULL, pOwnerAuth, NULL, &decLen, &dec))) return result; *punPubKeySize = decLen; *ppbPubKeyData = dec; return result; } #endif