diff options
Diffstat (limited to 'src/tspi/tsp_key.c')
-rw-r--r-- | src/tspi/tsp_key.c | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/tspi/tsp_key.c b/src/tspi/tsp_key.c new file mode 100644 index 0000000..d882527 --- /dev/null +++ b/src/tspi/tsp_key.c @@ -0,0 +1,337 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#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 + |