aboutsummaryrefslogtreecommitdiffstats
path: root/tpm2d/ibm-tss.h
diff options
context:
space:
mode:
Diffstat (limited to 'tpm2d/ibm-tss.h')
-rw-r--r--tpm2d/ibm-tss.h381
1 files changed, 381 insertions, 0 deletions
diff --git a/tpm2d/ibm-tss.h b/tpm2d/ibm-tss.h
new file mode 100644
index 000000000..2a4961359
--- /dev/null
+++ b/tpm2d/ibm-tss.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2021 James Bottomley <[email protected]>
+ *
+ * Supporting TPM routines for the IBM TSS
+ */
+#ifndef _TPM2_IBM_TSS_H
+#define _TPM2_IBM_TSS_H
+
+#define TSSINCLUDE(x) < TSS_INCLUDE/x >
+#include TSSINCLUDE(tss.h)
+#include TSSINCLUDE(tssutils.h)
+#include TSSINCLUDE(tssresponsecode.h)
+#include TSSINCLUDE(tssmarshal.h)
+#include TSSINCLUDE(Unmarshal_fp.h)
+#include TSSINCLUDE(tsscryptoh.h)
+
+#define EXT_TPM_RH_OWNER TPM_RH_OWNER
+
+#define VAL(X) X.val
+#define VAL_2B(X, MEMBER) X.t.MEMBER
+
+static const char *tpm2_dir;
+
+/* The TPM builds a small database of active files representing key
+ * parameters used for authentication and session encryption. Make sure
+ * they're contained in a separate directory to avoid stepping on any
+ * other application uses of the TPM */
+static inline const char *
+tpm2_set_unique_tssdir (void)
+{
+ char *prefix = getenv ("XDG_RUNTIME_DIR"), *template,
+ *dir;
+ int len = 0;
+
+ if (!prefix)
+ prefix = "/tmp";
+
+ len = snprintf (NULL, 0, "%s/tss2.XXXXXX", prefix);
+ if (len <= 0)
+ return NULL;
+ template = xtrymalloc (len + 1);
+ if (!template)
+ return NULL;
+
+ len++;
+ len = snprintf (template, len, "%s/tss2.XXXXXX", prefix);
+
+ dir = mkdtemp (template);
+
+ return dir;
+}
+
+static inline void
+tpm2_error (TPM_RC rc, const char *prefix)
+{
+ const char *msg, *submsg, *num;
+
+ TSS_ResponseCode_toString (&msg, &submsg, &num, rc);
+ log_error ("%s gave TPM2 Error: %s%s%s", prefix, msg, submsg, num);
+}
+
+static inline int
+TSS_start (TSS_CONTEXT **tssc)
+{
+ TPM_RC rc;
+
+ tpm2_dir = tpm2_set_unique_tssdir ();
+ if (!tpm2_dir)
+ /* make this non fatal */
+ log_error ("Failed to set unique TPM directory\n");
+
+ rc = TSS_Create (tssc);
+ if (rc)
+ {
+ tpm2_error (rc, "TSS_Create");
+ return GPG_ERR_CARD;
+ }
+ rc = TSS_SetProperty (*tssc, TPM_DATA_DIR, tpm2_dir);
+ if (rc)
+ /* make this non fatal */
+ tpm2_error (rc, "TSS_SetProperty");
+
+ return 0;
+}
+
+static inline TPM_RC
+tpm2_CreatePrimary (TSS_CONTEXT *tssContext, TPM_HANDLE primaryHandle,
+ TPM2B_SENSITIVE_CREATE *inSensitive,
+ TPM2B_PUBLIC *inPublic, TPM_HANDLE *objectHandle)
+{
+ CreatePrimary_In in;
+ CreatePrimary_Out out;
+ TPM_RC rc;
+
+ in.primaryHandle = primaryHandle;
+ in.inSensitive = *inSensitive;
+ in.inPublic = *inPublic;
+ /* no outside info */
+ in.outsideInfo.t.size = 0;
+ /* no PCR state */
+ in.creationPCR.count = 0;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_CreatePrimary,
+ TPM_RS_PW, NULL, 0,
+ TPM_RH_NULL, NULL, 0);
+
+ *objectHandle = out.objectHandle;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_FlushContext (TSS_CONTEXT *tssContext, TPM_HANDLE flushHandle)
+{
+ FlushContext_In in;
+ TPM_RC rc;
+
+ in.flushHandle = flushHandle;
+
+ rc = TSS_Execute (tssContext,
+ NULL,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_FlushContext,
+ TPM_RH_NULL, NULL, 0);
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_ReadPublic (TSS_CONTEXT *tssContext, TPM_HANDLE objectHandle,
+ TPMT_PUBLIC *pub, TPM_HANDLE auth)
+{
+ ReadPublic_In rin;
+ ReadPublic_Out rout;
+ TPM_RC rc;
+ UINT32 flags = 0;
+
+ if (auth != TPM_RH_NULL)
+ flags = TPMA_SESSION_ENCRYPT;
+
+ rin.objectHandle = objectHandle;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&rout,
+ (COMMAND_PARAMETERS *)&rin,
+ NULL,
+ TPM_CC_ReadPublic,
+ auth, NULL, flags,
+ TPM_RH_NULL, NULL, 0);
+
+ if (rc)
+ {
+ tpm2_error (rc, "TPM2_ReadPublic");
+ return rc;
+ }
+
+ if (pub)
+ *pub = rout.outPublic.publicArea;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_StartAuthSession (TSS_CONTEXT *tssContext, TPM_HANDLE tpmKey,
+ TPM_HANDLE bind, TPM_SE sessionType,
+ TPMT_SYM_DEF *symmetric, TPMI_ALG_HASH authHash,
+ TPM_HANDLE *sessionHandle,
+ const char *bindPassword)
+{
+ StartAuthSession_In in;
+ StartAuthSession_Out out;
+ StartAuthSession_Extra extra;
+ TPM_RC rc;
+
+ memset (&in, 0, sizeof(in));
+ memset (&extra, 0 , sizeof(extra));
+
+ extra.bindPassword = bindPassword;
+
+ in.tpmKey = tpmKey;
+ in.bind = bind;
+ in.sessionType = sessionType;
+ in.symmetric = *symmetric;
+ in.authHash = authHash;
+
+ if (tpmKey != TPM_RH_NULL)
+ {
+ /*
+ * For the TSS to use a key as salt, it must have
+ * access to the public part. It does this by keeping
+ * key files, but request the public part just to make
+ * sure
+ */
+ tpm2_ReadPublic (tssContext, tpmKey, NULL, TPM_RH_NULL);
+ /*
+ * don't care what rout returns, the purpose of the
+ * operation was to get the public key parameters into
+ * the tss so it can construct the salt
+ */
+ }
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ (EXTRA_PARAMETERS *)&extra,
+ TPM_CC_StartAuthSession,
+ TPM_RH_NULL, NULL, 0);
+
+ *sessionHandle = out.sessionHandle;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_Sign (TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle, DIGEST_2B *digest,
+ TPMT_SIG_SCHEME *inScheme, TPMT_SIGNATURE *signature,
+ TPM_HANDLE auth, const char *authVal)
+{
+ Sign_In in;
+ Sign_Out out;
+ TPM_RC rc;
+
+ in.keyHandle = keyHandle;
+ in.digest.t = *digest;
+ in.inScheme = *inScheme;
+ in.validation.tag = TPM_ST_HASHCHECK;
+ in.validation.hierarchy = TPM_RH_NULL;
+ in.validation.digest.t.size = 0;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_Sign,
+ auth, authVal, 0,
+ TPM_RH_NULL, NULL, 0);
+
+ *signature = out.signature;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_ECDH_ZGen (TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
+ TPM2B_ECC_POINT *inPoint, TPM2B_ECC_POINT *outPoint,
+ TPM_HANDLE auth, const char *authVal)
+{
+ ECDH_ZGen_In in;
+ ECDH_ZGen_Out out;
+ TPM_RC rc;
+
+ in.keyHandle = keyHandle;
+ in.inPoint = *inPoint;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_ECDH_ZGen,
+ auth, authVal, TPMA_SESSION_ENCRYPT,
+ TPM_RH_NULL, NULL, 0);
+
+ *outPoint = out.outPoint;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_RSA_Decrypt (TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
+ PUBLIC_KEY_RSA_2B *cipherText, TPMT_RSA_DECRYPT *inScheme,
+ PUBLIC_KEY_RSA_2B *message,
+ TPM_HANDLE auth, const char *authVal, int flags)
+{
+ RSA_Decrypt_In in;
+ RSA_Decrypt_Out out;
+ TPM_RC rc;
+
+ in.keyHandle = keyHandle;
+ in.inScheme = *inScheme;
+ in.cipherText.t = *cipherText;
+ in.label.t.size = 0;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_RSA_Decrypt,
+ auth, authVal, flags,
+ TPM_RH_NULL, NULL, 0);
+
+ *message = out.message.t;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_Load (TSS_CONTEXT *tssContext, TPM_HANDLE parentHandle,
+ PRIVATE_2B *inPrivate, TPM2B_PUBLIC *inPublic,
+ TPM_HANDLE *objectHandle,
+ TPM_HANDLE auth, const char *authVal)
+{
+ Load_In in;
+ Load_Out out;
+ TPM_RC rc;
+
+ in.parentHandle = parentHandle;
+ in.inPrivate.t = *inPrivate;
+ in.inPublic = *inPublic;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&out,
+ (COMMAND_PARAMETERS *)&in,
+ NULL,
+ TPM_CC_Load,
+ auth, authVal, 0,
+ TPM_RH_NULL, NULL, 0);
+
+ if (rc == TPM_RC_SUCCESS)
+ *objectHandle = out.objectHandle;
+
+ return rc;
+}
+
+static inline TPM_RC
+tpm2_Import (TSS_CONTEXT *tssContext, TPM_HANDLE parentHandle,
+ DATA_2B *encryptionKey, TPM2B_PUBLIC *objectPublic,
+ PRIVATE_2B *duplicate, ENCRYPTED_SECRET_2B *inSymSeed,
+ TPMT_SYM_DEF_OBJECT *symmetricAlg, PRIVATE_2B *outPrivate,
+ TPM_HANDLE auth, const char *authVal)
+{
+ Import_In iin;
+ Import_Out iout;
+ TPM_RC rc;
+
+ iin.parentHandle = parentHandle;
+ iin.encryptionKey.t = *encryptionKey;
+ iin.objectPublic = *objectPublic;
+ iin.duplicate.t = *duplicate;
+ iin.inSymSeed.t = *inSymSeed;
+ iin.symmetricAlg = *symmetricAlg;
+
+ rc = TSS_Execute (tssContext,
+ (RESPONSE_PARAMETERS *)&iout,
+ (COMMAND_PARAMETERS *)&iin,
+ NULL,
+ TPM_CC_Import,
+ auth, authVal, TPMA_SESSION_DECRYPT,
+ TPM_RH_NULL, NULL, 0);
+
+ *outPrivate = iout.outPrivate.t;
+
+ return rc;
+}
+
+static inline TPM_HANDLE
+tpm2_handle_int (TSS_CONTEXT *tssContext, TPM_HANDLE h)
+{
+ (void)tssContext;
+ return h;
+}
+
+static inline TPM_HANDLE
+tpm2_handle_ext (TSS_CONTEXT *tssContext, TPM_HANDLE h)
+{
+ (void)tssContext;
+ return h;
+}
+
+static inline int
+tpm2_handle_mso (TSS_CONTEXT *tssContext, TPM_HANDLE h, UINT32 mso)
+{
+ (void)tssContext;
+ return (h >> 24) == mso;
+}
+
+#endif