summaryrefslogtreecommitdiff
path: root/src/tspi/tsp_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tspi/tsp_key.c')
-rw-r--r--src/tspi/tsp_key.c337
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
+