aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2021-02-26 14:02:46 -0800
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2021-02-26 14:46:29 -0800
commitab8e86884dc63063c8554c3ecace339522cf389a (patch)
tree61b4f139dd25544f88f40face0b10b73327b62f9
parent30c6c83817862f2adc06161767ed510dbf65ae7a (diff)
downloadopenssl_tpm2_engine-ab8e86884dc63063c8554c3ecace339522cf389a.tar.gz
Work around Intel TSS Premature Abstraction
Apparently no-one at the TCG read the memo on pointless abstractions, so they have an internal and an external representation for the TPM handles. The really annoying thing is that the two are represented by the same type in the Intel TSS, so there's no way for the compiler to check if you've kept everything straight. The other significant problem is that the internal representation is only valid for as long as the context lives, so everything that has a longer lifetime than the context must be in the external representation. Finally, just to trip you up, a small number of commands use the external representation in the API but no-one will tell you which ones. Fix this by introducing APIs for transforming handles from internal to external and back, which are nops on the IBM TSS and add a host of transforms to the code. Proof that this is correct is simply that the Intel TSS works. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--create_tpm2_key.c28
-rw-r--r--e_tpm2.c5
-rw-r--r--ibm-tss.h24
-rw-r--r--load_tpm2_key.c2
-rw-r--r--seal_tpm2_data.c20
-rw-r--r--tpm2-common.c56
-rw-r--r--tpm2-common.h3
7 files changed, 96 insertions, 42 deletions
diff --git a/create_tpm2_key.c b/create_tpm2_key.c
index 4d6b07e..69cc516 100644
--- a/create_tpm2_key.c
+++ b/create_tpm2_key.c
@@ -816,6 +816,7 @@ int main(int argc, char **argv)
TPMT_HA digest;
ENCRYPTED_SECRET_2B secret, *enc_secret = NULL;
int restricted = 0;
+ char *parent_str = NULL;
OpenSSL_add_all_digests();
/* may be needed to decrypt the key */
@@ -854,11 +855,7 @@ int main(int argc, char **argv)
}
break;
case 'p':
- parent = tpm2_get_parent(optarg);
- if (parent == 0) {
- fprintf(stderr, "Invalid parent %s\n", optarg);
- exit(1);
- }
+ parent_str = optarg;
break;
case 's':
key_size = atoi(optarg);
@@ -985,6 +982,16 @@ int main(int argc, char **argv)
EVP_PKEY *pkey = openssl_read_key(wrap);
TPMT_SENSITIVE s;
+ if (parent_str) {
+ parent = tpm2_get_parent_ext(parent_str);
+ if (parent == 0) {
+ reason = "Invalid parent";
+ goto out_err;
+ }
+ } else {
+ parent = EXT_TPM_RH_OWNER;
+ }
+
/* steal existing private and public areas */
pub = &objectPublic;
priv = &outPrivate;
@@ -1052,7 +1059,15 @@ int main(int argc, char **argv)
goto out_free_auth;
}
- if ((parent & 0xff000000) == 0x40000000) {
+ if (parent_str) {
+ parent = tpm2_get_parent(tssContext, parent_str);
+ if (parent == 0) {
+ reason = "Invalid parent";
+ goto out_delete;
+ }
+ }
+
+ if (tpm2_handle_mso(tssContext, parent, TPM_HT_PERMANENT)) {
rc = tpm2_load_srk(tssContext, &phandle, parent_auth, NULL, parent, version);
if (rc) {
reason = "tpm2_load_srk";
@@ -1214,6 +1229,7 @@ int main(int argc, char **argv)
priv = &outPrivate;
}
tpm2_flush_srk(tssContext, phandle);
+ parent = tpm2_handle_ext(tssContext, parent);
TSS_Delete(tssContext);
tpm2_rm_keyfile(dir, phandle);
tpm2_rm_tssdir(dir);
diff --git a/e_tpm2.c b/e_tpm2.c
index d245dc9..56a0dc7 100644
--- a/e_tpm2.c
+++ b/e_tpm2.c
@@ -133,6 +133,7 @@ static int tpm2_engine_load_nvkey(ENGINE *e, EVP_PKEY **ppkey,
rc = tpm2_create(&tssContext, app_data->dir);
if (rc)
goto err;
+ key = tpm2_handle_int(tssContext, key);
rc = tpm2_readpublic(tssContext, key, &p);
if (rc)
goto err_del;
@@ -145,7 +146,7 @@ static int tpm2_engine_load_nvkey(ENGINE *e, EVP_PKEY **ppkey,
tpm2_delete(app_data);
goto out;
}
- app_data->key = key;
+ app_data->key = tpm2_handle_ext(tssContext, key);
if (VAL(p.objectAttributes) & TPMA_OBJECT_NODA) {
/* no DA implications, try an authorization and see
@@ -202,7 +203,7 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
TPM_HANDLE key;
key = strtoul(key_id + nvkey_len, NULL, 16);
- if ((key & 0xff000000) != 0x81000000) {
+ if ((key >> 24) != TPM_HT_PERSISTENT) {
fprintf(stderr, "nvkey is not an NV index\n");
return 0;
}
diff --git a/ibm-tss.h b/ibm-tss.h
index 0bc2971..d40eb46 100644
--- a/ibm-tss.h
+++ b/ibm-tss.h
@@ -7,6 +7,12 @@
#include TSSINCLUDE(tsscrypto.h)
#include TSSINCLUDE(tsscryptoh.h)
+#define EXT_TPM_RH_OWNER TPM_RH_OWNER
+#define EXT_TPM_RH_PLATFORM TPM_RH_PLATFORM
+#define EXT_TPM_RH_ENDORSEMENT TPM_RH_ENDORSEMENT
+#define EXT_TPM_RH_NULL TPM_RH_NULL
+#define INT_TPM_RH_NULL TPM_RH_NULL
+
#define VAL(X) X.val
#define VAL_2B(X, MEMBER) X.b.MEMBER
#define VAL_2B_P(X, MEMBER) X->b.MEMBER
@@ -480,3 +486,21 @@ tpm2_PolicyCounterTimer(TSS_CONTEXT *tssContext, TPM_HANDLE policySession,
return rc;
}
+
+static inline TPM_HANDLE
+tpm2_handle_int(TSS_CONTEXT *tssContext, TPM_HANDLE h)
+{
+ return h;
+}
+
+static inline TPM_HANDLE
+tpm2_handle_ext(TSS_CONTEXT *tssContext, TPM_HANDLE h)
+{
+ return h;
+}
+
+static inline int
+tpm2_handle_mso(TSS_CONTEXT *tssContext, TPM_HANDLE h, UINT32 mso)
+{
+ return (h >> 24) == mso;
+}
diff --git a/load_tpm2_key.c b/load_tpm2_key.c
index 65148e6..5fe9e8f 100644
--- a/load_tpm2_key.c
+++ b/load_tpm2_key.c
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
usage(argv[0]);
}
- if ((nvindex & 0xff000000) != 0x81000000) {
+ if ((nvindex >> 24) != TPM_HT_PERSISTENT) {
printf("nvindex must have MSO 81\n");
exit(1);
}
diff --git a/seal_tpm2_data.c b/seal_tpm2_data.c
index c18fbcd..9017c12 100644
--- a/seal_tpm2_data.c
+++ b/seal_tpm2_data.c
@@ -105,6 +105,7 @@ int main(int argc, char **argv)
BYTE *buffer;
int32_t size;
uint16_t pubkey_len, privkey_len;
+ char *parent_str = NULL;
while (1) {
option_index = 0;
@@ -146,12 +147,8 @@ int main(int argc, char **argv)
}
break;
case 'p':
- parent = tpm2_get_parent(optarg);
- if (parent == 0) {
- fprintf(stderr, "Invalid parent %s\n", optarg);
- exit(1);
- }
- break;
+ parent_str = optarg;
+ break;
case 'v':
fprintf(stdout, "%s " VERSION "\n"
"Copyright 2017 by James Bottomley\n"
@@ -227,7 +224,15 @@ int main(int argc, char **argv)
goto out_rmdir;
}
- if ((parent & 0xff000000) == 0x40000000) {
+ if (parent_str) {
+ parent = tpm2_get_parent(tssContext, parent_str);
+ if (parent == 0) {
+ reason = "Invalid parent";
+ goto out_delete;
+ }
+ }
+
+ if (tpm2_handle_mso(tssContext, parent, TPM_HT_PERMANENT)) {
rc = tpm2_load_srk(tssContext, &phandle, parent_auth,
NULL, parent, 1);
if (rc) {
@@ -298,6 +303,7 @@ int main(int argc, char **argv)
size = sizeof(privkey);
TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)&outPrivate, &privkey_len,
&buffer, &size);
+ parent = tpm2_handle_ext(tssContext, parent);
tpm2_write_tpmfile(filename, pubkey, pubkey_len,
privkey, privkey_len, data_auth == NULL,
parent, sk, 2, NULL);
diff --git a/tpm2-common.c b/tpm2-common.c
index c420dd5..90b758f 100644
--- a/tpm2-common.c
+++ b/tpm2-common.c
@@ -609,7 +609,7 @@ TPM_RC tpm2_load_srk(TSS_CONTEXT *tssContext, TPM_HANDLE *h, const char *auth,
void tpm2_flush_srk(TSS_CONTEXT *tssContext, TPM_HANDLE hSRK)
{
/* only flush if it's a volatile key which we must have created */
- if ((hSRK & 0xFF000000) == 0x80000000)
+ if (tpm2_handle_mso(tssContext, hSRK, TPM_HT_TRANSIENT))
tpm2_flush_handle(tssContext, hSRK);
}
@@ -1380,7 +1380,7 @@ int tpm2_load_engine_file(const char *filename, struct app_data **app_data,
ad->parent = ASN1_INTEGER_get(parent);
else
/* older keys have absent parent */
- ad->parent = TPM_RH_OWNER;
+ ad->parent = EXT_TPM_RH_OWNER;
ad->pub = OPENSSL_malloc(pubkey->length);
if (!ad->pub)
@@ -1428,12 +1428,12 @@ int tpm2_load_engine_file(const char *filename, struct app_data **app_data,
goto import_err;
}
- if ((ad->parent & 0xff000000) == 0x40000000) {
+ parentHandle = tpm2_handle_int(tssContext, ad->parent);
+ if (tpm2_handle_mso(tssContext, parentHandle, TPM_HT_PERMANENT)) {
tpm2_load_srk(tssContext, &parentHandle,
- srk_auth, NULL, ad->parent, 1);
- } else {
- parentHandle = ad->parent;
+ srk_auth, NULL, parentHandle, 1);
}
+
rc = tpm2_get_session_handle(tssContext, &session,
parentHandle,
TPM_SE_HMAC,
@@ -1562,7 +1562,7 @@ TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
return 0;
if (app_data->key) {
- key = app_data->key;
+ key = tpm2_handle_int(tssContext, app_data->key);
goto out;
}
@@ -1574,11 +1574,10 @@ TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
size = app_data->pub_len;
TPM2B_PUBLIC_Unmarshal(&inPublic, &buffer, &size, FALSE);
- if ((app_data->parent & 0xff000000) == 0x81000000) {
- parentHandle = app_data->parent;
- } else {
+ parentHandle = tpm2_handle_int(tssContext, app_data->parent);
+ if (tpm2_handle_mso(tssContext, parentHandle, TPM_HT_PERMANENT)) {
rc = tpm2_load_srk(tssContext, &parentHandle, srk_auth, NULL,
- app_data->parent, app_data->type);
+ parentHandle, app_data->type);
if (rc)
goto out;
}
@@ -1615,31 +1614,38 @@ void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key)
TSS_Delete(tssContext);
}
-TPM_HANDLE tpm2_get_parent(const char *pstr)
+TPM_HANDLE tpm2_get_parent_ext(const char *pstr)
{
TPM_HANDLE p;
if (strcmp(pstr, "owner") == 0)
- p = TPM_RH_OWNER;
+ p = EXT_TPM_RH_OWNER;
else if (strcmp(pstr, "platform") == 0)
- p = TPM_RH_PLATFORM;
+ p = EXT_TPM_RH_PLATFORM;
else if (strcmp(pstr, "endorsement") == 0)
- p = TPM_RH_ENDORSEMENT;
+ p = EXT_TPM_RH_ENDORSEMENT;
else if (strcmp(pstr, "null") == 0)
- p = TPM_RH_NULL;
- else
+ p = EXT_TPM_RH_NULL;
+ else {
p = strtoul(pstr, NULL, 16);
+ if ((p >> 24) != TPM_HT_PERSISTENT)
+ p = 0;
+ }
- if (((p & 0xff000000) == 0x40000000) &&
- (p == TPM_RH_OWNER ||
- p == TPM_RH_PLATFORM ||
- p == TPM_RH_ENDORSEMENT ||
- p == TPM_RH_NULL))
- return p;
- else if ((p & 0xff000000) == 0x81000000)
+ return p;
+}
+
+TPM_HANDLE tpm2_get_parent(TSS_CONTEXT *tssContext, const char *pstr)
+{
+ TPM_HANDLE p;
+
+ p = tpm2_get_parent_ext(pstr);
+ if (p == 0)
return p;
- return 0;
+ p = tpm2_handle_int(tssContext, p);
+
+ return p;
}
int tpm2_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
diff --git a/tpm2-common.h b/tpm2-common.h
index dfd940f..2d6c561 100644
--- a/tpm2-common.h
+++ b/tpm2-common.h
@@ -78,7 +78,8 @@ TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key);
void tpm2_delete(struct app_data *app_data);
char *tpm2_get_auth(UI_METHOD *ui, char *input_string, void *cb_data);
-TPM_HANDLE tpm2_get_parent(const char *pstr);
+TPM_HANDLE tpm2_get_parent_ext(const char *pstr);
+TPM_HANDLE tpm2_get_parent(TSS_CONTEXT *tssContext, const char *pstr);
int tpm2_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
BYTE *privkey, int privkey_len, int empty_auth,
TPM_HANDLE parent, STACK_OF(TSSOPTPOLICY) *sk,