diff --git a/Makefile-integration.am b/Makefile-integration.am index 06334987..e2255de6 100644 --- a/Makefile-integration.am +++ b/Makefile-integration.am @@ -10,8 +10,7 @@ integration_scripts = \ test/integration/pkcs11-javarunner.sh.java \ test/integration/nss-tests.sh \ test/integration/ptool-link.sh.nosetup \ - test/integration/python-pkcs11.sh \ - test/integration/key_import-link.sh.nosetup + test/integration/python-pkcs11.sh # Note that -fapi.sh.fapi is symlinked to .sh.nosetup # If we'd use the .fapi extension then .nosetup and .fapi overwrite each others .log @@ -19,8 +18,7 @@ integration_scripts = \ if HAVE_FAPI integration_scripts += \ test/integration/p11-tool-fapi.sh.fapi \ - test/integration/pkcs11-tool-init-fapi.sh.fapi \ - test/integration/key_import-link-fapi.sh.fapi + test/integration/pkcs11-tool-init-fapi.sh.fapi endif EXTRA_DIST += \ diff --git a/Makefile.am b/Makefile.am index 401a054f..505b90a1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,16 +78,6 @@ endif AM_DISTCHECK_CONFIGURE_FLAGS = --with-p11kitconfigdir='$$(datarootdir)/p11kitconfigdir' --with-p11kitmoduledir='$$(libdir)' -# The key_import tool -bin_PROGRAMS = tools/key_import/key_import -if ENABLE_ASAN - tools_key_import_key_import_LDFLAGS = $(AM_LDFLAGS) -shared-libasan -else - tools_key_import_key_import_LDFLAGS = $(AM_LDFLAGS) -endif -tools_key_import_key_import_LDADD = $(libtpm2_pkcs11) -tools_key_import_key_import_SOURCES = tools/key_import/import.c - # # Due to limitations in how cmocka works, we build a separate library here so we # can have a PKCS11 shared object with undefined calls into the rest of the lib @@ -129,8 +119,8 @@ AM_TESTS_ENVIRONMENT = \ PYTHON_INTERPRETER=@PYTHON_INTERPRETER@ \ TEST_FUNC_LIB=$(srcdir)/test/integration/scripts/int-test-funcs.sh \ TEST_FIXTURES=$(abs_top_srcdir)/test/integration/fixtures \ - PATH=$(abs_top_srcdir)/tools/tpm2_ptool:$(abs_builddir)/tools/key_import:./src:$(PATH) \ - PYTHONPATH=$(abs_top_srcdir)/tools/tpm2_ptool:$(PYTHONPATH) \ + PATH=$(abs_top_srcdir)/tools:./src:$(PATH) \ + PYTHONPATH=$(abs_top_srcdir)/tools:$(PYTHONPATH) \ TPM2_PKCS11_MODULE=$(abs_builddir)/src/.libs/libtpm2_pkcs11.so \ TEST_JAVA_ROOT=$(JAVAROOT) \ PACKAGE_URL=$(PACKAGE_URL) \ diff --git a/docs/KEY_IMPORT_TOOL.md b/docs/KEY_IMPORT_TOOL.md deleted file mode 100644 index 601e4913..00000000 --- a/docs/KEY_IMPORT_TOOL.md +++ /dev/null @@ -1,14 +0,0 @@ -# The key_import Tool - -The `key_import` tool in this project is a C program that serves as an example for importing TPM keys into a tpm2-pkcs11 token. The key import mechanism uses PKCS #11 vendor-specific attributes and works with both FAPI and ESYSDB backends. - -Supported modes: -- Key to be imported: Ordinary TPM key with or without an auth value. -- Key Import Formats: Keys can be imported as persistent handle or TSS key objects obtained from `tpm2 create` (`TPM2B_PUBLIC` and `TPM2B_PRIVATE` blobs). - - If key objects are used, the associated parent key must be the same primary key used for token initialization. Parent keys with or without an auth value are supported. - -The PKCS #11 vendor-specific attributes used during the key import procedure are: -- Persistent Handle: `CKA_TPM2_PERSISTENT_HANDLE` and `CKA_TPM2_OBJAUTH`. -- TSS Key Objects: `CKA_TPM2_PUB_BLOB`, `CKA_TPM2_PRIV_BLOB`, and `CKA_TPM2_OBJAUTH`. - -For more details, please refer to `test/integration/key_import-link.sh.nosetup`. diff --git a/src/lib/attrs.c b/src/lib/attrs.c index 585a50d0..0c81e6a4 100644 --- a/src/lib/attrs.c +++ b/src/lib/attrs.c @@ -167,12 +167,10 @@ static attr_handler2 attr_handlers[] = { ADD_ATTR_HANDLER(CKA_WRAP_TEMPLATE, TYPE_BYTE_TEMP_SEQ), ADD_ATTR_HANDLER(CKA_UNWRAP_TEMPLATE, TYPE_BYTE_TEMP_SEQ), ADD_ATTR_HANDLER(CKA_ALLOWED_MECHANISMS, TYPE_BYTE_INT_SEQ), - ADD_ATTR_HANDLER(CKA_TPM2_OBJAUTH, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_OBJAUTH_ENC, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_PUB_BLOB, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_PRIV_BLOB, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_ENC_BLOB, TYPE_BYTE_HEX_STR), - ADD_ATTR_HANDLER(CKA_TPM2_PERSISTENT_HANDLE, TYPE_BYTE_INT), }; static attr_handler2 default_handler = { .memtype = 0, .name="UNKNOWN" }; diff --git a/src/lib/attrs.h b/src/lib/attrs.h index e28d1754..c0c542c5 100644 --- a/src/lib/attrs.h +++ b/src/lib/attrs.h @@ -10,13 +10,11 @@ /* * We will allow these to be accessed, but the values are not stable */ -#define CKA_VENDOR_TPM2_DEFINED 0x0F000000UL -#define CKA_TPM2_OBJAUTH_ENC (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x1UL) -#define CKA_TPM2_PUB_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x2UL) -#define CKA_TPM2_PRIV_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x3UL) -#define CKA_TPM2_ENC_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x4UL) -#define CKA_TPM2_OBJAUTH (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x5UL) -#define CKA_TPM2_PERSISTENT_HANDLE (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x6UL) +#define CKA_VENDOR_TPM2_DEFINED 0x0F000000UL +#define CKA_TPM2_OBJAUTH_ENC (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x1UL) +#define CKA_TPM2_PUB_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x2UL) +#define CKA_TPM2_PRIV_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x3UL) +#define CKA_TPM2_ENC_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x4UL) /* Invalid values for error detection */ #define CK_OBJECT_CLASS_BAD (~(CK_OBJECT_CLASS)0) diff --git a/src/lib/key.c b/src/lib/key.c index 7cdfccd4..552b0e70 100644 --- a/src/lib/key.c +++ b/src/lib/key.c @@ -13,12 +13,6 @@ #include "session_ctx.h" #include "utils.h" -enum keygen_mode { - keygen_mode_normal, - keygen_mode_kobjs, - keygen_mode_phandle -}; - typedef struct sanity_check_data sanity_check_data; struct sanity_check_data { bool is_extractable; @@ -143,36 +137,6 @@ static CK_RV check_specific_attrs(CK_MECHANISM_TYPE mech, } } -static CK_RV check_tpm_vendor_attrs( - attr_list *pubkey_templ_w_types, attr_list *privkey_templ_w_types, - enum keygen_mode *keygen_mode) { - - /* From pPublicKeyTemplate */ - CK_ATTRIBUTE_PTR a_pub_blob = attr_get_attribute_by_type(pubkey_templ_w_types, CKA_TPM2_PUB_BLOB); - CK_ATTRIBUTE_PTR a_pub_handle = attr_get_attribute_by_type(pubkey_templ_w_types, CKA_TPM2_PERSISTENT_HANDLE); - - /* From pPrivateKeyTemplate */ - CK_ATTRIBUTE_PTR a_priv_auth = attr_get_attribute_by_type(privkey_templ_w_types, CKA_TPM2_OBJAUTH); - CK_ATTRIBUTE_PTR a_priv_blob = attr_get_attribute_by_type(privkey_templ_w_types, CKA_TPM2_PRIV_BLOB); - CK_ATTRIBUTE_PTR a_priv_handle = attr_get_attribute_by_type(privkey_templ_w_types, CKA_TPM2_PERSISTENT_HANDLE); - - if (a_pub_handle && a_priv_handle && !(a_pub_blob || a_priv_blob)) { - /* Persistent key found */ - *keygen_mode = keygen_mode_phandle; - } else if (a_pub_blob && a_priv_blob && !(a_pub_handle || a_priv_handle)) { - /* TPM key objects found */ - *keygen_mode = keygen_mode_kobjs; - } else if (!(a_pub_blob || a_pub_handle || a_priv_auth || a_priv_blob || a_priv_handle)) { - *keygen_mode = keygen_mode_normal; - } else { - /* Invalid combination */ - LOGE("Key import request detected, but the attribute combination is invalid or missing"); - return CKR_ATTRIBUTE_TYPE_INVALID; - } - - return CKR_OK; -} - CK_RV key_gen ( session_ctx *ctx, @@ -189,14 +153,9 @@ CK_RV key_gen ( CK_RV rv = CKR_GENERAL_ERROR; - enum keygen_mode keygen_mode = keygen_mode_normal; - twist newauthhex = NULL; twist newwrapped_auth = NULL; - twist pub_blob = NULL; - twist priv_blob = NULL; - attr_list *pubkey_templ_w_types = NULL; attr_list *privkey_templ_w_types = NULL; @@ -205,12 +164,6 @@ CK_RV key_gen ( tpm_object_data objdata = { 0 }; - CK_ATTRIBUTE_PTR attr_ptr = NULL; - - uint32_t priv_esys_tr = 0, pub_esys_tr = 0; - CK_ULONG priv_persistent_handle = 0; - CK_ULONG pub_persistent_handle = 0; - token *tok = session_ctx_get_token(ctx); assert(tok); @@ -270,166 +223,42 @@ CK_RV key_gen ( goto out; } - /* Initialize the objects attributes */ - new_public_tobj->attrs = pubkey_templ_w_types; - new_private_tobj->attrs = privkey_templ_w_types; - - /* make it clear that tobj now owns these */ - pubkey_templ_w_types = privkey_templ_w_types = NULL; - - /* Check if the import of an existing TPM key (persistent handle or key objects) is requested */ - rv = check_tpm_vendor_attrs( - new_public_tobj->attrs, new_private_tobj->attrs, - &keygen_mode); - if (rv) { + rv = utils_new_random_object_auth(&newauthhex); + if (rv != CKR_OK) { + LOGE("Failed to create new object auth"); goto out; } - if (keygen_mode == keygen_mode_normal) { /* Generate a new TPM key */ - - rv = utils_new_random_object_auth(&newauthhex); - if (rv != CKR_OK) { - LOGE("Failed to create new object auth"); - goto out; - } - - rv = tpm2_generate_key( - tok->tctx, - tok->pobject.handle, - tok->pobject.objauth, - newauthhex, - mechanism, - new_public_tobj->attrs, - new_private_tobj->attrs, - &objdata); - if (rv != CKR_OK) { - LOGE("Failed to generate key"); - goto out; - } - - /* set the tpm object handles */ - tobject_set_esys_tr(new_private_tobj, objdata.privhandle); - tobject_set_esys_tr(new_public_tobj, objdata.pubhandle); - - /* populate blob data */ - rv = tobject_set_blob_data(new_private_tobj, objdata.pubblob, objdata.privblob); - if (rv != CKR_OK) { - goto out; - } - - rv = tobject_set_blob_data(new_public_tobj, objdata.pubblob, NULL); - if (rv != CKR_OK) { - goto out; - } - - } else { /* Import an existing TPM key */ - - /* Read the CKA_TPM2_OBJAUTH */ - attr_ptr = attr_get_attribute_by_type(new_private_tobj->attrs, CKA_TPM2_OBJAUTH); - if (attr_ptr) { - newauthhex = twistbin_new(attr_ptr->pValue, attr_ptr->ulValueLen); - - /* Secure erase the CKA_TPM2_OBJAUTH field in the privkey template */ - memset(attr_ptr->pValue, 0, attr_ptr->ulValueLen); - attr_pfree_cleanse(attr_ptr); - - /* [To-do] delete the CKA_TPM2_OBJAUTH from the privkey template to save storage space */ - } - - if (keygen_mode == keygen_mode_phandle) { /* The key to import is a persistent handle */ - - attr_ptr = attr_get_attribute_by_type(new_private_tobj->attrs, CKA_TPM2_PERSISTENT_HANDLE); - rv = attr_CK_ULONG(attr_ptr, &priv_persistent_handle); - if (rv != CKR_OK) { - LOGE("Failed to get private key persistent handle"); - goto out; - } - - attr_ptr = attr_get_attribute_by_type(new_public_tobj->attrs, CKA_TPM2_PERSISTENT_HANDLE); - rv = attr_CK_ULONG(attr_ptr, &pub_persistent_handle); - if (rv != CKR_OK) { - LOGE("Failed to get public key persistent handle"); - goto out; - } - - if (priv_persistent_handle != pub_persistent_handle) { - LOGE("The public and private key persistent handles are not the same"); - return CKR_ATTRIBUTE_TYPE_INVALID; - } - - rv = tpm_get_esys_tr(tok->tctx, (uint32_t)priv_persistent_handle, - &priv_esys_tr, &pub_esys_tr); - if (rv != CKR_OK) { - LOGE("Failed to get ESYS_TR of privkey"); - goto out; - } - - tobject_set_persistent_handle(new_private_tobj, priv_persistent_handle); - tobject_set_persistent_handle(new_public_tobj, pub_persistent_handle); - tobject_set_esys_tr(new_private_tobj, priv_esys_tr); - tobject_set_esys_tr(new_public_tobj, pub_esys_tr); - - } else if (keygen_mode == keygen_mode_kobjs) { /* The key to import includes both public and private blobs */ - - attr_ptr = attr_get_attribute_by_type(new_public_tobj->attrs, CKA_TPM2_PUB_BLOB); - pub_blob = twistbin_new(attr_ptr->pValue, attr_ptr->ulValueLen); - - attr_ptr = attr_get_attribute_by_type(new_private_tobj->attrs, CKA_TPM2_PRIV_BLOB); - priv_blob = twistbin_new(attr_ptr->pValue, attr_ptr->ulValueLen); - - rv = tpm_loadobj(tok->tctx, tok->pobject.handle, tok->pobject.objauth, - pub_blob, NULL, &pub_esys_tr); - if (rv != CKR_OK) { - LOGE("Failed to load key objects"); - goto out; - } - - rv = tpm_loadobj(tok->tctx, tok->pobject.handle, tok->pobject.objauth, - pub_blob, priv_blob, &priv_esys_tr); - if (rv != CKR_OK) { - LOGE("Failed to load key objects"); - goto out; - } - - tobject_set_esys_tr(new_private_tobj, priv_esys_tr); - tobject_set_esys_tr(new_public_tobj, pub_esys_tr); - - rv = tobject_set_blob_data(new_private_tobj, pub_blob, priv_blob); - if (rv != CKR_OK) { - goto out; - } - - rv = tobject_set_blob_data(new_public_tobj, pub_blob, NULL); - if (rv != CKR_OK) { - goto out; - } - } else { /* Will not reach here */ - assert(0); - } - - /* Populate the mandatory attributes based on the TPM key */ - rv = tpm_parse_key_to_attrs(tok->tctx, priv_esys_tr, mechanism, - new_public_tobj->attrs, new_private_tobj->attrs, - &objdata); - if (rv != CKR_OK) { - goto out; - } + rv = utils_ctx_wrap_objauth(tok->wrappingkey, newauthhex, &newwrapped_auth); + if (rv != CKR_OK) { + LOGE("Failed to wrap new object auth"); + goto out; } - if (newauthhex) { - rv = utils_ctx_wrap_objauth(tok->wrappingkey, newauthhex, &newwrapped_auth); - if (rv != CKR_OK) { - LOGE("Failed to wrap new object auth"); - goto out; - } - - /* populate auth data, public objects do not need an auth */ - rv = tobject_set_auth(new_private_tobj, newauthhex, newwrapped_auth); - if (rv != CKR_OK) { - goto out; - } + rv = tpm2_generate_key( + tok->tctx, + tok->pobject.handle, + tok->pobject.objauth, + newauthhex, + mechanism, + pubkey_templ_w_types, + privkey_templ_w_types, + &objdata); + if (rv != CKR_OK) { + LOGE("Failed to generate key"); + goto out; } + /* set the tpm object handles */ + tobject_set_handle(new_private_tobj, objdata.privhandle); + tobject_set_handle(new_public_tobj, objdata.pubhandle); + + new_public_tobj->attrs = pubkey_templ_w_types; + new_private_tobj->attrs = privkey_templ_w_types; + + /* make it clear that tobj now owns these */ + pubkey_templ_w_types = privkey_templ_w_types = NULL; + /* * objects have default required attributes, add them if not present. */ @@ -440,6 +269,23 @@ CK_RV key_gen ( goto out; } + /* populate blob data */ + rv = tobject_set_blob_data(new_private_tobj, objdata.pubblob, objdata.privblob); + if (rv != CKR_OK) { + goto out; + } + + rv = tobject_set_blob_data(new_public_tobj, objdata.pubblob, NULL); + if (rv != CKR_OK) { + goto out; + } + + /* populate auth data, public objects do not need an auth */ + rv = tobject_set_auth(new_private_tobj, newauthhex, newwrapped_auth); + if (rv != CKR_OK) { + goto out; + } + rv = backend_add_object(tok, new_public_tobj); if (rv != CKR_OK) { LOGE("Failed to add public object to db"); @@ -471,8 +317,6 @@ CK_RV key_gen ( tpm_objdata_free(&objdata); twist_free(newauthhex); twist_free(newwrapped_auth); - twist_free(pub_blob); - twist_free(priv_blob); attr_list_free(pubkey_templ_w_types); attr_list_free(privkey_templ_w_types); diff --git a/src/lib/object.c b/src/lib/object.c index b422fe55..5564a5de 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -827,16 +827,10 @@ CK_RV tobject_set_auth(tobject *tobj, twist authbin, twist wrappedauthhex) { return r ? CKR_OK : CKR_GENERAL_ERROR; } -void tobject_set_esys_tr(tobject *tobj, uint32_t esys_tr) { +void tobject_set_handle(tobject *tobj, uint32_t handle) { assert(tobj); - tobj->tpm_esys_tr = esys_tr; -} - -void tobject_set_persistent_handle(tobject *tobj, uint32_t handle) { - assert(tobj); - - tobj->tpm_persistent_handle = handle; + tobj->tpm_handle = handle; } void tobject_set_id(tobject *tobj, unsigned id) { @@ -1305,16 +1299,6 @@ CK_RV object_init_from_attrs(tobject *tobj) { } } - a = attr_get_attribute_by_type(tobj->attrs, CKA_TPM2_PERSISTENT_HANDLE); - if (a && a->pValue && a->ulValueLen) { - CK_ULONG handle = 0; - if (attr_CK_ULONG(a, &handle) != CKR_OK) { - LOGE("Failed to read the tpm persistent handle"); - goto error; - } - tobj->tpm_persistent_handle = (uint32_t)handle; - } - return CKR_OK; error: diff --git a/src/lib/object.h b/src/lib/object.h index 799c812f..08996c74 100644 --- a/src/lib/object.h +++ b/src/lib/object.h @@ -38,8 +38,7 @@ struct tobject { twist unsealed_auth; /** unwrapped auth value */ - uint32_t tpm_esys_tr; /** loaded tpm handle */ - uint32_t tpm_persistent_handle; /** persistent TPM handle **/ + uint32_t tpm_handle; /** loaded tpm handle */ bool is_authenticated; /** true if a context specific login has authenticated use of the object */ }; @@ -74,8 +73,7 @@ CK_RV tobject_set_blob_data(tobject *tobj, twist pub, twist priv); */ CK_RV tobject_set_auth(tobject *tobj, twist authbin, twist wrappedauthhex); -void tobject_set_esys_tr(tobject *tobj, uint32_t esys_tr); -void tobject_set_persistent_handle(tobject *tobj, uint32_t handle); +void tobject_set_handle(tobject *tobj, uint32_t handle); void tobject_set_id(tobject *tobj, unsigned id); void tobject_free(tobject *tobj); diff --git a/src/lib/session_ctx.c b/src/lib/session_ctx.c index 6c4846b0..d597951a 100644 --- a/src/lib/session_ctx.c +++ b/src/lib/session_ctx.c @@ -317,21 +317,11 @@ CK_RV session_ctx_logout(session_ctx *ctx) { attr_pfree_cleanse(a); } - /* - * Do not perform tpm_flushcontext when: - * - tpm_esys_tr is 0, or - * - the object is private and the associated key in the TPM is persistent. - * - * If the object is public and the associated key in the TPM is persistent, - * tpm_flushcontext is still necessary because, during the initialization of the object, - * a transient TPM key with only the public component is created from the persistent key. - */ - if (tobj->tpm_esys_tr && - !(cka_private && tobj->tpm_persistent_handle)) { - bool result = tpm_flushcontext(tpm, tobj->tpm_esys_tr); + if (tobj->tpm_handle) { + bool result = tpm_flushcontext(tpm, tobj->tpm_handle); assert(result); UNUSED(result); - tobj->tpm_esys_tr = 0; + tobj->tpm_handle = 0; /* Clear the unwrapped auth value for tertiary objects */ twist_free(tobj->unsealed_auth); diff --git a/src/lib/token.c b/src/lib/token.c index e67a2e30..555621a7 100644 --- a/src/lib/token.c +++ b/src/lib/token.c @@ -631,40 +631,18 @@ CK_RV token_load_object(token *tok, CK_OBJECT_HANDLE key, tobject **loaded_tobj) * The object may already be loaded by the TPM or may just be * a public key object not-resident in the TPM. */ - if (tobj->tpm_esys_tr || (!tobj->pub && !tobj->tpm_persistent_handle)) { + if (tobj->tpm_handle || !tobj->pub) { *loaded_tobj = tobj; return CKR_OK; } - if (tobj->tpm_persistent_handle && v != CKO_SECRET_KEY) { - if (v == CKO_PRIVATE_KEY) { - rv = tpm_get_esys_tr( - tpm, - tobj->tpm_persistent_handle, - &tobj->tpm_esys_tr, - NULL); - if (rv != CKR_OK) { - return rv; - } - } else { - rv = tpm_get_esys_tr( - tpm, - tobj->tpm_persistent_handle, - NULL, - &tobj->tpm_esys_tr); - if (rv != CKR_OK) { - return rv; - } - } - } else { - rv = tpm_loadobj( - tpm, - tok->pobject.handle, tok->pobject.objauth, - tobj->pub, tobj->priv, - &tobj->tpm_esys_tr); - if (rv != CKR_OK) { - return rv; - } + rv = tpm_loadobj( + tpm, + tok->pobject.handle, tok->pobject.objauth, + tobj->pub, tobj->priv, + &tobj->tpm_handle); + if (rv != CKR_OK) { + return rv; } rv = utils_ctx_unwrap_objauth(tok->wrappingkey, tobj->objauth, diff --git a/src/lib/tpm.c b/src/lib/tpm.c index 009f831c..a622a47e 100644 --- a/src/lib/tpm.c +++ b/src/lib/tpm.c @@ -1234,7 +1234,7 @@ static CK_RV tpm_hmac_large(tpm_op_data *opdata, CK_BYTE_PTR data, CK_ULONG data assert(tctx); twist auth = tobj->unsealed_auth; - TPMI_DH_OBJECT handle = tobj->tpm_esys_tr; + TPMI_DH_OBJECT handle = tobj->tpm_handle; ESYS_TR session = tctx->hmac_session; @@ -1358,7 +1358,7 @@ static CK_RV tpm_hmac(tpm_op_data *opdata, CK_BYTE_PTR data, CK_ULONG datalen, C assert(tctx); twist auth = tobj->unsealed_auth; - TPMI_DH_OBJECT handle = tobj->tpm_esys_tr; + TPMI_DH_OBJECT handle = tobj->tpm_handle; ESYS_TR session = tctx->hmac_session; @@ -1417,7 +1417,7 @@ CK_RV tpm_sign(tpm_op_data *opdata, CK_BYTE_PTR data, CK_ULONG datalen, CK_BYTE_ assert(tctx); twist auth = tobj->unsealed_auth; - TPMI_DH_OBJECT handle = tobj->tpm_esys_tr; + TPMI_DH_OBJECT handle = tobj->tpm_handle; ESYS_CONTEXT *ectx = tctx->esys_ctx; ESYS_TR session = tctx->hmac_session; TPMT_SIG_SCHEME *scheme = NULL; @@ -1614,7 +1614,7 @@ CK_RV tpm_rsa_oaep_get_opdata(mdetail *m, tpm_ctx *tctx, CK_MECHANISM_PTR mech, * TPM is hardcoded to MGF1 + in the TPM, make sure what is requested is supported */ CK_RSA_PKCS_MGF_TYPE supported_mgf; - CK_RV rv = get_oaep_mgf1_alg(tctx, tobj->tpm_esys_tr, &supported_mgf); + CK_RV rv = get_oaep_mgf1_alg(tctx, tobj->tpm_handle, &supported_mgf); if (rv != CKR_OK) { return rv; } @@ -2231,7 +2231,7 @@ CK_RV tpm_rsa_decrypt(tpm_op_data *tpm_enc_data, memcpy(tpm_ctext.buffer, ctext, ctextlen); twist auth = tpm_enc_data->tobj->unsealed_auth; - ESYS_TR handle = tpm_enc_data->tobj->tpm_esys_tr; + ESYS_TR handle = tpm_enc_data->tobj->tpm_handle; bool result = set_esys_auth(ctx->esys_ctx, handle, auth); if (!result) { return CKR_GENERAL_ERROR; @@ -2492,7 +2492,7 @@ static CK_RV do_buffered_encdec(tpm_op_data *tpm_enc_data, TPM2B_IV *iv = &tpm_enc_data->sym.iv; twist auth = tpm_enc_data->tobj->unsealed_auth; - ESYS_TR handle = tpm_enc_data->tobj->tpm_esys_tr; + ESYS_TR handle = tpm_enc_data->tobj->tpm_handle; /* final calls don't have input data, they just exhaust the internal buffer if present */ bool is_final = !in; @@ -4577,7 +4577,7 @@ CK_RV tpm_get_pss_sig_state(tpm_ctx *tctx, tobject *tobj, .digest = { 0 } }; - bool res = set_esys_auth(tctx->esys_ctx, tobj->tpm_esys_tr, + bool res = set_esys_auth(tctx->esys_ctx, tobj->tpm_handle, tobj->unsealed_auth); if (!res) { return CKR_GENERAL_ERROR; @@ -4585,7 +4585,7 @@ CK_RV tpm_get_pss_sig_state(tpm_ctx *tctx, tobject *tobj, TSS2_RC rval = Esys_Sign( tctx->esys_ctx, - tobj->tpm_esys_tr, + tobj->tpm_handle, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, @@ -4659,12 +4659,12 @@ CK_RV tpm_ec_ecdh1_derive(tpm_ctx *tctx, tobject *tobj, uint8_t *ecc_point, return rv; } - bool res = set_esys_auth(tctx->esys_ctx, tobj->tpm_esys_tr, tobj->unsealed_auth); + bool res = set_esys_auth(tctx->esys_ctx, tobj->tpm_handle, tobj->unsealed_auth); if (!res) { return CKR_GENERAL_ERROR; } - rv = Esys_ECDH_ZGen(tctx->esys_ctx, tobj->tpm_esys_tr, ESYS_TR_PASSWORD, + rv = Esys_ECDH_ZGen(tctx->esys_ctx, tobj->tpm_handle, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, &in_point, &out_point); if (rv != CKR_OK) { return rv; @@ -4685,159 +4685,3 @@ CK_RV tpm_ec_ecdh1_derive(tpm_ctx *tctx, tobject *tobj, uint8_t *ecc_point, return rv; } -CK_RV tpm_get_esys_tr( - tpm_ctx *ctx, - uint32_t persistent_handle, - uint32_t *esys_tr, - uint32_t *esys_tr_pub) -{ - ESYS_TR tr; - TPM2B_PUBLIC *public = NULL; - - TSS2_RC rval; - CK_RV rv = CKR_OK; - - rval = Esys_TR_FromTPMPublic( - ctx->esys_ctx, - persistent_handle, - ESYS_TR_NONE, - ESYS_TR_NONE, - ESYS_TR_NONE, - &tr); - if (rval != TSS2_RC_SUCCESS) { - LOGE("Esys_TR_FromTPMPublic: %s:", Tss2_RC_Decode(rval)); - rv = CKR_GENERAL_ERROR; - goto exit; - } - - if (esys_tr_pub) { - if ((rv = tpm_readpub(ctx, tr, &public, NULL, NULL))) { - goto exit_flush; - } - - if (!tpm_loadexternal(ctx, public, esys_tr_pub)) { - rv = CKR_GENERAL_ERROR; - goto exit_flush; - } - } - - if (esys_tr) { - *esys_tr = tr; - goto exit; - } - -exit_flush: - if (!tpm_flushcontext(ctx, tr)) { - rv = CKR_GENERAL_ERROR; - } -exit: - free(public); - return rv; -} - -CK_RV tpm_parse_key_to_attrs( - tpm_ctx *ctx, - uint32_t esys_tr, - CK_MECHANISM_PTR mechanism, - attr_list *pub_attrs, - attr_list *priv_attrs, - tpm_object_data *obj_data) -{ - - CK_RV rv = CKR_GENERAL_ERROR; - TPM2B_PUBLIC *public = NULL; - - assert(pub_attrs); - assert(priv_attrs); - assert(obj_data); - - rv = sanity_check_mech(mechanism); - if (rv != CKR_OK) { - goto exit; - } - - if ((rv = tpm_readpub(ctx, esys_tr, &public, NULL, NULL))) { - goto exit; - } - - /* Check if the TPM key type is consistent with the PKCS11 mechanism */ - switch(mechanism->mechanism) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - if (public->publicArea.type != TPM2_ALG_RSA) { - LOGE("Mismatch in the given TPM key type with the mechanism"); - rv = CKR_MECHANISM_INVALID; - goto exit; - } - break; - - case CKM_EC_KEY_PAIR_GEN: - if (public->publicArea.type != TPM2_ALG_ECC) { - LOGE("Mismatch in the given TPM key type with the mechanism"); - rv = CKR_MECHANISM_INVALID; - goto exit; - } - break; - } - - /* Initialize the attribute list */ - - obj_data->attrs = attr_list_new(); - if (!obj_data->attrs) { - LOGE("oom"); - rv = CKR_HOST_MEMORY; - goto exit; - } - - /* Populate key type-specific attributes for pub & priv */ - - switch(mechanism->mechanism) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - rv = tpm_object_data_populate_rsa(public, obj_data); - if (rv != CKR_OK) { - goto exit_attr_list_free; - } - break; - - case CKM_EC_KEY_PAIR_GEN: - rv = tpm_object_data_populate_ecc(public, obj_data); - if (rv != CKR_OK) { - goto exit_attr_list_free; - } - break; - } - - /* Populate non-key-type-specific attributes for pub & priv */ - - TPMA_OBJECT objattrs = public->publicArea.objectAttributes; - - CK_BBOOL extractable = !!!(objattrs & (TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT)); - CK_BBOOL sensitive = !extractable; - CK_BBOOL never_extractable = !extractable; - CK_BBOOL local = !!(objattrs & TPMA_OBJECT_SENSITIVEDATAORIGIN); - CK_BBOOL decrypt = !!(objattrs & TPMA_OBJECT_DECRYPT); - CK_BBOOL sign = !!(objattrs & TPMA_OBJECT_SIGN_ENCRYPT); - - if (!attr_list_add_bool(obj_data->attrs, CKA_EXTRACTABLE, extractable) || - !attr_list_add_bool(obj_data->attrs, CKA_ALWAYS_SENSITIVE, sensitive) || - !attr_list_add_bool(obj_data->attrs, CKA_NEVER_EXTRACTABLE, never_extractable) || - !attr_list_add_bool(obj_data->attrs, CKA_LOCAL, local) || - !attr_list_add_bool(obj_data->attrs, CKA_DECRYPT, decrypt) || - !attr_list_add_bool(obj_data->attrs, CKA_VERIFY, decrypt) || /* decrypt and verify are the same */ - !attr_list_add_bool(obj_data->attrs, CKA_SIGN, sign) || - !attr_list_add_bool(obj_data->attrs, CKA_ENCRYPT, sign)) { /* sign and encrypt are same */ - rv = CKR_HOST_MEMORY; - goto exit_attr_list_free; - } - - /* Other public/private specific attributes are covered by attr_add_missing_attrs() */ - - (void) pub_attrs; - (void) priv_attrs; - - goto exit; -exit_attr_list_free: - attr_list_free(obj_data->attrs); -exit: - free(public); - return rv; -} diff --git a/src/lib/tpm.h b/src/lib/tpm.h index 090c7641..24246082 100644 --- a/src/lib/tpm.h +++ b/src/lib/tpm.h @@ -199,57 +199,8 @@ CK_RV tpm_create_transient_primary_from_template(tpm_ctx *tpm, CK_RV tpm_get_pss_sig_state(tpm_ctx *tctx, tobject *tobj, bool *pss_sigs_good); -/** - * Retrieve the associated ESYS_TR from the given TPM2_HANDLE. - * - * @param ctx - * The TPM API context. - * @param persistent_handle - * The TPM persistent handle (TPM2_HANDLE). - * @param esys_tr - * An optional output (can be NULL). - * The associated ESYS_TR is returned here. - * @param esys_tr_pub - * An optional output (can be NULL). - * A new key is created with only the public component from the - * persistent handle. The associated ESYS_TR is returned here. - * @return - * CKR_OK on success; otherwise, an error code. - */ -CK_RV tpm_get_esys_tr( - tpm_ctx *ctx, - uint32_t persistent_handle, - uint32_t *esys_tr, - uint32_t *esys_tr_pub); - bool tpm_get_name(tpm_ctx *ctx, uint32_t handle, twist *name); -/** - * Populate the CK_ATTRIBUTE list based on the given TPM key - * - * @param ctx - * The TPM API context. - * @param esys_tr - * The TPM key ESYS_TR. - * @param mechanism - * The mechanism. - * @param pub_attrs - * The public key's CK_ATTRIBUTE list is returned here. - * @param priv_attrs - * The private key's CK_ATTRIBUTE list is returned here. - * @param obj_data - * The struct tpm_object_data is returned here. - * @return - * CKR_OK on success; otherwise, an error code. - */ -CK_RV tpm_parse_key_to_attrs( - tpm_ctx *tpm, - uint32_t esys_tr, - CK_MECHANISM_PTR mechanism, - attr_list *pub_attrs, - attr_list *priv_attrs, - tpm_object_data *obj_data); - void tpm_init(void); void tpm_destroy(void); diff --git a/test/integration/key_import-link-fapi.sh.fapi b/test/integration/key_import-link-fapi.sh.fapi deleted file mode 120000 index 5e2a4875..00000000 --- a/test/integration/key_import-link-fapi.sh.fapi +++ /dev/null @@ -1 +0,0 @@ -key_import-link.sh.nosetup \ No newline at end of file diff --git a/test/integration/key_import-link.sh.nosetup b/test/integration/key_import-link.sh.nosetup deleted file mode 100755 index 5f283447..00000000 --- a/test/integration/key_import-link.sh.nosetup +++ /dev/null @@ -1,449 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: BSD-2-Clause -# -# Copyright (c) 2024 Infineon Technologies AG -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE - -set -xe - -if [ -z "$T" ]; then - export T="$(cd "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" -fi - -source "$T/test/integration/scripts/helpers.sh" - -check_openssl_version - -export TPM2OPENSSL_TCTI="$TPM2TOOLS_TCTI" - -tempdir=$(mktemp -d) - -function cleanup() { - rm -rf "$tempdir" -} -trap cleanup EXIT - -onerror() { - echo "$BASH_COMMAND on line ${BASH_LINENO[0]} failed: $?" - exit 1 -} -trap onerror ERR - -setup_asan - -key_import -h - -if [ -z "$modpath" ]; then - modpath="$PWD/src/.libs/libtpm2_pkcs11.so" -fi - -echo "modpath=$modpath" - -pkcs11_tool() { - pkcs11-tool --module "$modpath" "$@" - return $? -} - -# ==================================================================== -# FUNCTION: create_key -# DESCRIPTION: Provision ordinary TPM keys with/without parent auth, -# with/without key auth -# PARAMETERS: -# $1 - algo -# $2 - parent context -# $3 - parent auth -# $4 - key name -# $5 - persistent handle -# $6 - key auth -# ==================================================================== -create_key() { - if [ -z "$3" ]; then - if [ -z "$6" ]; then - tpm2_create -C $2 -g sha256 -G $1 \ - -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv - else - tpm2_create -C $2 -p $6 -g sha256 -G $1 \ - -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv - fi - tpm2_load -C $2 -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv \ - -c ${tempdir}/${4}.ctx - else - if [ -z "$6" ]; then - tpm2_create -C $2 -P $3 -g sha256 -G $1 \ - -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv - else - tpm2_create -C $2 -P $3 -p $6 -g sha256 -G $1 \ - -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv - fi - tpm2_load -C $2 -P $3 -u ${tempdir}/${4}.pub -r ${tempdir}/${4}.priv \ - -c ${tempdir}/${4}.ctx - fi - tpm2_evictcontrol -C o -c ${tempdir}/${4}.ctx $5 - tpm2_readpublic -c $5 -} - -# ==================================================================== -# FUNCTION: rsakey_tests -# DESCRIPTION: A helper function for testing RSA key. -# PARAMETERS: -# $1 - slot index -# $2 - key label -# ==================================================================== -rsakey_tests() { - rm -f ${tempdir}/rsa.pub.pem ${tempdir}/rsa.pub.der - - # The value of id is the hex representation of the ASCII text of the label - id=$(echo -n $2 | xxd -p) - - # Read the public component - pkcs11_tool --slot-index $1 --login --pin myuserpin --id $id --type pubkey \ - --read-object --output-file ${tempdir}/rsa.pub.der - openssl rsa -inform DER -outform PEM -in ${tempdir}/rsa.pub.der -pubin \ - -out ${tempdir}/rsa.pub.pem - cat ${tempdir}/rsa.pub.pem - - # Create a file with random data - pkcs11_tool --slot-index $1 --generate-random 32 --output-file ${tempdir}/data.plain - - # Perform RSA encryption and decryption - openssl rsautl -encrypt -inkey ${tempdir}/rsa.pub.pem -in ${tempdir}/data.plain \ - -pubin -out ${tempdir}/data.cipher - pkcs11_tool --slot-index $1 --login --pin myuserpin --id $id --decrypt \ - --mechanism RSA-PKCS --input-file ${tempdir}/data.cipher \ - --output-file ${tempdir}/data.decipher - diff ${tempdir}/data.plain ${tempdir}/data.decipher - - # Perform sign and verification - pkcs11_tool --slot-index $1 --id $id --login --pin myuserpin --sign \ - --mechanism SHA256-RSA-PKCS --input-file ${tempdir}/data.plain \ - --output-file ${tempdir}/data.rsa.sig - openssl dgst -sha256 -verify ${tempdir}/rsa.pub.pem \ - -signature ${tempdir}/data.rsa.sig ${tempdir}/data.plain -} - -# ==================================================================== -# FUNCTION: eckey_tests -# DESCRIPTION: A helper function for testing EC key. -# PARAMETERS: -# $1 - slot index -# $2 - key label -# ==================================================================== -eckey_tests() { - rm -f ${tempdir}/ec.pub.pem ${tempdir}/ec.pub.der - - # The value of id is the hex representation of the ASCII text of the label - id=$(echo -n $2 | xxd -p) - - # Read the public component - pkcs11_tool --slot-index $1 --login --pin myuserpin --id $id --type pubkey \ - --read-object --output-file ${tempdir}/ec.pub.der - openssl ec -inform DER -outform PEM -in ${tempdir}/ec.pub.der -pubin \ - -out ${tempdir}/ec.pub.pem - cat ${tempdir}/ec.pub.pem - - # Create a file with random data - pkcs11_tool --slot-index $1 --generate-random 32 --output-file ${tempdir}/data.plain - - # Perform sign and verification - pkcs11_tool --slot-index $1 --id $id --login --pin myuserpin --sign \ - --mechanism ECDSA-SHA1 --signature-format openssl \ - --input-file ${tempdir}/data.plain --output-file ${tempdir}/data.ec.sig - openssl dgst -sha1 -verify ${tempdir}/ec.pub.pem \ - -signature ${tempdir}/data.ec.sig ${tempdir}/data.plain -} - -export TPM2_PKCS11_STORE="$tempdir" - -echo "TPM2_PKCS11_STORE=$TPM2_PKCS11_STORE" - -echo "testdata">${tempdir}/data - -echo "Should have uninitialized token" -pkcs11_tool -T | grep -q uninitialized -echo "Found uninitialized token" - -# pkcs11_tool slot index starts from 0 -pkcs11tool_slot_index=0 - -# tpm2_pkcs11 slot index starts from 1 -tpm2pkcs11_slot_index=1 - -###################### -# Provision keys (primary key without auth value) -##################### - -echo "Provision keys (primary key without auth value) starts here" - -# Check if TPM2_PKCS11_BACKEND is set to fapi -if [ "$TPM2_PKCS11_BACKEND" != "fapi" ]; then - tpm2_clear -c p - tpm2_createprimary -G ecc -c ${tempdir}/primarynoauth.ctx - tpm2_evictcontrol -c ${tempdir}/primarynoauth.ctx 0x81000001 -fi - -# Create an RSA key with no auth value -create_key rsa 0x81000001 "" primnoauth_rsakeynoauth 0x81000002 "" - -# Create an RSA key with auth value -create_key rsa 0x81000001 "" primnoauth_rsakeywithauth 0x81000003 rsakeyauth123 - -# Create an ECC key with no auth value -create_key ecc 0x81000001 "" primnoauth_eckeynoauth 0x81000004 "" - -# Create an ECC key with auth value -create_key ecc 0x81000001 "" primnoauth_eckeywithauth 0x81000005 eckeyauth123 - -######## -# Tests (primary key without auth value) -######## - -echo "Testing (primary key without auth value) starts here" - -# Initialize the token in the first slot -pkcs11_tool --slot-index $pkcs11tool_slot_index --init-token --label tpm2-token-primary-no-auth --so-pin mysopin -pkcs11_tool --slot-index $pkcs11tool_slot_index --login --login-type="so" --init-pin --so-pin mysopin --pin myuserpin - -pkcs11_tool --list-token-slots -pkcs11_tool --list-token-slots | grep "Slot 0 (0x1): tpm2-token-primary-no-auth" -pkcs11_tool --list-token-slots | grep -Pz "Slot 1 \(0x2\): \n token state: uninitialized" - -# Import keys using their persistent handles -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000002 \ - --key-label rsakeynoauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000003 --key-auth rsakeyauth123 \ - --key-label rsakeywithauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000004 \ - --key-label eckeynoauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000005 --key-auth eckeyauth123 \ - --key-label eckeywithauth-persist - -# Import keys using their object files -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/primnoauth_rsakeynoauth.pub \ - --private ${tempdir}/primnoauth_rsakeynoauth.priv \ - --key-label rsakeynoauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/primnoauth_rsakeywithauth.pub \ - --private ${tempdir}/primnoauth_rsakeywithauth.priv \ - --key-auth rsakeyauth123 \ - --key-label rsakeywithauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/primnoauth_eckeynoauth.pub \ - --private ${tempdir}/primnoauth_eckeynoauth.priv \ - --key-label eckeynoauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/primnoauth_eckeywithauth.pub \ - --private ${tempdir}/primnoauth_eckeywithauth.priv \ - --key-auth eckeyauth123 \ - --key-label eckeywithauth-objects - -pkcs11_tool --slot-index $pkcs11tool_slot_index --list-objects --login --pin myuserpin - -# Iterate through all the imported keys: -rsakey_tests $pkcs11tool_slot_index rsakeynoauth-persist -rsakey_tests $pkcs11tool_slot_index rsakeywithauth-persist -eckey_tests $pkcs11tool_slot_index eckeynoauth-persist -eckey_tests $pkcs11tool_slot_index eckeywithauth-persist -rsakey_tests $pkcs11tool_slot_index rsakeynoauth-objects -rsakey_tests $pkcs11tool_slot_index rsakeywithauth-objects -eckey_tests $pkcs11tool_slot_index eckeynoauth-objects -eckey_tests $pkcs11tool_slot_index eckeywithauth-objects - -################## -# Negative testing -################## - -echo "Negative testing starts here" - -set +e - -key_import bad 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Missing inputs" || exit 1 - -key_import -bad 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "invalid option" || exit 1 - -key_import --bad 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "unrecognized option" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --persistent-handle 0x81000002 \ - --key-label rsakeynoauth-persist 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Missing inputs" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000002 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Missing inputs" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000002 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Missing inputs" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0xbad \ - --key-label rsakeynoauth-persist 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Expecting an 8-character long hexadecimal" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/bad.pub \ - --private ${tempdir}/primnoauth_rsakeynoauth.priv \ - --key-label rsakeynoauth-objects 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Could not open the file \"${tempdir}/bad.pub\"" || exit 1 - -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000001 \ - --public ${tempdir}/primnoauth_rsakeynoauth.pub \ - --private ${tempdir}/bad.priv \ - --key-label rsakeynoauth-objects 2> ${tempdir}/error.log && exit 1 -cat ${tempdir}/error.log | grep "Could not open the file \"${tempdir}/bad.priv\"" || exit 1 - -set -e - -# Check if TPM2_PKCS11_BACKEND is set to fapi -if [ "$TPM2_PKCS11_BACKEND" == "fapi" ]; then - exit 0 -fi - -################### -# Provision keys (primary key with auth value) -################### - -echo "Provision keys (primary key with auth value) starts here" - -tpm2_createprimary -G ecc -c ${tempdir}/primarywithauth.ctx -p parentauth123 -tpm2_evictcontrol -c ${tempdir}/primarywithauth.ctx 0x81000011 - -# Create an RSA key with no auth value -create_key rsa 0x81000011 parentauth123 primwithauth_rsakeynoauth 0x81000012 "" - -# Create an RSA key with auth value -create_key rsa 0x81000011 parentauth123 primwithauth_rsakeywithauth 0x81000013 rsakeyauth123 - -# Create an ECC key with no auth value -create_key ecc 0x81000011 parentauth123 primwithauth_eckeynoauth 0x81000014 "" - -# Create an ECC key with auth value -create_key ecc 0x81000011 parentauth123 primwithauth_eckeywithauth 0x81000015 eckeyauth123 - -######## -# Tests (primary key with auth value) -######## - -echo "Testing (primary key with auth value) starts here" - -pkcs11tool_slot_index=$(expr $pkcs11tool_slot_index + 1) -tpm2pkcs11_slot_index=$(expr $tpm2pkcs11_slot_index + 1) - -# Initialize the token in the second slot -pid=$(tpm2_ptool init --primary-handle 0x81000011 --primary-auth parentauth123 \ - --path $TPM2_PKCS11_STORE | grep id | sed 's/id: //') -tpm2_ptool addtoken --pid $pid --sopin mysopin --userpin myuserpin \ - --label tpm2-token-primary-with-auth --path $TPM2_PKCS11_STORE - -pkcs11_tool --list-token-slots -pkcs11_tool --list-token-slots | grep "Slot 0 (0x1): tpm2-token-primary-no-auth" -pkcs11_tool --list-token-slots | grep "Slot 1 (0x2): tpm2-token-primary-with-auth" -pkcs11_tool --list-token-slots | grep -Pz "Slot 2 \(0x3\): \n token state: uninitialized" - -# Import keys using their persistent handles -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000012 \ - --key-label rsakeynoauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000013 --key-auth rsakeyauth123 \ - --key-label rsakeywithauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000014 \ - --key-label eckeynoauth-persist -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --persistent-handle 0x81000015 --key-auth eckeyauth123 \ - --key-label eckeywithauth-persist - -# Import keys using their object files -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000011 \ - --parent-auth parentauth123 \ - --public ${tempdir}/primwithauth_rsakeynoauth.pub \ - --private ${tempdir}/primwithauth_rsakeynoauth.priv \ - --key-label rsakeynoauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000011 \ - --parent-auth parentauth123 \ - --public ${tempdir}/primwithauth_rsakeywithauth.pub \ - --private ${tempdir}/primwithauth_rsakeywithauth.priv \ - --key-auth rsakeyauth123 \ - --key-label rsakeywithauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000011 \ - --parent-auth parentauth123 \ - --public ${tempdir}/primwithauth_eckeynoauth.pub \ - --private ${tempdir}/primwithauth_eckeynoauth.priv \ - --key-label eckeynoauth-objects -key_import --slot-id $tpm2pkcs11_slot_index --user-pin myuserpin \ - --tcti "$TPM2TOOLS_TCTI" \ - --parent-persistent-handle 0x81000011 \ - --parent-auth parentauth123 \ - --public ${tempdir}/primwithauth_eckeywithauth.pub \ - --private ${tempdir}/primwithauth_eckeywithauth.priv \ - --key-auth eckeyauth123 \ - --key-label eckeywithauth-objects - -pkcs11_tool --slot-index $pkcs11tool_slot_index --list-objects --login --pin myuserpin - -# Iterate through all the imported keys: -rsakey_tests $pkcs11tool_slot_index rsakeynoauth-persist -rsakey_tests $pkcs11tool_slot_index rsakeywithauth-persist -eckey_tests $pkcs11tool_slot_index eckeynoauth-persist -eckey_tests $pkcs11tool_slot_index eckeywithauth-persist -rsakey_tests $pkcs11tool_slot_index rsakeynoauth-objects -rsakey_tests $pkcs11tool_slot_index rsakeywithauth-objects -eckey_tests $pkcs11tool_slot_index eckeynoauth-objects -eckey_tests $pkcs11tool_slot_index eckeywithauth-objects - -exit 0 diff --git a/tools/key_import/import.c b/tools/key_import/import.c deleted file mode 100644 index caa4a972..00000000 --- a/tools/key_import/import.c +++ /dev/null @@ -1,767 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -/* - * Copyright (c) 2024 Infineon Technologies AG - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "attrs.h" -#include "db.h" -#include "pkcs11.h" -#include "utils.h" - -#ifdef DEBUG -#define PRINT_E(...) \ - fprintf(stderr, "%s:%d:%s() ", __FILE__, __LINE__, __func__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n") -#else -#define PRINT_E(...) \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n") -#endif - -#define ADD_ATTR(a, t, l, v) \ - do { \ - CK_ATTRIBUTE_PTR p = a; \ - p->type = t; \ - p->ulValueLen = l; \ - p->pValue = v; \ - } while (0) - -static const struct { - CK_RV rv; - const char *str; -} ckr_str_map[] = { - { CKR_OK, "CKR_OK" }, - { CKR_CANCEL, "CKR_CANCEL" }, - { CKR_HOST_MEMORY, "CKR_HOST_MEMORY" }, - { CKR_SLOT_ID_INVALID, "CKR_SLOT_ID_INVALID" }, - { CKR_GENERAL_ERROR, "CKR_GENERAL_ERROR" }, - { CKR_FUNCTION_FAILED, "CKR_FUNCTION_FAILED" }, - { CKR_ARGUMENTS_BAD, "CKR_ARGUMENTS_BAD" }, - { CKR_NO_EVENT, "CKR_NO_EVENT" }, - { CKR_NEED_TO_CREATE_THREADS, "CKR_NEED_TO_CREATE_THREADS" }, - { CKR_CANT_LOCK, "CKR_CANT_LOCK" }, - { CKR_ATTRIBUTE_READ_ONLY, "CKR_ATTRIBUTE_READ_ONLY" }, - { CKR_ATTRIBUTE_SENSITIVE, "CKR_ATTRIBUTE_SENSITIVE" }, - { CKR_ATTRIBUTE_TYPE_INVALID, "CKR_ATTRIBUTE_TYPE_INVALID" }, - { CKR_ATTRIBUTE_VALUE_INVALID, "CKR_ATTRIBUTE_VALUE_INVALID" }, - { CKR_DATA_INVALID, "CKR_DATA_INVALID" }, - { CKR_DATA_LEN_RANGE, "CKR_DATA_LEN_RANGE" }, - { CKR_DEVICE_ERROR, "CKR_DEVICE_ERROR" }, - { CKR_DEVICE_MEMORY, "CKR_DEVICE_MEMORY" }, - { CKR_DEVICE_REMOVED, "CKR_DEVICE_REMOVED" }, - { CKR_ENCRYPTED_DATA_INVALID, "CKR_ENCRYPTED_DATA_INVALID" }, - { CKR_ENCRYPTED_DATA_LEN_RANGE, "CKR_ENCRYPTED_DATA_LEN_RANGE" }, - { CKR_FUNCTION_CANCELED, "CKR_FUNCTION_CANCELED" }, - { CKR_FUNCTION_NOT_PARALLEL, "CKR_FUNCTION_NOT_PARALLEL" }, - { CKR_FUNCTION_NOT_SUPPORTED, "CKR_FUNCTION_NOT_SUPPORTED" }, - { CKR_KEY_HANDLE_INVALID, "CKR_KEY_HANDLE_INVALID" }, - { CKR_KEY_SIZE_RANGE, "CKR_KEY_SIZE_RANGE" }, - { CKR_KEY_TYPE_INCONSISTENT, "CKR_KEY_TYPE_INCONSISTENT" }, - { CKR_KEY_NOT_NEEDED, "CKR_KEY_NOT_NEEDED" }, - { CKR_KEY_CHANGED, "CKR_KEY_CHANGED" }, - { CKR_KEY_NEEDED, "CKR_KEY_NEEDED" }, - { CKR_KEY_INDIGESTIBLE, "CKR_KEY_INDIGESTIBLE" }, - { CKR_KEY_FUNCTION_NOT_PERMITTED, "CKR_KEY_FUNCTION_NOT_PERMITTED" }, - { CKR_KEY_NOT_WRAPPABLE, "CKR_KEY_NOT_WRAPPABLE" }, - { CKR_KEY_UNEXTRACTABLE, "CKR_KEY_UNEXTRACTABLE" }, - { CKR_MECHANISM_INVALID, "CKR_MECHANISM_INVALID" }, - { CKR_MECHANISM_PARAM_INVALID, "CKR_MECHANISM_PARAM_INVALID" }, - { CKR_OBJECT_HANDLE_INVALID, "CKR_OBJECT_HANDLE_INVALID" }, - { CKR_OPERATION_ACTIVE, "CKR_OPERATION_ACTIVE" }, - { CKR_OPERATION_NOT_INITIALIZED, "CKR_OPERATION_NOT_INITIALIZED" }, - { CKR_PIN_INCORRECT, "CKR_PIN_INCORRECT" }, - { CKR_PIN_INVALID, "CKR_PIN_INVALID" }, - { CKR_PIN_LEN_RANGE, "CKR_PIN_LEN_RANGE" }, - { CKR_PIN_EXPIRED, "CKR_PIN_EXPIRED" }, - { CKR_PIN_LOCKED, "CKR_PIN_LOCKED" }, - { CKR_SESSION_CLOSED, "CKR_SESSION_CLOSED" }, - { CKR_SESSION_COUNT, "CKR_SESSION_COUNT" }, - { CKR_SESSION_HANDLE_INVALID, "CKR_SESSION_HANDLE_INVALID" }, - { CKR_SESSION_PARALLEL_NOT_SUPPORTED, "CKR_SESSION_PARALLEL_NOT_SUPPORTED" }, - { CKR_SESSION_READ_ONLY, "CKR_SESSION_READ_ONLY" }, - { CKR_SESSION_EXISTS, "CKR_SESSION_EXISTS" }, - { CKR_SESSION_READ_ONLY_EXISTS, "CKR_SESSION_READ_ONLY_EXISTS" }, - { CKR_SESSION_READ_WRITE_SO_EXISTS, "CKR_SESSION_READ_WRITE_SO_EXISTS" }, - { CKR_SIGNATURE_INVALID, "CKR_SIGNATURE_INVALID" }, - { CKR_SIGNATURE_LEN_RANGE, "CKR_SIGNATURE_LEN_RANGE" }, - { CKR_TEMPLATE_INCOMPLETE, "CKR_TEMPLATE_INCOMPLETE" }, - { CKR_TEMPLATE_INCONSISTENT, "CKR_TEMPLATE_INCONSISTENT" }, - { CKR_TOKEN_NOT_PRESENT, "CKR_TOKEN_NOT_PRESENT" }, - { CKR_TOKEN_NOT_RECOGNIZED, "CKR_TOKEN_NOT_RECOGNIZED" }, - { CKR_TOKEN_WRITE_PROTECTED, "CKR_TOKEN_WRITE_PROTECTED" }, - { CKR_UNWRAPPING_KEY_HANDLE_INVALID, "CKR_UNWRAPPING_KEY_HANDLE_INVALID" }, - { CKR_UNWRAPPING_KEY_SIZE_RANGE, "CKR_UNWRAPPING_KEY_SIZE_RANGE" }, - { CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT" }, - { CKR_USER_ALREADY_LOGGED_IN, "CKR_USER_ALREADY_LOGGED_IN" }, - { CKR_USER_NOT_LOGGED_IN, "CKR_USER_NOT_LOGGED_IN" }, - { CKR_USER_PIN_NOT_INITIALIZED, "CKR_USER_PIN_NOT_INITIALIZED" }, - { CKR_USER_TYPE_INVALID, "CKR_USER_TYPE_INVALID" }, - { CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "CKR_USER_ANOTHER_ALREADY_LOGGED_IN" }, - { CKR_USER_TOO_MANY_TYPES, "CKR_USER_TOO_MANY_TYPES" }, - { CKR_WRAPPED_KEY_INVALID, "CKR_WRAPPED_KEY_INVALID" }, - { CKR_WRAPPED_KEY_LEN_RANGE, "CKR_WRAPPED_KEY_LEN_RANGE" }, - { CKR_WRAPPING_KEY_HANDLE_INVALID, "CKR_WRAPPING_KEY_HANDLE_INVALID" }, - { CKR_WRAPPING_KEY_SIZE_RANGE, "CKR_WRAPPING_KEY_SIZE_RANGE" }, - { CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "CKR_WRAPPING_KEY_TYPE_INCONSISTENT" }, - { CKR_RANDOM_SEED_NOT_SUPPORTED, "CKR_RANDOM_SEED_NOT_SUPPORTED" }, - { CKR_RANDOM_NO_RNG, "CKR_RANDOM_NO_RNG" }, - { CKR_DOMAIN_PARAMS_INVALID, "CKR_DOMAIN_PARAMS_INVALID" }, - { CKR_BUFFER_TOO_SMALL, "CKR_BUFFER_TOO_SMALL" }, - { CKR_SAVED_STATE_INVALID, "CKR_SAVED_STATE_INVALID" }, - { CKR_INFORMATION_SENSITIVE, "CKR_INFORMATION_SENSITIVE" }, - { CKR_STATE_UNSAVEABLE, "CKR_STATE_UNSAVEABLE" }, - { CKR_CRYPTOKI_NOT_INITIALIZED, "CKR_CRYPTOKI_NOT_INITIALIZED" }, - { CKR_CRYPTOKI_ALREADY_INITIALIZED, "CKR_CRYPTOKI_ALREADY_INITIALIZED" }, - { CKR_MUTEX_BAD, "CKR_MUTEX_BAD" }, - { CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED" }, - { CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED" }, -}; - -static const char * -ckr_to_string(CK_RV rv) { - for (size_t i = 0; i < ARRAY_LEN(ckr_str_map); i++) { - if (ckr_str_map[i].rv == rv) { - return ckr_str_map[i].str; - } - } - - return "unknown error"; -} - -int -tpm2_ec_alg_to_asn1(TPM2_ALGORITHM_ID alg, uint8_t **der) { - int ret = -1; - int nid = NID_undef; - ASN1_OBJECT *obj = NULL; - unsigned char *d = NULL; - int d_len = 0; - - switch (alg) { - case TPM2_ECC_NIST_P192: - nid = NID_X9_62_prime192v1; - break; - case TPM2_ECC_NIST_P224: - nid = NID_secp224r1; - break; - case TPM2_ECC_NIST_P256: - nid = NID_X9_62_prime256v1; - break; - case TPM2_ECC_NIST_P384: - nid = NID_secp384r1; - break; - case TPM2_ECC_NIST_P521: - nid = NID_secp521r1; - break; - default: - PRINT_E("Unsupported TPM EC algorithm: %d", alg); - goto exit; - } - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - PRINT_E("Failed to convert NID to ASN1_OBJECT"); - goto exit; - } - - d_len = i2d_ASN1_OBJECT(obj, &d); - if (!d_len || !d) { - PRINT_E("i2d_ASN1_OBJECT has failed"); - goto exit; - } - - *der = malloc(d_len); - if (!der) { - PRINT_E("calloc has failed"); - goto exit; - } - - memcpy(*der, d, d_len); - - ret = d_len; -exit: - ASN1_OBJECT_free(obj); - OPENSSL_free(d); - return ret; -} - -int -c_initialize(void) { - CK_RV rv; - CK_C_INITIALIZE_ARGS args = { - .CreateMutex = NULL, - .DestroyMutex = NULL, - .LockMutex = NULL, - .UnlockMutex = NULL, - .flags = CKF_LIBRARY_CANT_CREATE_OS_THREADS, - }; - - rv = C_Initialize(&args); - if (rv != CKR_OK) { - PRINT_E("C_Initialize has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -c_finalize(void) { - CK_RV rv; - - rv = C_Finalize(NULL_PTR); - if (rv != CKR_OK && rv != CKR_CRYPTOKI_NOT_INITIALIZED) { - PRINT_E("C_Finalize has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -c_get_info(void) { - CK_RV rv; - CK_INFO info; - - rv = C_GetInfo(&info); - if (rv != CKR_OK) { - PRINT_E("C_GetInfo has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -c_get_slot(CK_SLOT_ID slot_id) { - CK_RV rv; - CK_TOKEN_INFO info = { 0 }; - - rv = C_GetTokenInfo(slot_id, &info); - if (rv != CKR_OK) { - PRINT_E("C_GetTokenInfo has failed: %s", ckr_to_string(rv)); - return 1; - } - - if (info.flags & CKF_TOKEN_INITIALIZED) { - printf("Slot id: %ld\n", slot_id); - - info.label[sizeof(info.label) - 1] = '\0'; - printf("Token label: %s\n", info.label); - - info.manufacturerID[sizeof(info.manufacturerID) - 1] = '\0'; - printf("Token manufacturer id: %s\n", info.manufacturerID); - - info.model[sizeof(info.model) - 1] = '\0'; - printf("Token model: %s\n", info.model); - - info.serialNumber[sizeof(info.serialNumber) - 1] = '\0'; - printf("Token serial number: %s\n", info.serialNumber); - } else { - PRINT_E("Token is not initialized."); - return 1; - } - - return 0; -} - -int -c_open_session(CK_SLOT_ID slot_id, CK_SESSION_HANDLE *session) { - CK_RV rv; - CK_FLAGS flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; - CK_SESSION_HANDLE s = CK_INVALID_HANDLE; - - rv = C_OpenSession(slot_id, flags, NULL, NULL, &s); - if (rv != CKR_OK) { - PRINT_E("C_OpenSession has failed: %s", ckr_to_string(rv)); - return 1; - } - - *session = s; - - return 0; -} - -int -c_close_session(CK_SESSION_HANDLE session) { - CK_RV rv; - - if (session == CK_INVALID_HANDLE) { - return 0; - } - - rv = C_CloseSession(session); - if (rv != CKR_OK) { - PRINT_E("C_CloseSession has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -c_login(CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR user_pin) { - CK_RV rv; - CK_USER_TYPE user_type = CKU_USER; - CK_ULONG user_pin_len = 0; - - if (session == CK_INVALID_HANDLE) { - return 0; - } - - if (user_pin) { - user_pin_len = strlen((char *)user_pin); - } - - rv = C_Login(session, user_type, user_pin, user_pin_len); - if (rv != CKR_OK) { - PRINT_E("C_Login has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -c_generate_keypair(CK_SESSION_HANDLE session, - CK_MECHANISM *mech, - CK_ATTRIBUTE *pub, - CK_ULONG pub_len, - CK_ATTRIBUTE *priv, - CK_ULONG priv_len) { - CK_RV rv; - CK_OBJECT_HANDLE pubkey; - CK_OBJECT_HANDLE privkey; - - rv = C_GenerateKeyPair(session, mech, pub, pub_len, priv, priv_len, &pubkey, &privkey); - if (rv != CKR_OK) { - PRINT_E("C_GenerateKeyPair has failed: %s", ckr_to_string(rv)); - return 1; - } - - return 0; -} - -int -main(int argc, char **argv) { - - int ret = 1; - - /* tpm2-tss variables */ - - TSS2_RC tss2_rc; - TPM2_HANDLE parent_persistent_handle = 0; - TPM2_HANDLE persistent_handle = 0; - ESYS_CONTEXT *esys_ctx = NULL; - TSS2_TCTI_CONTEXT *tcti = NULL; - TPM2B_PUBLIC *key_public = NULL; - TPM2B_PUBLIC pub_tpm2b = { 0 }; - TPM2B_PRIVATE priv_tpm2b = { 0 }; - ESYS_TR parent_esys_tr = 0; - ESYS_TR esys_tr = 0; - TPM2B_DIGEST parent_auth = { 0 }; - unsigned long tpm2_handle = 0; - char *pub_path = NULL; - char *priv_path = NULL; - size_t offset = 0; - - /* PKCS #11 variables */ - - CK_UTF8CHAR_PTR key_label = NULL; - CK_UTF8CHAR_PTR parent_auth_value = NULL; - CK_UTF8CHAR_PTR auth_value = NULL; - CK_ULONG pubkey_attrs_count = 0; - CK_ULONG privkey_attrs_count = 0; - CK_MECHANISM mech - = { .mechanism = CKR_MECHANISM_INVALID, .pParameter = NULL, .ulParameterLen = 0 }; - CK_BBOOL ck_true = CK_TRUE; - CK_ATTRIBUTE pubkey_attrs[4] = { 0 }; - CK_ATTRIBUTE privkey_attrs[5] = { 0 }; - int pub_attrs_ind = 0; - int priv_attrs_ind = 0; - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - CK_SLOT_ID slot_id = 0; - CK_UTF8CHAR_PTR user_pin = NULL; - uint8_t *cka_ec_params = NULL; - int cka_ec_params_len = 0; - - /* getopt variables */ - - int opt; - int opt_index = 0; - const char *short_opts = "A:a:C:c:hk:l:r:s:u:t:"; - static struct option long_opts[] - = { { "key-auth", required_argument, NULL, 'a' }, - { "persistent-handle", required_argument, NULL, 'c' }, - { "help", no_argument, NULL, 'h' }, - { "user-pin", required_argument, NULL, 'k' }, - { "key-label", required_argument, NULL, 'l' }, - { "parent-persistent-handle", required_argument, NULL, 'C' }, - { "parent-auth", required_argument, NULL, 'A' }, - { "private", required_argument, NULL, 'r' }, - { "slot-id", required_argument, NULL, 's' }, - { "public", required_argument, NULL, 'u' }, - { "tcti", required_argument, NULL, 't' }, - { 0, 0, 0, 0 } }; - - /* File reading variables */ - - FILE *pub_f = NULL, *priv_f = NULL; - uint8_t *pub_blob = NULL, *priv_blob = NULL; - size_t pub_sz = 0, priv_sz = 0; - - /* End of local variable declarations */ - - while ((opt = getopt_long(argc, argv, short_opts, long_opts, &opt_index)) != -1) { - switch (opt) { - case 'A': - parent_auth_value = (unsigned char *)optarg; - break; - - case 'a': - auth_value = (unsigned char *)optarg; - break; - - case 'C': - if (strlen(optarg) != 10 || strncmp(optarg, "0x", 2)) { - PRINT_E("Invalid input format. Expecting an 8-character long" - " hexadecimal with the prefix '0x', e.g., 0x81000001."); - goto exit; - } - - parent_persistent_handle = strtol(optarg, NULL, 16); - - if (parent_persistent_handle < TPM2_PERSISTENT_FIRST - || parent_persistent_handle > TPM2_PERSISTENT_LAST) { - PRINT_E("Invalid parent persistent handle. The value must be in the range of " - "0x%08x to 0x%08x.", - TPM2_PERSISTENT_FIRST, TPM2_PERSISTENT_LAST); - goto exit; - } - - break; - - case 'c': - if (strlen(optarg) != 10 || strncmp(optarg, "0x", 2)) { - PRINT_E("Invalid input format. Expecting an 8-character long" - " hexadecimal with the prefix '0x', e.g., 0x81000001."); - goto exit; - } - - persistent_handle = strtol(optarg, NULL, 16); - - if (persistent_handle < TPM2_PERSISTENT_FIRST - || persistent_handle > TPM2_PERSISTENT_LAST) { - PRINT_E("Invalid persistent handle. The value must be in the range of 0x%08x to " - "0x%08x.", - TPM2_PERSISTENT_FIRST, TPM2_PERSISTENT_LAST); - goto exit; - } - - break; - - case 'h': - printf("A TPM key import tool for tpm2-pkcs11 tokens, " - "capable of importing keys as either persistent handles or key objects.\n"); - printf("Usage: key_import []\n"); - printf("Options:\n"); - printf(" -A, --parent-auth The authorization value of the\n"); - printf(" parent key.\n"); - printf(" -a, --key-auth The TPM key's authorization value.\n"); - printf(" -C, --parent-persistent-handle The persistent handle of the parent key\n"); - printf(" to which the key objects are associated.\n"); - printf(" -c, --persistent-handle The persistent handle of the TPM key\n"); - printf(" to be imported.\n"); - printf(" If this option is selected, do not\n"); - printf(" specify -r, -u, -C, or -A.\n"); - printf(" -h, --help Show this help message.\n"); - printf(" -k, --user-pin The PKCS#11 token user PIN.\n"); - printf(" -l, --key-label The PKCS#11 key label to assign to the\n"); - printf(" TPM key.\n"); - printf(" -r, --private A file containing the sensitive portion\n"); - printf(" of the TPM key object. This option is\n"); - printf(" specified alongside -u, -C, and -A.\n"); - printf(" If this option is selected, do not\n"); - printf(" specify -c.\n"); - printf(" -s, --slot-id The PKCS#11 slot ID where the token\n"); - printf(" resides (default is 0).\n"); - printf(" -u, --public A file containing the public portion of\n"); - printf(" the TPM key object. This option is\n"); - printf(" specified alongside -r, -C, and -A.\n"); - printf(" If this option is selected, do not\n"); - printf(" specify -c.\n"); - printf(" -t, --tcti The transmission interface with the TPM.\n"); - - ret = 0; - goto exit; - - case 'k': - user_pin = (unsigned char *)optarg; - break; - - case 'l': - key_label = (unsigned char *)optarg; - break; - - case 'r': - priv_path = optarg; - break; - - case 's': - slot_id = strtol(optarg, NULL, 10); - if (slot_id > MAX_TOKEN_CNT) { - PRINT_E("Slot ID cannot be greater than %d", MAX_TOKEN_CNT); - goto exit; - } - break; - - case 'u': - pub_path = optarg; - break; - - case 't': - tss2_rc = Tss2_TctiLdr_Initialize(optarg, &tcti); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Tcti initialization has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - tss2_rc = Esys_Initialize(&esys_ctx, tcti, NULL); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Esys initialization has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - break; - - case '?': - /* The option is marked as required_argument, but no argument is provided. */ - goto exit; - - default: - /* The option is unrecognized. */ - PRINT_E("Invalid option. Check the command usage by running: %s --help", argv[0]); - goto exit; - } - } - - if (!user_pin || !esys_ctx || !key_label) { - PRINT_E("Missing inputs. Check the command usage by running: %s --help", argv[0]); - goto exit; - } - - if (persistent_handle && pub_path && priv_path && parent_persistent_handle) { - PRINT_E("Ambiguous options detected. Persistent handle and key objects cannot" - " be used together. Check the command usage by running: %s --help", - argv[0]); - goto exit; - } - - ADD_ATTR(&pubkey_attrs[pub_attrs_ind++], CKA_ID, strlen((char *)key_label), key_label); - ADD_ATTR(&pubkey_attrs[pub_attrs_ind++], CKA_LABEL, strlen((char *)key_label), key_label); - - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_ID, strlen((char *)key_label), key_label); - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_LABEL, strlen((char *)key_label), key_label); - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_SENSITIVE, sizeof(ck_true), &ck_true); - if (auth_value) { - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_TPM2_OBJAUTH, strlen((char *)auth_value), - auth_value); - } - - if (persistent_handle) { - - tpm2_handle = persistent_handle; - ADD_ATTR(&pubkey_attrs[pub_attrs_ind++], CKA_TPM2_PERSISTENT_HANDLE, sizeof(tpm2_handle), - &tpm2_handle); - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_TPM2_PERSISTENT_HANDLE, sizeof(tpm2_handle), - &tpm2_handle); - - /* Create the ESYS_TR object from the persistent handle */ - - tss2_rc = Esys_TR_FromTPMPublic(esys_ctx, persistent_handle, ESYS_TR_NONE, ESYS_TR_NONE, - ESYS_TR_NONE, &esys_tr); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Esys_TR_FromTPMPublic has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - } else if (pub_path && priv_path && parent_persistent_handle) { - - /* Read the public and private key blobs */ - - pub_f = fopen(pub_path, "rb"); - if (!pub_f) { - PRINT_E("Could not open the file \"%s\": %s", pub_path, strerror(errno)); - goto exit; - } - - priv_f = fopen(priv_path, "rb"); - if (!priv_f) { - PRINT_E("Could not open the file \"%s\": %s", priv_path, strerror(errno)); - goto exit; - } - - pub_sz = sizeof(TPM2B_PUBLIC); - priv_sz = sizeof(TPM2B_PRIVATE); - pub_blob = calloc(1, pub_sz); - priv_blob = calloc(1, priv_sz); - if (!pub_blob || !priv_blob) { - PRINT_E("calloc has failed"); - goto exit; - } - - pub_sz = fread(pub_blob, 1, sizeof(TPM2B_PUBLIC), pub_f); - if (!feof(pub_f)) { - PRINT_E("Failed to read from pub_f"); - goto exit; - } - - priv_sz = fread(priv_blob, 1, sizeof(TPM2B_PRIVATE), priv_f); - if (!feof(priv_f)) { - PRINT_E("Failed to read from priv_f"); - goto exit; - } - - tss2_rc = Tss2_MU_TPM2B_PUBLIC_Unmarshal(pub_blob, pub_sz, &offset, &pub_tpm2b); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Tss2_MU_PUBLIC_Unmarshal has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - offset = 0; - tss2_rc = Tss2_MU_TPM2B_PRIVATE_Unmarshal(priv_blob, priv_sz, &offset, &priv_tpm2b); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Tss2_MU_PRIVATE_Unmarshal has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - /* Parent authorization */ - - tss2_rc = Esys_TR_FromTPMPublic(esys_ctx, parent_persistent_handle, ESYS_TR_NONE, - ESYS_TR_NONE, ESYS_TR_NONE, &parent_esys_tr); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Esys_TR_FromTPMPublic has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - if (parent_auth_value) { - parent_auth.size = (UINT16)snprintf( - (char *)parent_auth.buffer, sizeof(parent_auth.buffer), "%s", parent_auth_value); - - tss2_rc = Esys_TR_SetAuth(esys_ctx, parent_esys_tr, &parent_auth); - if (tss2_rc != TPM2_RC_SUCCESS) { - PRINT_E("Esys_TR_SetAuth has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - } - - /* Load the child key objects and create the ESYS_TR object */ - - tss2_rc = Esys_Load(esys_ctx, parent_esys_tr, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, - &priv_tpm2b, &pub_tpm2b, &esys_tr); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Esys_Load has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - ADD_ATTR(&pubkey_attrs[pub_attrs_ind++], CKA_TPM2_PUB_BLOB, pub_sz, pub_blob); - ADD_ATTR(&privkey_attrs[priv_attrs_ind++], CKA_TPM2_PRIV_BLOB, priv_sz, priv_blob); - - } else { - PRINT_E("Missing inputs. Check the command usage by running: %s --help", argv[0]); - goto exit; - } - - /* Set the mechanism and ECC attributes */ - - tss2_rc = Esys_ReadPublic(esys_ctx, esys_tr, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, - &key_public, NULL, NULL); - if (tss2_rc != TSS2_RC_SUCCESS) { - PRINT_E("Esys_ReadPublic has failed with: %s", Tss2_RC_Decode(tss2_rc)); - goto exit; - } - - switch (key_public->publicArea.type) { - case TPM2_ALG_RSA: - mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; - break; - case TPM2_ALG_ECC: - mech.mechanism = CKM_EC_KEY_PAIR_GEN; - cka_ec_params_len = tpm2_ec_alg_to_asn1(key_public->publicArea.parameters.eccDetail.curveID, - &cka_ec_params); - if (!cka_ec_params_len || !cka_ec_params) { - goto exit; - } - - ADD_ATTR(&pubkey_attrs[pub_attrs_ind++], CKA_EC_PARAMS, cka_ec_params_len, cka_ec_params); - break; - default: - PRINT_E("The given TPM key type is not supported."); - goto exit; - } - - /* Finalize the public and private key templates */ - - assert(pub_attrs_ind <= ARRAY_LEN(pubkey_attrs)); - assert(priv_attrs_ind <= ARRAY_LEN(privkey_attrs)); - - pubkey_attrs_count = pub_attrs_ind; - privkey_attrs_count = priv_attrs_ind; - - /* Start the key import process */ - - if (c_initialize() || c_get_info() || c_get_slot(slot_id) || c_open_session(slot_id, &session) - || c_login(session, user_pin) - || c_generate_keypair(session, &mech, pubkey_attrs, pubkey_attrs_count, privkey_attrs, - privkey_attrs_count)) { - goto exit_c; - } - - ret = 0; - -exit_c: - c_close_session(session); - c_finalize(); -exit: - pub_f ? fclose(pub_f) : 0; - priv_f ? fclose(priv_f) : 0; - free(cka_ec_params); - free(pub_blob); - free(priv_blob); - esys_ctx ? Esys_Finalize(&esys_ctx) : 0; - tcti ? Tss2_TctiLdr_Finalize(&tcti) : 0; - free(key_public); - return ret; -} diff --git a/tools/tpm2_ptool/setup.py b/tools/setup.py similarity index 100% rename from tools/tpm2_ptool/setup.py rename to tools/setup.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/__init__.py b/tools/tpm2_pkcs11/__init__.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/__init__.py rename to tools/tpm2_pkcs11/__init__.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/command.py b/tools/tpm2_pkcs11/command.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/command.py rename to tools/tpm2_pkcs11/command.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/commandlets_keys.py b/tools/tpm2_pkcs11/commandlets_keys.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/commandlets_keys.py rename to tools/tpm2_pkcs11/commandlets_keys.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/commandlets_store.py b/tools/tpm2_pkcs11/commandlets_store.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/commandlets_store.py rename to tools/tpm2_pkcs11/commandlets_store.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/commandlets_token.py b/tools/tpm2_pkcs11/commandlets_token.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/commandlets_token.py rename to tools/tpm2_pkcs11/commandlets_token.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/db.py b/tools/tpm2_pkcs11/db.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/db.py rename to tools/tpm2_pkcs11/db.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/objects.py b/tools/tpm2_pkcs11/objects.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/objects.py rename to tools/tpm2_pkcs11/objects.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/pkcs11t.py b/tools/tpm2_pkcs11/pkcs11t.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/pkcs11t.py rename to tools/tpm2_pkcs11/pkcs11t.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/tpm2.py b/tools/tpm2_pkcs11/tpm2.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/tpm2.py rename to tools/tpm2_pkcs11/tpm2.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/tpm2_ptool.py b/tools/tpm2_pkcs11/tpm2_ptool.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/tpm2_ptool.py rename to tools/tpm2_pkcs11/tpm2_ptool.py diff --git a/tools/tpm2_ptool/tpm2_pkcs11/utils.py b/tools/tpm2_pkcs11/utils.py similarity index 100% rename from tools/tpm2_ptool/tpm2_pkcs11/utils.py rename to tools/tpm2_pkcs11/utils.py diff --git a/tools/tpm2_ptool/tpm2_ptool b/tools/tpm2_ptool similarity index 100% rename from tools/tpm2_ptool/tpm2_ptool rename to tools/tpm2_ptool diff --git a/tools/tpm2_ptool/tpm2_ptool.py b/tools/tpm2_ptool.py similarity index 100% rename from tools/tpm2_ptool/tpm2_ptool.py rename to tools/tpm2_ptool.py