diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2021-02-26 14:02:46 -0800 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2021-02-26 14:46:29 -0800 |
commit | ab8e86884dc63063c8554c3ecace339522cf389a (patch) | |
tree | 61b4f139dd25544f88f40face0b10b73327b62f9 | |
parent | 30c6c83817862f2adc06161767ed510dbf65ae7a (diff) | |
download | openssl_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.c | 28 | ||||
-rw-r--r-- | e_tpm2.c | 5 | ||||
-rw-r--r-- | ibm-tss.h | 24 | ||||
-rw-r--r-- | load_tpm2_key.c | 2 | ||||
-rw-r--r-- | seal_tpm2_data.c | 20 | ||||
-rw-r--r-- | tpm2-common.c | 56 | ||||
-rw-r--r-- | tpm2-common.h | 3 |
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); @@ -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; } @@ -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, |