summaryrefslogtreecommitdiff
path: root/src/tcs/tcs_utils.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
commitc3649a2def02c41d837ae1f79dda729ccb91e677 (patch)
treebea46dff212fdef977fe9094a70a939e8cc21885 /src/tcs/tcs_utils.c
downloadtrousers-upstream/0.3.9.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tcs/tcs_utils.c')
-rw-r--r--src/tcs/tcs_utils.c537
1 files changed, 537 insertions, 0 deletions
diff --git a/src/tcs/tcs_utils.c b/src/tcs/tcs_utils.c
new file mode 100644
index 0000000..7e19d09
--- /dev/null
+++ b/src/tcs/tcs_utils.c
@@ -0,0 +1,537 @@
+
+/*
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "trousers_types.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcs_int_literals.h"
+#include "capabilities.h"
+#include "tcsps.h"
+#include "tcslog.h"
+
+
+TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
+TSS_UUID SRK_UUID = TSS_UUID_SRK;
+
+
+void
+LogData(char *string, UINT32 data)
+{
+#if 0
+ /* commenting out temporarily, logs getting too chatty */
+ LogDebug("%s %08x", string, data);
+#endif
+}
+
+void
+LogResult(char *string, TCPA_RESULT result)
+{
+#if 0
+ /* commenting out temporarily, logs getting too chatty */
+ LogDebug("Leaving %s with result 0x%08x", string, result);
+#endif
+}
+
+UINT16
+Decode_UINT16(BYTE * in)
+{
+ UINT16 temp = 0;
+ temp = (in[1] & 0xFF);
+ temp |= (in[0] << 8);
+ return temp;
+}
+
+void
+UINT64ToArray(UINT64 i, BYTE * out)
+{
+ out[0] = (BYTE) ((i >> 56) & 0xFF);
+ out[1] = (BYTE) ((i >> 48) & 0xFF);
+ out[2] = (BYTE) ((i >> 40) & 0xFF);
+ out[3] = (BYTE) ((i >> 32) & 0xFF);
+ out[4] = (BYTE) ((i >> 24) & 0xFF);
+ out[5] = (BYTE) ((i >> 16) & 0xFF);
+ out[6] = (BYTE) ((i >> 8) & 0xFF);
+ out[7] = (BYTE) (i & 0xFF);
+}
+
+void
+UINT32ToArray(UINT32 i, BYTE * out)
+{
+ out[0] = (BYTE) ((i >> 24) & 0xFF);
+ out[1] = (BYTE) ((i >> 16) & 0xFF);
+ out[2] = (BYTE) ((i >> 8) & 0xFF);
+ out[3] = (BYTE) (i & 0xFF);
+}
+
+void
+UINT16ToArray(UINT16 i, BYTE * out)
+{
+ out[0] = (BYTE) ((i >> 8) & 0xFF);
+ out[1] = (BYTE) (i & 0xFF);
+}
+
+UINT32
+Decode_UINT32(BYTE * y)
+{
+ UINT32 x = 0;
+
+ x = y[0];
+ x = ((x << 8) | (y[1] & 0xFF));
+ x = ((x << 8) | (y[2] & 0xFF));
+ x = ((x << 8) | (y[3] & 0xFF));
+
+ return x;
+}
+
+UINT64
+Decode_UINT64(BYTE *y)
+{
+ UINT64 x = 0;
+
+ x = y[0];
+ x = ((x << 8) | (y[1] & 0xFF));
+ x = ((x << 8) | (y[2] & 0xFF));
+ x = ((x << 8) | (y[3] & 0xFF));
+ x = ((x << 8) | (y[4] & 0xFF));
+ x = ((x << 8) | (y[5] & 0xFF));
+ x = ((x << 8) | (y[6] & 0xFF));
+ x = ((x << 8) | (y[7] & 0xFF));
+
+ return x;
+}
+
+void
+LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE * blob)
+{
+ if (blob)
+ UINT64ToArray(in, &blob[*offset]);
+ *offset += sizeof(UINT64);
+}
+
+void
+LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE * blob)
+{
+ if (blob)
+ UINT32ToArray(in, &blob[*offset]);
+ *offset += sizeof(UINT32);
+}
+
+void
+LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE * blob)
+{
+ if (blob)
+ UINT16ToArray(in, &blob[*offset]);
+ *offset += sizeof(UINT16);
+}
+
+void
+UnloadBlob_UINT64(UINT64 *offset, UINT64 * out, BYTE * blob)
+{
+ if (out)
+ *out = Decode_UINT64(&blob[*offset]);
+ *offset += sizeof(UINT64);
+}
+
+void
+UnloadBlob_UINT32(UINT64 *offset, UINT32 * out, BYTE * blob)
+{
+ if (out)
+ *out = Decode_UINT32(&blob[*offset]);
+ *offset += sizeof(UINT32);
+}
+
+void
+UnloadBlob_UINT16(UINT64 *offset, UINT16 * out, BYTE * blob)
+{
+ if (out)
+ *out = Decode_UINT16(&blob[*offset]);
+ *offset += sizeof(UINT16);
+}
+
+void
+LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE * blob)
+{
+ if (blob)
+ blob[*offset] = data;
+ (*offset)++;
+}
+
+void
+UnloadBlob_BYTE(UINT64 *offset, BYTE * dataOut, BYTE * blob)
+{
+ if (dataOut)
+ *dataOut = blob[*offset];
+ (*offset)++;
+}
+
+void
+LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE * blob)
+{
+ if (blob)
+ blob[*offset] = data;
+ (*offset)++;
+}
+
+void
+UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
+{
+ if (dataOut)
+ *dataOut = blob[*offset];
+ (*offset)++;
+}
+
+void
+LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
+{
+ if ((size == 0) || ((*offset + size) > TSS_TPM_TXBLOB_SIZE))
+ return;
+
+ if (container)
+ memcpy(&container[*offset], object, size);
+ (*offset) += (UINT64) size;
+}
+
+void
+UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
+{
+ if ((size == 0) || ((*offset + size) > TSS_TPM_TXBLOB_SIZE))
+ return;
+
+ if (object)
+ memcpy(object, &container[*offset], size);
+ (*offset) += (UINT64) size;
+}
+
+void
+LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal, BYTE * blob)
+{
+
+ UINT16ToArray(tag, &blob[0]);
+ LogData("Header Tag:", tag);
+ UINT32ToArray(paramSize, &blob[2]);
+ LogData("Header ParamSize:", paramSize);
+ UINT32ToArray(ordinal, &blob[6]);
+ LogData("Header Ordinal:", ordinal);
+#if 0
+ LogInfo("Blob's TPM Ordinal: 0x%x", ordinal);
+#endif
+}
+
+#ifdef TSS_DEBUG
+TSS_RESULT
+LogUnloadBlob_Header(BYTE * blob, UINT32 * size, char *file, int line)
+{
+ TSS_RESULT result;
+
+ UINT16 temp = Decode_UINT16(blob);
+ LogData("UnloadBlob_Tag:", (temp));
+ *size = Decode_UINT32(&blob[2]);
+ LogData("UnloadBlob_Header, size:", *size);
+ LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
+
+ if ((result = Decode_UINT32(&blob[6]))) {
+ LogTPMERR(result, file, line);
+ }
+
+ return result;
+}
+#else
+TSS_RESULT
+UnloadBlob_Header(BYTE * blob, UINT32 * size)
+{
+ UINT16 temp = Decode_UINT16(blob);
+ LogData("UnloadBlob_Tag:", (temp));
+ *size = Decode_UINT32(&blob[2]);
+ LogData("UnloadBlob_Header, size:", *size);
+ LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
+ return Decode_UINT32(&blob[6]);
+}
+#endif
+
+void
+LoadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
+{
+ LoadBlob_UINT32(offset, auth->AuthHandle, blob);
+ LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce);
+ LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob);
+ LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC);
+}
+
+void
+UnloadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
+{
+ if (!auth) {
+ UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
+ UnloadBlob_BOOL(offset, NULL, blob);
+ UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
+
+ return;
+ }
+
+ UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce);
+ UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob);
+ UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC);
+}
+
+void
+UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *out)
+{
+ if (!out) {
+ *offset += (sizeof(BYTE) * 4);
+ return;
+ }
+
+ UnloadBlob_BYTE(offset, &out->major, blob);
+ UnloadBlob_BYTE(offset, &out->minor, blob);
+ UnloadBlob_BYTE(offset, &out->revMajor, blob);
+ UnloadBlob_BYTE(offset, &out->revMinor, blob);
+}
+
+void
+LoadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *ver)
+{
+ LoadBlob_BYTE(offset, ver->major, blob);
+ LoadBlob_BYTE(offset, ver->minor, blob);
+ LoadBlob_BYTE(offset, ver->revMajor, blob);
+ LoadBlob_BYTE(offset, ver->revMinor, blob);
+}
+
+void
+UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
+{
+ if (!out) {
+ *offset += (sizeof(BYTE) * 4);
+ return;
+ }
+
+ UnloadBlob_BYTE(offset, &out->major, blob);
+ UnloadBlob_BYTE(offset, &out->minor, blob);
+ UnloadBlob_BYTE(offset, &out->revMajor, blob);
+ UnloadBlob_BYTE(offset, &out->revMinor, blob);
+}
+
+void
+LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *ver)
+{
+ LoadBlob_BYTE(offset, ver->major, blob);
+ LoadBlob_BYTE(offset, ver->minor, blob);
+ LoadBlob_BYTE(offset, ver->revMajor, blob);
+ LoadBlob_BYTE(offset, ver->revMinor, blob);
+}
+
+TSS_RESULT
+UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms)
+{
+ if (!keyParms) {
+ UINT32 parmSize;
+
+ UnloadBlob_UINT32(offset, NULL, blob);
+ UnloadBlob_UINT16(offset, NULL, blob);
+ UnloadBlob_UINT16(offset, NULL, blob);
+ UnloadBlob_UINT32(offset, &parmSize, blob);
+
+ if (parmSize > 0)
+ UnloadBlob(offset, parmSize, blob, NULL);
+
+ return TSS_SUCCESS;
+ }
+
+ UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob);
+ UnloadBlob_UINT16(offset, &keyParms->encScheme, blob);
+ UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob);
+ UnloadBlob_UINT32(offset, &keyParms->parmSize, blob);
+
+ if (keyParms->parmSize == 0)
+ keyParms->parms = NULL;
+ else {
+ keyParms->parms = malloc(keyParms->parmSize);
+ if (keyParms->parms == NULL) {
+ LogError("malloc of %u bytes failed.", keyParms->parmSize);
+ keyParms->parmSize = 0;
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+
+ UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms);
+ }
+
+ return TSS_SUCCESS;
+}
+
+void
+UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
+{
+ if (!flags) {
+ UnloadBlob_UINT32(offset, NULL, blob);
+
+ return;
+ }
+
+ UnloadBlob_UINT32(offset, flags, blob);
+}
+
+TSS_RESULT
+UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TCPA_CERTIFY_INFO *certify)
+{
+ TSS_RESULT rc;
+
+ if (!certify) {
+ TPM_VERSION version;
+ UINT32 size;
+
+ UnloadBlob_VERSION(offset, blob, &version);
+ UnloadBlob_UINT16(offset, NULL, blob);
+ UnloadBlob_KEY_FLAGS(offset, blob, NULL);
+ UnloadBlob_BOOL(offset, NULL, blob);
+
+ if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
+ return rc;
+
+ UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
+ UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
+ UnloadBlob_BOOL(offset, NULL, blob);
+ UnloadBlob_UINT32(offset, &size, blob);
+
+ if (size > 0)
+ UnloadBlob(offset, size, blob, NULL);
+
+ if (Decode_UINT16((BYTE *) &version) == TPM_TAG_CERTIFY_INFO2){
+ /* This is a TPM_CERTIFY_INFO2 structure. */
+ /* Read migrationAuthority. */
+ UnloadBlob_UINT32(offset, &size, blob);
+ if (size > 0)
+ UnloadBlob(offset, size, blob, NULL);
+ }
+
+ return TSS_SUCCESS;
+ }
+
+ UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&certify->version);
+ UnloadBlob_UINT16(offset, &certify->keyUsage, blob);
+ UnloadBlob_KEY_FLAGS(offset, blob, &certify->keyFlags);
+ UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob);
+
+ if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &certify->algorithmParms)))
+ return rc;
+
+ UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest);
+ UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce);
+ UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->parentPCRStatus, blob);
+ UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob);
+
+ if (certify->PCRInfoSize > 0) {
+ certify->PCRInfo = (BYTE *)malloc(certify->PCRInfoSize);
+ if (certify->PCRInfo == NULL) {
+ LogError("malloc of %u bytes failed.", certify->PCRInfoSize);
+ certify->PCRInfoSize = 0;
+ free(certify->algorithmParms.parms);
+ certify->algorithmParms.parms = NULL;
+ certify->algorithmParms.parmSize = 0;
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+ UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo);
+ } else {
+ certify->PCRInfo = NULL;
+ }
+
+ if (Decode_UINT16((BYTE *) &certify->version) == TPM_TAG_CERTIFY_INFO2){
+ /* This is a TPM_CERTIFY_INFO2 structure. */
+ /* Read migrationAuthority. */
+ UINT32 size;
+ UnloadBlob_UINT32(offset, &size, blob);
+ if (size > 0)
+ UnloadBlob(offset, size, blob, NULL);
+ }
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+UnloadBlob_KEY_HANDLE_LIST(UINT64 *offset, BYTE *blob, TCPA_KEY_HANDLE_LIST *list)
+{
+ UINT16 i;
+
+ if (!list) {
+ UINT16 size;
+
+ UnloadBlob_UINT16(offset, &size, blob);
+
+ *offset += (size * sizeof(UINT32));
+
+ return TSS_SUCCESS;
+ }
+
+ UnloadBlob_UINT16(offset, &list->loaded, blob);
+ if (list->loaded == 0) {
+ list->handle = NULL;
+ return TSS_SUCCESS;
+ }
+
+ list->handle = malloc(list->loaded * sizeof (UINT32));
+ if (list->handle == NULL) {
+ LogError("malloc of %zd bytes failed.", list->loaded * sizeof (UINT32));
+ list->loaded = 0;
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+
+ for (i = 0; i < list->loaded; i++)
+ UnloadBlob_UINT32(offset, &list->handle[i], blob);
+
+ return TSS_SUCCESS;
+}
+
+void
+LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
+{
+ LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
+}
+
+void
+UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
+{
+ UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
+}
+
+void
+LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
+{
+ LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
+}
+
+void
+UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
+{
+ UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
+}
+
+void
+LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
+{
+ LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
+}
+
+void
+UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
+{
+ UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
+}
+