[go: nahoru, domu]

ESYS: Crypto backend for usage of openssl's libcrypto added.

* The crypto backend can be selected with the option
  --with-crypto={ossl,gcrypt}.The default is gcrypt.
* Only the crypto provider independent code will remain in esys_crypto.{c,h}
  The provider dependent code can be found in:
  esys_crypto_{ossl,cgrypt}.{c,h}
* The provider dependent source files are removed from the lists
  generated in the bootstrap script and are added explicitly
  to the makefile variables in Makefile.am

Signed-off-by: Juergen Repp <Juergen.Repp@sit.fraunhofer.de>
diff --git a/Makefile-test.am b/Makefile-test.am
index 31e7f0c..4eef5b0 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -56,6 +56,15 @@
 test_helper_tpm_transientempty_SOURCES = test/helper/tpm_transientempty.c
 endif #ENABLE_INTEGRATION
 
+if ESYS_OSSL
+ESYSLDFLAGS = -lssl -lcrypto
+ESYSCFLAGS = -DOSSL
+else
+if ESYS_GCRYPT
+ESYSLDFLAGS = -lgcrypt
+endif
+endif
+
 if UNIT
 TESTS_UNIT  = \
     test/unit/CommonPreparePrologue \
@@ -292,32 +301,32 @@
 
 test_unit_esys_resubmissions_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_resubmissions_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_resubmissions_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_resubmissions_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_resubmissions_SOURCES = test/unit/esys-resubmissions.c
 
 test_unit_esys_sequence_finish_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_sequence_finish_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_sequence_finish_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_sequence_finish_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_sequence_finish_SOURCES = test/unit/esys-sequence-finish.c
 
 test_unit_esys_tcti_rcs_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_tcti_rcs_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_tcti_rcs_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_tcti_rcs_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_tcti_rcs_SOURCES = test/unit/esys-tcti-rcs.c
 
 test_unit_esys_tpm_rcs_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_tpm_rcs_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_tpm_rcs_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_tpm_rcs_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_tpm_rcs_SOURCES = test/unit/esys-tpm-rcs.c
 
 test_unit_esys_getpollhandles_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_getpollhandles_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_getpollhandles_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_getpollhandles_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_getpollhandles_SOURCES = test/unit/esys-getpollhandles.c
 
 test_unit_esys_nulltcti_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
 test_unit_esys_nulltcti_LDADD = $(CMOCKA_LIBS)  $(TESTS_LDADD)
-test_unit_esys_nulltcti_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_unit_esys_nulltcti_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_unit_esys_nulltcti_SOURCES = test/unit/esys-nulltcti.c \
         src/tss2-esys/esys_context.c
 endif # ESAPI
@@ -421,77 +430,77 @@
 if ESAPI
 test_integration_esys_audit_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_audit_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_audit_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_audit_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_audit_int_SOURCES = \
     test/integration/esys-audit.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_certify_creation_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_certify_creation_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_certify_creation_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_certify_creation_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_certify_creation_int_SOURCES = \
     test/integration/esys-certify-creation.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_certify_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_certify_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_certify_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_certify_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_certify_int_SOURCES = \
     test/integration/esys-certify.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_change_eps_int_CFLAGS = $(TESTS_CFLAGS)
 test_integration_esys_change_eps_int_LDADD = $(TESTS_LDADD)
-test_integration_esys_change_eps_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_change_eps_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_change_eps_int_SOURCES = \
     test/integration/esys-change-eps.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_clear_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_clear_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_clear_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_clear_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_clear_int_SOURCES = \
     test/integration/esys-clear.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_clear_control_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_clear_control_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_clear_control_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_clear_control_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_clear_control_int_SOURCES = \
     test/integration/esys-clear-control.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_clear_session_int_CFLAGS  = $(TESTS_CFLAGS) -DTEST_SESSION
 test_integration_esys_clear_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_clear_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_clear_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_clear_session_int_SOURCES = \
     test/integration/esys-clear.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_clockset_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_clockset_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_clockset_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_clockset_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_clockset_int_SOURCES = \
     test/integration/esys-clockset.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_commit_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_commit_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_commit_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_commit_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_commit_int_SOURCES = \
     test/integration/esys-commit.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_create_fail_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_create_fail_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_fail_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_fail_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_fail_int_SOURCES = \
     test/integration/esys-create-fail.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_createloaded_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_createloaded_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_createloaded_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_createloaded_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_createloaded_int_SOURCES = \
     test/integration/esys-createloaded.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -499,28 +508,28 @@
 test_integration_esys_createloaded_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_createloaded_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_createloaded_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_createloaded_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_createloaded_session_int_SOURCES = \
     test/integration/esys-createloaded.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_create_password_auth_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_create_password_auth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_password_auth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_password_auth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_password_auth_int_SOURCES = \
     test/integration/esys-create-password-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_create_primary_ecc_hmac_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_create_primary_ecc_hmac_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_primary_ecc_hmac_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_primary_ecc_hmac_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_primary_ecc_hmac_int_SOURCES = \
     test/integration/esys-create-primary-hmac.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_create_primary_hmac_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_create_primary_hmac_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_primary_hmac_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_primary_hmac_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_primary_hmac_int_SOURCES = \
     test/integration/esys-create-primary-hmac.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -528,7 +537,7 @@
 test_integration_esys_create_session_auth_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_AES_ENCRYPTION
 test_integration_esys_create_session_auth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_session_auth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_session_auth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_session_auth_int_SOURCES = \
     test/integration/esys-create-session-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -536,7 +545,7 @@
 test_integration_esys_create_session_auth_bound_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_AES_ENCRYPTION -DTEST_BOUND_SESSIION
 test_integration_esys_create_session_auth_bound_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_session_auth_bound_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_session_auth_bound_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_session_auth_bound_int_SOURCES = \
     test/integration/esys-create-session-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -544,7 +553,7 @@
 test_integration_esys_create_session_auth_ecc_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_AES_ENCRYPTION -DTEST_ECC
 test_integration_esys_create_session_auth_ecc_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_session_auth_ecc_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_session_auth_ecc_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_session_auth_ecc_int_SOURCES = \
     test/integration/esys-create-session-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -552,98 +561,98 @@
 test_integration_esys_create_session_auth_xor_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_XOR_OBFUSCATION
 test_integration_esys_create_session_auth_xor_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_create_session_auth_xor_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_create_session_auth_xor_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_create_session_auth_xor_int_SOURCES = \
     test/integration/esys-create-session-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_duplicate_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_duplicate_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_duplicate_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_duplicate_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_duplicate_int_SOURCES = \
     test/integration/esys-duplicate.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_ecc_parameters_int_CFLAGS = $(TESTS_CFLAGS)
 test_integration_esys_ecc_parameters_int_LDADD = $(TESTS_LDADD)
-test_integration_esys_ecc_parameters_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_ecc_parameters_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_ecc_parameters_int_SOURCES = \
     test/integration/esys-ecc-parameters.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_ecdh_keygen_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_ecdh_keygen_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_ecdh_keygen_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_ecdh_keygen_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_ecdh_keygen_int_SOURCES = \
     test/integration/esys-ecdh-keygen.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_ecdh_zgen_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_ecdh_zgen_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_ecdh_zgen_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_ecdh_zgen_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_ecdh_zgen_int_SOURCES = \
     test/integration/esys-ecdh-zgen.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_encrypt_decrypt_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_encrypt_decrypt_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_encrypt_decrypt_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_encrypt_decrypt_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_encrypt_decrypt_int_SOURCES = \
     test/integration/esys-encrypt-decrypt.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_event_sequence_complete_int_CFLAGS = $(TESTS_CFLAGS)
 test_integration_esys_event_sequence_complete_int_LDADD = $(TESTS_LDADD)
-test_integration_esys_event_sequence_complete_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_event_sequence_complete_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_event_sequence_complete_int_SOURCES = \
     test/integration/esys-event-sequence-complete.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_evict_control_serialization_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_evict_control_serialization_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_evict_control_serialization_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_evict_control_serialization_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_evict_control_serialization_int_SOURCES = \
     test/integration/esys-evict-control-serialization.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_field_upgrade_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_field_upgrade_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_field_upgrade_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_field_upgrade_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_field_upgrade_int_SOURCES = \
     test/integration/esys-field-upgrade.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_firmware_read_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_firmware_read_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_firmware_read_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_firmware_read_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_firmware_read_int_SOURCES = \
     test/integration/esys-firmware-read.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_get_capability_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_get_capability_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_get_capability_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_get_capability_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_get_capability_int_SOURCES = \
     test/integration/esys-get-capability.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_get_random_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_get_random_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_get_random_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_get_random_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_get_random_int_SOURCES = \
     test/integration/esys-get-random.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_get_time_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_get_time_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_get_time_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_get_time_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_get_time_int_SOURCES = \
     test/integration/esys-get-time.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_hashsequencestart_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_hashsequencestart_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hashsequencestart_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hashsequencestart_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hashsequencestart_int_SOURCES = \
     test/integration/esys-hashsequencestart.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -651,21 +660,21 @@
 test_integration_esys_hashsequencestart_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_hashsequencestart_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hashsequencestart_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hashsequencestart_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hashsequencestart_session_int_SOURCES = \
     test/integration/esys-hashsequencestart.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_hierarchy_control_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_hierarchy_control_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hierarchy_control_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hierarchy_control_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hierarchy_control_int_SOURCES = \
     test/integration/esys-hierarchy-control.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_hmacsequencestart_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_hmacsequencestart_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hmacsequencestart_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hmacsequencestart_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hmacsequencestart_int_SOURCES = \
     test/integration/esys-hmacsequencestart.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -673,35 +682,35 @@
 test_integration_esys_hmacsequencestart_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_hmacsequencestart_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hmacsequencestart_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hmacsequencestart_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hmacsequencestart_session_int_SOURCES = \
     test/integration/esys-hmacsequencestart.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_hierarchychangeauth_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_hierarchychangeauth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_hierarchychangeauth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_hierarchychangeauth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_hierarchychangeauth_int_SOURCES = \
     test/integration/esys-hierarchychangeauth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_import_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_import_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_import_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_import_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_import_int_SOURCES = \
     test/integration/esys-import.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_lock_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_lock_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_lock_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_lock_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_lock_int_SOURCES = \
     test/integration/esys-lock.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_make_credential_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_make_credential_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_make_credential_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_make_credential_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_make_credential_int_SOURCES = \
     test/integration/esys-make-credential.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -709,21 +718,21 @@
 test_integration_esys_make_credential_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_make_credential_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_make_credential_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_make_credential_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_make_credential_session_int_SOURCES = \
     test/integration/esys-make-credential.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_nv_certify_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_nv_certify_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_certify_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_certify_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_certify_int_SOURCES = \
     test/integration/esys-nv-certify.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_nv_ram_counter_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_nv_ram_counter_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_counter_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_counter_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_counter_int_SOURCES = \
     test/integration/esys-nv-ram-counter.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -731,14 +740,14 @@
 test_integration_esys_nv_ram_counter_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_nv_ram_counter_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_counter_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_counter_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_counter_session_int_SOURCES = \
     test/integration/esys-nv-ram-counter.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_nv_ram_extend_index_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_nv_ram_extend_index_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_extend_index_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_extend_index_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_extend_index_int_SOURCES = \
     test/integration/esys-nv-ram-extend-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -746,7 +755,7 @@
 test_integration_esys_nv_ram_extend_index_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_nv_ram_extend_index_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_extend_index_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_extend_index_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_extend_index_session_int_SOURCES = \
     test/integration/esys-nv-ram-extend-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -755,7 +764,7 @@
     -I. -I$(srcdir)/src/esapi/esapi -I$(srcdir)/include/esapi -I$(srcdir)/test/integration/ \
     -I$(srcdir)/src/esapi/esapi_util -DTEST_READ_LOCK
 test_integration_esys_nv_ram_ordinary_index_rlock_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_ordinary_index_rlock_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_ordinary_index_rlock_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_ordinary_index_rlock_int_SOURCES = \
     test/integration/esys-nv-ram-ordinary-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -764,7 +773,7 @@
     -I. -I$(srcdir)/src/esapi/esapi -I$(srcdir)/include/esapi -I$(srcdir)/include/esapi \
     -I$(srcdir)/src/esapi/esapi_util -DTEST_SESSION -DTEST_READ_LOCK
 test_integration_esys_nv_ram_ordinary_index_rlock_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_ordinary_index_rlock_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_ordinary_index_rlock_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_ordinary_index_rlock_session_int_SOURCES = \
     test/integration/esys-nv-ram-ordinary-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -773,7 +782,7 @@
     -I. -I$(srcdir)/src/esapi/esapi -I$(srcdir)/include/esapi -I$(srcdir)/include/esapi \
     -I$(srcdir)/src/esapi/esapi_util  -DTEST_WRITE_LOCK
 test_integration_esys_nv_ram_ordinary_index_wlock_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_ordinary_index_wlock_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_ordinary_index_wlock_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_ordinary_index_wlock_int_SOURCES = \
     test/integration/esys-nv-ram-ordinary-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -782,14 +791,14 @@
     -I. -I$(srcdir)/src/esapi/esapi -I$(srcdir)/include/esapi -I$(srcdir)/include/esapi \
     -I$(srcdir)/src/esapi/esapi_util -DTEST_SESSION -DTEST_WRITE_LOCK
 test_integration_esys_nv_ram_ordinary_index_wlock_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_ordinary_index_wlock_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_ordinary_index_wlock_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_ordinary_index_wlock_session_int_SOURCES = \
     test/integration/esys-nv-ram-ordinary-index.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_nv_ram_set_bits_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_nv_ram_set_bits_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_set_bits_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_set_bits_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_set_bits_int_SOURCES = \
     test/integration/esys-nv-ram-set-bits.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
@@ -797,21 +806,21 @@
 test_integration_esys_nv_ram_set_bits_session_int_CFLAGS  = $(TESTS_CFLAGS) \
     -DTEST_SESSION
 test_integration_esys_nv_ram_set_bits_session_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_nv_ram_set_bits_session_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_nv_ram_set_bits_session_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_nv_ram_set_bits_session_int_SOURCES = \
     test/integration/esys-nv-ram-set-bits.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_object_changeauth_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_object_changeauth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_object_changeauth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_object_changeauth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_object_changeauth_int_SOURCES = \
     test/integration/esys-object-changeauth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
-test_integration_esys_policy_authorize_int_CFLAGS  = $(TESTS_CFLAGS)
+test_integration_esys_policy_authorize_int_CFLAGS  = $(TESTS_CFLAGS) $(ESYSCFLAGS)
 test_integration_esys_policy_authorize_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_authorize_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_authorize_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSLDFLAGS)
 test_integration_esys_policy_authorize_int_SOURCES = \
     test/integration/esys-policy-authorize.int.c \
     src/tss2-esys/esys_crypto.c \
@@ -819,14 +828,14 @@
 
 test_integration_esys_policy_regression_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_policy_regression_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_regression_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_regression_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_policy_regression_int_SOURCES = \
     test/integration/esys-policy-regression.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
-test_integration_esys_policy_ticket_int_CFLAGS  = $(TESTS_CFLAGS)
+test_integration_esys_policy_ticket_int_CFLAGS  = $(TESTS_CFLAGS) $(ESYSCFLAGS)
 test_integration_esys_policy_ticket_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_ticket_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_ticket_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_policy_ticket_int_SOURCES = \
     test/integration/esys-policy-ticket.int.c \
     src/tss2-esys/esys_crypto.c \
@@ -834,133 +843,133 @@
 
 test_integration_esys_policy_nv_changeauth_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_policy_nv_changeauth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_nv_changeauth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_nv_changeauth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_policy_nv_changeauth_int_SOURCES = \
     test/integration/esys-policy-nv-changeauth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_policy_nv_undefine_special_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_policy_nv_undefine_special_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_nv_undefine_special_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_nv_undefine_special_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_policy_nv_undefine_special_int_SOURCES = \
     test/integration/esys-policy-nv-undefine-special.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_policy_password_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_policy_password_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_policy_password_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_policy_password_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_policy_password_int_SOURCES = \
     test/integration/esys-policy-password.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_pcr_basic_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_pcr_basic_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_pcr_basic_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_pcr_basic_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_pcr_basic_int_SOURCES = \
     test/integration/esys-pcr-basic.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_pcr_auth_value_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_pcr_auth_value_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_pcr_auth_value_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_pcr_auth_value_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_pcr_auth_value_int_SOURCES = \
     test/integration/esys-pcr-auth-value.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_pp_commands_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_pp_commands_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_pp_commands_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_pp_commands_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_pp_commands_int_SOURCES = \
     test/integration/esys-pp-commands.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_quote_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_quote_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_quote_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_quote_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_quote_int_SOURCES = \
     test/integration/esys-quote.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_rsa_encrypt_decrypt_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_rsa_encrypt_decrypt_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_rsa_encrypt_decrypt_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_rsa_encrypt_decrypt_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_rsa_encrypt_decrypt_int_SOURCES = \
     test/integration/esys-rsa-encrypt-decrypt.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_save_and_load_context_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_save_and_load_context_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_save_and_load_context_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_save_and_load_context_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_save_and_load_context_int_SOURCES = \
     test/integration/esys-save-and-load-context.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_set_algorithm_set_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_set_algorithm_set_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_set_algorithm_set_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_set_algorithm_set_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_set_algorithm_set_int_SOURCES = \
     test/integration/esys-set-algorithm-set.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_stir_random_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_stir_random_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_stir_random_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_stir_random_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_stir_random_int_SOURCES = \
     test/integration/esys-stir-random.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_testparms_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_testparms_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_testparms_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_testparms_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_testparms_int_SOURCES = \
     test/integration/esys-testparms.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_tpm_tests_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_tpm_tests_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_tpm_tests_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_tpm_tests_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_tpm_tests_int_SOURCES = \
     test/integration/esys-tpm-tests.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_tr_fromTpmPublic_key_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_tr_fromTpmPublic_key_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_tr_fromTpmPublic_key_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_tr_fromTpmPublic_key_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_tr_fromTpmPublic_key_int_SOURCES = \
     test/integration/esys-tr-fromTpmPublic-key.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_tr_fromTpmPublic_nv_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_tr_fromTpmPublic_nv_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_tr_fromTpmPublic_nv_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_tr_fromTpmPublic_nv_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_tr_fromTpmPublic_nv_int_SOURCES = \
     test/integration/esys-tr-fromTpmPublic-nv.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_tr_getName_hierarchy_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_tr_getName_hierarchy_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_tr_getName_hierarchy_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_tr_getName_hierarchy_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_tr_getName_hierarchy_int_SOURCES = \
     test/integration/esys-tr-getName-hierarchy.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_unseal_password_auth_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_unseal_password_auth_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_unseal_password_auth_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_unseal_password_auth_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_unseal_password_auth_int_SOURCES = \
     test/integration/esys-unseal-password-auth.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_verify_signature_int_CFLAGS  = $(TESTS_CFLAGS)
 test_integration_esys_verify_signature_int_LDADD   = $(TESTS_LDADD)
-test_integration_esys_verify_signature_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_verify_signature_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_verify_signature_int_SOURCES = \
     test/integration/esys-verify-signature.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
 
 test_integration_esys_zgen_2phase_int_CFLAGS = $(TESTS_CFLAGS)
 test_integration_esys_zgen_2phase_int_LDADD = $(TESTS_LDADD)
-test_integration_esys_zgen_2phase_int_LDFLAGS = $(TESTS_LDFLAGS) -lgcrypt
+test_integration_esys_zgen_2phase_int_LDFLAGS = $(TESTS_LDFLAGS) $(ESYSFLAGS)
 test_integration_esys_zgen_2phase_int_SOURCES = \
     test/integration/esys-zgen-2phase.int.c \
     test/integration/main-esapi.c test/integration/test-esapi.h
diff --git a/Makefile.am b/Makefile.am
index d78d23f..39bf7d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -284,10 +284,21 @@
 nodist_pkgconfig_DATA += lib/tss2-esys.pc
 EXTRA_DIST += lib/tss2-esys.pc.in
 
-src_tss2_esys_libtss2_esys_la_CFLAGS  = $(AM_CFLAGS) -I$(srcdir)/src/tss2-esys
+
 src_tss2_esys_libtss2_esys_la_LIBADD  = $(libtss2_sys) $(libtss2_mu) \
     $(libtss2_tcti_device) $(libtss2_tcti_mssim) $(libutil)
+
+if ESYS_OSSL
+TSS2_ESYS_SRC += src/tss2-esys/esys_crypto_ossl.h src/tss2-esys/esys_crypto_ossl.c
+src_tss2_esys_libtss2_esys_la_CFLAGS  = $(AM_CFLAGS) -I$(srcdir)/src/tss2-esys -DOSSL
+src_tss2_esys_libtss2_esys_la_LDFLAGS = $(AM_LDFLAGS) -ldl  -lssl -lcrypto
+else
+if ESYS_GCRYPT
+TSS2_ESYS_SRC += src/tss2-esys/esys_crypto_gcrypt.h src/tss2-esys/esys_crypto_gcrypt.c
+src_tss2_esys_libtss2_esys_la_CFLAGS  = $(AM_CFLAGS) -I$(srcdir)/src/tss2-esys
 src_tss2_esys_libtss2_esys_la_LDFLAGS = $(AM_LDFLAGS) -ldl -lgcrypt
+endif
+endif
 src_tss2_esys_libtss2_esys_la_SOURCES = $(TSS2_ESYS_SRC)
 
 endif #ESAPI
diff --git a/bootstrap b/bootstrap
index 7c627f4..d20ba7f 100755
--- a/bootstrap
+++ b/bootstrap
@@ -12,6 +12,35 @@
     echo ""
 }
 
+# remove source files from list if their usage depends on a configure option
+remove_src () {
+    files=$1
+    shift
+    for x in $*
+    do
+      x=$(echo "$x" | sed 's/\//\\\//g')
+      files=$(echo $files | sed -e "s/$x//")
+    done
+    echo $files
+}
+
+# generate list of eys source files for use in Makefile.am
+# if you add new source files, you must run ./bootstrap again
+# files after the var name will be elimenated from list list
+src_esys_listvar () {
+    basedir=$1;
+    shift;
+    suffix=$1
+    shift;
+    var=$1
+    shift;
+
+    files=$(find "${basedir}" -name "${suffix}" | LC_ALL=C sort | tr '\n' ' ')
+    files=$(remove_src "${files}" $*)
+    printf "${var} = ${files}"
+    echo ""
+}
+
 VARS_FILE=src_vars.mk
 AUTORECONF=${AUTORECONF:-autoreconf}
 
@@ -25,8 +54,8 @@
   src_listvar "src/tss2-sys/" "*.h" "TSS2_SYS_H"
   printf "TSS2_SYS_SRC = \$(TSS2_SYS_H) \$(TSS2_SYS_C)\n"
 
-  src_listvar "src/tss2-esys/" "*.h" "TSS2_ESYS_H"
-  src_listvar "src/tss2-esys/" "*.c" "TSS2_ESYS_C"
+  src_esys_listvar "src/tss2-esys/" "*.h" "TSS2_ESYS_H"  src/tss2-esys/esys_crypto_ossl.h  src/tss2-esys/esys_crypto_gcrypt.h
+  src_esys_listvar "src/tss2-esys/" "*.c" "TSS2_ESYS_C" src/tss2-esys/esys_crypto_ossl.c  src/tss2-esys/esys_crypto_gcrypt.c
   printf "TSS2_ESYS_SRC = \$(TSS2_ESYS_H) \$(TSS2_ESYS_C)\n"
 
   src_listvar "src/tss2-mu" "*.c" "TSS2_MU_C"
diff --git a/configure.ac b/configure.ac
index c8aa314..d70fd69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-#;**********************************************************************;
+;**********************************************************************;
 # Copyright (c) 2015 - 2018 Intel Corporation
 # Copyright (c) 2018 Fraunhofer SIT sponsored by Infineon Technologies AG
 # All rights reserved.
@@ -63,16 +63,48 @@
                             [build the esapi layer (default is yes)])],
             [enable_esapi=$enableval],
             [enable_esapi=yes])
-AS_IF([test "x$enable_esapi" != xno],
+
+
+AC_ARG_ENABLE([esapi], 
+    AS_HELP_STRING([--disable-esapi], [Enable TSS ESYS API library @<:@default=yes@:>@]),
+    [],
+    [enable_esapi="yes"])
+AM_CONDITIONAL(ESAPI, test "x$enable_esapi" = "xyes")
+
+AC_ARG_WITH([crypto],
+            [AS_HELP_STRING([--with-crypto={gcrypt,ossl}],
+                            [sets the ESAPI crypto backend (default is gcrypt)])],
+            [],
+            [with_crypto=gcrypt])
+
+AM_CONDITIONAL(ESYS_OSSL, test "x$with_crypto" = "xossl")
+AM_CONDITIONAL(ESYS_GCRYPT, test "x$with_crypto" = "xgcrypt")
+
+AS_IF([test "x$with_crypto" != "xgcrypt"],
+    AS_IF([test "x$with_crypto" != "xossl"],
+          AC_MSG_ERROR([Bad value for --with-crypto $with_crypto])))
+
+AS_IF([test "x$enable_esapi" != xno -a "x$with_crypto" = "xgcrypt"],
       [AC_CHECK_HEADER([gcrypt.h],
                        [],
                        [AC_MSG_ERROR([Missing required header: gcrypt.h.])])])
-AS_IF([test "x$enable_esapi" != xno],
+
+AS_IF([test "x$enable_esapi" != xno -a "x$with_cryptor" = "xgcrypt"],
       [AC_CHECK_LIB([gcrypt],
                     [gcry_mac_open],
                     [],
                     [AC_MSG_ERROR([Missing required library: gcrypt.])])])
-AM_CONDITIONAL([ESAPI], [test "x$enable_esapi" != xno])
+
+AS_IF([test "x$enable_esapi" != xno -a "x$with_crypto" = "xossl"],
+      [AC_CHECK_HEADER([openssl/ssl.h],
+                       [],
+                       [AC_MSG_ERROR([Missing required header: openssl/ssl.h.])])])
+
+AS_IF([test "x$enable_esapi" != xno -a "x$with_crypto" = "xossl"],
+    AC_CHECK_LIB(ssl, OPENSSL_init_ssl, [FOUND_SSL_LIB="yes"]))
+
+AS_IF([test "x$enable_esapi" != xno -a "x$with_crypto" = "xossl"],
+    AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]))
 
 AC_ARG_WITH([tctidefaultmodule],
             [AS_HELP_STRING([--with-tctidefaultmodule],
diff --git a/doc/doxygen.dox b/doc/doxygen.dox
index 6335893..096a60d 100644
--- a/doc/doxygen.dox
+++ b/doc/doxygen.dox
@@ -1036,7 +1036,7 @@
  \fn TSS2_RC iesys_cryptogcry_pk_encrypt( TPM2B_PUBLIC *key, size_t in_size, BYTE *in_buffer, size_t max_out_size, BYTE *out_buffer, size_t *out_size, const char *label)
  \fn TSS2_RC iesys_crypto_KDFaHmac( TPM2_ALG_ID alg, uint8_t *hmacKey, size_t hmacKeySize, uint32_t counter, const char *label, TPM2B_NONCE *contextU, TPM2B_NONCE *contextV, uint32_t bitlength, uint8_t *hmac, size_t *hmacSize)
  \fn TSS2_RC iesys_crypto_KDFa( TPM2_ALG_ID hashAlg, uint8_t *hmacKey, size_t hmacKeySize, const char *label, TPM2B_NONCE *contextU, TPM2B_NONCE *contextV, uint32_t bitLength, uint32_t *counterInOut, BYTE *outKey, BOOL use_digest_size)
- \fn TSS2_RC iesys_cryptogcry_KDFe( TPM2_ALG_ID hashAlg, TPM2B_ECC_PARAMETER *Z, const char *label, TPM2B_ECC_PARAMETER *partyUInfo, TPM2B_ECC_PARAMETER *partyVInfo, UINT32 bit_size, BYTE *key)
+ \fn TSS2_RC iesys_crypto_KDFe( TPM2_ALG_ID hashAlg, TPM2B_ECC_PARAMETER *Z, const char *label, TPM2B_ECC_PARAMETER *partyUInfo, TPM2B_ECC_PARAMETER *partyVInfo, UINT32 bit_size, BYTE *key)
  \fn TSS2_RC iesys_cryptogcry_sym_aes_encrypt( uint8_t *key, TPM2_ALG_ID tpm_sym_alg, TPMI_AES_KEY_BITS key_bits, TPM2_ALG_ID tpm_mode, size_t blk_len, uint8_t *dst, size_t dst_size, uint8_t *iv)
  \fn TSS2_RC iesys_cryptogcry_sym_aes_decrypt( uint8_t *key, TPM2_ALG_ID tpm_sym_alg, TPMI_AES_KEY_BITS key_bits, TPM2_ALG_ID tpm_mode, size_t blk_len, uint8_t *dst, size_t dst_size, uint8_t *iv)
  \fn TSS2_RC iesys_xor_parameter_obfuscation( TPM2_ALG_ID hash_alg, uint8_t *key, size_t key_size, TPM2B_NONCE * contextU, TPM2B_NONCE * contextV, BYTE *data, size_t data_size)
diff --git a/src/tss2-esys/esys_crypto.c b/src/tss2-esys/esys_crypto.c
index 6a02e52..08bfb3e 100644
--- a/src/tss2-esys/esys_crypto.c
+++ b/src/tss2-esys/esys_crypto.c
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: BSD-2 */
 /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
  * All rights reserved.
- *******************************************************************************/
+ ******************************************************************************/
 
 #define _GNU_SOURCE
 
@@ -17,26 +17,6 @@
 #define LOGMODULE esys
 #include "util/log.h"
 
-/** Context to hold temporary values for iesys_crypto */
-typedef struct _IESYS_CRYPTO_CONTEXT {
-    enum {
-        IESYS_CRYPTOGCRY_TYPE_HASH = 1,
-        IESYS_CRYPTOGCRY_TYPE_HMAC,
-    } type; /**< The type of context to hold; hash or hmac */
-    union {
-        struct {
-            gcry_md_hd_t gcry_context;
-            int gcry_hash_alg;
-            size_t hash_len;
-        } hash; /**< the state variables for a hash context */
-        struct {
-            gcry_mac_hd_t gcry_context;
-            int gcry_hmac_alg;
-            size_t hmac_len;
-        } hmac; /**< the state variables for an hmac context */
-    };
-} IESYS_CRYPTOGCRY_CONTEXT;
-
 /** Provide the digest size for a given hash algorithm.
  *
  * This function provides the size of the digest for a given hash algorithm.
@@ -78,485 +58,6 @@
     return TSS2_RC_SUCCESS;
 }
 
-/** Provide the context for the computation of a hash digest.
- *
- * The context will be created and initialized according to the hash function.
- * @param[out] context The created context (callee-allocated).
- * @param[in] hashAlg The hash algorithm for the creation of the context.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_VALUE or TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
-                            TPM2_ALG_ID hashAlg)
-{
-    LOG_TRACE("call: context=%p hashAlg=%"PRIu16, context, hashAlg);
-    return_if_null(context, "Context is NULL", TSS2_ESYS_RC_BAD_REFERENCE);
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext;
-    mycontext = calloc(1, sizeof(IESYS_CRYPTOGCRY_CONTEXT));
-    return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
-    mycontext->type = IESYS_CRYPTOGCRY_TYPE_HASH;
-
-    switch (hashAlg) {
-    case TPM2_ALG_SHA1:
-        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA1;
-        break;
-    case TPM2_ALG_SHA256:
-        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA256;
-        break;
-    case TPM2_ALG_SHA384:
-        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA384;
-        break;
-    default:
-        LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", hashAlg);
-        free(mycontext);
-        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
-    }
-    int hash_len = gcry_md_get_algo_dlen(mycontext->hash.gcry_hash_alg);
-    if (hash_len <= 0) {
-        LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", hashAlg);
-        free(mycontext);
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    mycontext->hash.hash_len = hash_len;
-
-    gcry_error_t r = gcry_md_open(&mycontext->hash.gcry_context,
-                                  mycontext->hash.gcry_hash_alg, 0);
-    if (r != 0) {
-        LOG_ERROR("GCry error.");
-        free(mycontext);
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    if (context == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Update the digest value of a digest object from a byte buffer.
- *
- * The context of a digest object will be updated according to the hash
- * algorithm of the context.
- * @param[in,out] context The context of the digest object which will be updated.
- * @param[in] buffer The data for the update.
- * @param[in] size The size of the data buffer.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- */
-TSS2_RC
-iesys_cryptogcry_hash_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
-                             const uint8_t * buffer, size_t size)
-{
-    LOG_TRACE("called for context %p, buffer %p and size %zd", context, buffer,
-              size);
-    if (context == NULL || buffer == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext = (IESYS_CRYPTOGCRY_CONTEXT *) context;
-    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
-        LOG_ERROR("bad context");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    LOGBLOB_TRACE(buffer, size, "Updating hash with");
-
-    gcry_md_write(mycontext->hash.gcry_context, buffer, size);
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Update the digest value of a digest object from a TPM2B object.
- *
- * The context of a digest object will be updated according to the hash
- * algorithm of the context.
- * @param[in,out] context The context of the digest object which will be updated.
- * @param[in] b The TPM2B object for the update.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- */
-TSS2_RC
-iesys_cryptogcry_hash_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
-{
-    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
-    if (context == NULL || b == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    TSS2_RC ret = iesys_cryptogcry_hash_update(context, &b->buffer[0], b->size);
-    return ret;
-}
-
-/** Get the digest value of a digest object and close the context.
- *
- * The digest value will written to a passed buffer and the resources of the
- * digest object are released.
- * @param[in,out] context The context of the digest object to be released
- * @param[out] buffer The buffer for the digest value (caller-allocated).
- * @param[out] size The size of the digest.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hash_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
-                             uint8_t * buffer, size_t * size)
-{
-    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
-              context, buffer, size);
-    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext = * context;
-    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
-        LOG_ERROR("bad context");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    if (*size < mycontext->hash.hash_len) {
-        LOG_ERROR("Buffer too small");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    uint8_t *cpHash = gcry_md_read(mycontext->hash.gcry_context,
-                                   mycontext->hash.gcry_hash_alg);
-    if (cpHash == NULL) {
-        LOG_ERROR("GCry error.");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    LOGBLOB_TRACE(cpHash, mycontext->hash.hash_len, "read hash result");
-
-    *size = mycontext->hash.hash_len;
-    memmove(buffer, cpHash, *size);
-
-    gcry_md_close(mycontext->hash.gcry_context);
-
-    free(mycontext);
-    *context = NULL;
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Get the digest value of a digest object and close the context.
- *
- * The digest value will written to a passed TPM2B object and the
- * digest object are released.
- * @param[in,out] context The context of the digest object to be released
- * @param[out] b The TPM2B object for the digest (caller-allocated).
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hash_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * b)
-{
-    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
-    if (context == NULL || *context == NULL || b == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    size_t s = b->size;
-    TSS2_RC ret = iesys_cryptogcry_hash_finish(context, &b->buffer[0], &s);
-    b->size = s;
-    return ret;
-}
-
-/** Release the resources of a digest object.
- *
- * The assigned resources will be released and the context will be set to NULL.
- * @param[in,out] context The context of the digest object.
- */
-void
-iesys_cryptogcry_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
-{
-    LOG_TRACE("called for context-pointer %p", context);
-    if (context == NULL || *context == NULL) {
-        LOG_DEBUG("Null-Pointer passed");
-        return;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
-        (IESYS_CRYPTOGCRY_CONTEXT *) * context;
-    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
-        LOG_DEBUG("bad context");
-        return;
-    }
-
-    gcry_md_close(mycontext->hash.gcry_context);
-    free(mycontext);
-    *context = NULL;
-}
-
-/* HMAC */
-
-/** Provide the context an HMAC digest object from a byte buffer key.
- *
- * The context will be created and initialized according to the hash function
- * and the used HMAC key.
- * @param[out] context The created context (callee-allocated).
- * @param[in] hmacAlg The hash algorithm for the HMAC computation.
- * @param[in] key The byte buffer of the HMAC key.
- * @param[in] size The size of the HMAC key.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
-                            TPM2_ALG_ID hmacAlg,
-                            const uint8_t * key, size_t size)
-{
-    TSS2_RC r;
-
-    LOG_TRACE("called for context-pointer %p and hmacAlg %d", context, hmacAlg);
-    LOGBLOB_TRACE(key, size, "Starting  hmac with");
-    if (context == NULL || key == NULL) {
-        LOG_ERROR("Null-Pointer passed in for context");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
-        calloc(1, sizeof(IESYS_CRYPTOGCRY_CONTEXT));
-    if (mycontext == NULL) {
-        LOG_ERROR("Out of Memory");
-        return TSS2_ESYS_RC_MEMORY;
-    }
-
-    switch (hmacAlg) {
-    case TPM2_ALG_SHA1:
-        mycontext->hmac.gcry_hmac_alg = GCRY_MAC_HMAC_SHA1;
-        break;
-    case TPM2_ALG_SHA256:
-        mycontext->hmac.gcry_hmac_alg = GCRY_MAC_HMAC_SHA256;
-        break;
-    default:
-        LOG_ERROR("Unsupported hmac algo.");
-        free(mycontext);
-        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
-    }
-
-    int hmac_len = gcry_mac_get_algo_maclen(mycontext->hmac.gcry_hmac_alg);
-    if (hmac_len <= 0) {
-        LOG_ERROR("GCry error.");
-        free(mycontext);
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    mycontext->type = IESYS_CRYPTOGCRY_TYPE_HMAC;
-    mycontext->hmac.hmac_len = hmac_len;
-
-    r = gcry_mac_open(&mycontext->hmac.gcry_context,
-                      mycontext->hmac.gcry_hmac_alg, 0, NULL);
-    if (r != 0) {
-        LOG_ERROR("GCry error.");
-        free(mycontext);
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    r = gcry_mac_setkey(mycontext->hmac.gcry_context, key, size);
-    if (r != 0) {
-        LOG_ERROR("GCry error.");
-        gcry_mac_close(mycontext->hmac.gcry_context);
-        free(mycontext);
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Provide the context an HMAC digest object from a byte TPM2B key.
- *
- * The context will be created and initialized according to the hash function
- * and the used HMAC key.
- * @param[out] context The created context.
- * @param[in] hmacAlg The hash algorithm for the HMAC computation.
- * @param[in] key The TPM2B object of the HMAC key.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_start2b(IESYS_CRYPTO_CONTEXT_BLOB ** context,
-                              TPM2_ALG_ID hmacAlg, TPM2B * key)
-{
-    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, key);
-    if (context == NULL || key == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    TSS2_RC ret = iesys_cryptogcry_hmac_start(context, hmacAlg, &key->buffer[0],
-                                              key->size);
-    return ret;
-}
-
-/** Update and HMAC digest value from a byte buffer.
- *
- * The context of a digest object will be updated according to the hash
- * algorithm and the key of the context.
- * @param[in,out] context The context of the digest object which will be updated.
- * @param[in] buffer The data for the update.
- * @param[in] size The size of the data buffer.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
-                             const uint8_t * buffer, size_t size)
-{
-    LOG_TRACE("called for context %p, buffer %p and size %zd",
-              context, buffer, size);
-    if (context == NULL || buffer == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext = (IESYS_CRYPTOGCRY_CONTEXT *) context;
-    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
-        LOG_ERROR("bad context");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    LOGBLOB_TRACE(buffer, size, "Updating hmac with");
-
-    gcry_mac_write(mycontext->hmac.gcry_context, buffer, size);
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Update and HMAC digest value from a TPM2B object.
- *
- * The context of a digest object will be updated according to the hash
- * algorithm and the key of the context.
- * @param[in,out] context The context of the digest object which will be updated.
- * @param[in] b The TPM2B object for the update.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
-{
-    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
-    if (context == NULL || b == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    TSS2_RC ret = iesys_cryptogcry_hmac_update(context, &b->buffer[0], b->size);
-    return ret;
-}
-
-/** Write the HMAC digest value to a byte buffer and close the context.
- *
- * The digest value will written to a passed buffer and the resources of the
- * HMAC object are released.
- * @param[in,out] context The context of the HMAC object.
- * @param[out] buffer The buffer for the digest value (caller-allocated).
- * @param[out] size The size of the digest.
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_BAD_SIZE If the size passed is lower than the HMAC length.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
-                             uint8_t * buffer, size_t * size)
-{
-    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
-              context, buffer, size);
-    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
-        (IESYS_CRYPTOGCRY_CONTEXT *) * context;
-    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
-        LOG_ERROR("bad context");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    if (*size < mycontext->hmac.hmac_len) {
-        LOG_ERROR("Buffer too small");
-        return TSS2_ESYS_RC_BAD_SIZE;
-    }
-
-    TSS2_RC r = gcry_mac_read(mycontext->hmac.gcry_context, buffer, size);
-    if (r != 0) {
-        LOG_ERROR("GCry error.");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    LOGBLOB_TRACE(buffer, *size, "read hmac result");
-
-    gcry_mac_close(mycontext->hmac.gcry_context);
-
-    free(mycontext);
-    *context = NULL;
-
-    return TSS2_RC_SUCCESS;
-}
-
-/** Write the HMAC digest value to a TPM2B object and close the context.
- *
- * The digest value will written to a passed TPM2B object and the resources of
- * the HMAC object are released.
- * @param[in,out] context The context of the HMAC object.
- * @param[out] hmac The buffer for the digest value (caller-allocated).
- * @retval TSS2_RC_SUCCESS on success.
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
- * @retval TSS2_ESYS_RC_BAD_SIZE if the size passed is lower than the HMAC length.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_hmac_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * hmac)
-{
-    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, hmac);
-    if (context == NULL || *context == NULL || hmac == NULL) {
-        LOG_ERROR("Null-Pointer passed");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-    size_t s = hmac->size;
-    TSS2_RC ret = iesys_cryptogcry_hmac_finish(context, &hmac->buffer[0], &s);
-    hmac->size = s;
-    return ret;
-}
-
-/** Release the resources of an HAMC object.
- *
- * The assigned resources will be released and the context will be set to NULL.
- * @param[in,out] context The context of the HMAC object.
- */
-void
-iesys_cryptogcry_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
-{
-    LOG_TRACE("called for context-pointer %p", context);
-    if (context == NULL || *context == NULL) {
-        LOG_DEBUG("Null-Pointer passed");
-        return;
-    }
-    if (*context != NULL) {
-        IESYS_CRYPTOGCRY_CONTEXT *mycontext =
-            (IESYS_CRYPTOGCRY_CONTEXT *) * context;
-        if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
-            LOG_DEBUG("bad context");
-            return;
-        }
-
-        gcry_mac_close(mycontext->hmac.gcry_context);
-
-        free(mycontext);
-        *context = NULL;
-    }
-}
-
 /** Compute the command or response parameter hash.
  *
  * These hashes are needed for the computation of the HMAC used for the
@@ -855,7 +356,8 @@
      /* Fill outKey with results from KDFaHmac */
     for (; bytes > 0; subKey = &subKey[hlen], bytes = bytes - hlen) {
         LOG_TRACE("IESYS KDFa hmac key bytes: %i", bytes);
-        /* if (bytes < (INT32)hlen) hlen = bytes; */
+        //if(bytes < (INT32)hlen)
+        //    hlen = bytes;
         counter++;
         r = iesys_crypto_KDFaHmac(hashAlg, hmacKey,
                                   hmacKeySize, counter, label, contextU,
@@ -870,29 +372,6 @@
     return TPM2_RC_SUCCESS;
 }
 
-/** Compute random TPM2B data.
- *
- * The random data will be generated and written to a passed TPM2B structure.
- * @param[out] nonce The TPM2B structure for the random data (caller-allocated).
- * @param[in] num_bytes The number of bytes to be generated.
- * @retval TSS2_RC_SUCCESS on success.
- */
-TSS2_RC
-iesys_cryptogcry_random2b(TPM2B_NONCE * nonce, size_t num_bytes)
-{
-    if (num_bytes == 0) {
-        nonce->size = sizeof(TPMU_HA);
-    } else {
-        nonce->size = num_bytes;
-    }
-    /*
-     * possible values for random level:
-     *  GCRY_WEAK_RANDOM GCRY_STRONG_RANDOM  GCRY_VERY_STRONG_RANDOM
-     */
-    gcry_randomize(&nonce->buffer[0], nonce->size, GCRY_STRONG_RANDOM);
-    return TSS2_RC_SUCCESS;
-}
-
 /** Compute KDFe as described in TPM spec part 1 C 6.1
  *
  * @param hashAlg [in] The nameAlg of the recipient key.
@@ -908,13 +387,13 @@
  * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
  */
 TSS2_RC
-iesys_cryptogcry_KDFe(TPM2_ALG_ID hashAlg,
-                      TPM2B_ECC_PARAMETER *Z,
-                      const char *label,
-                      TPM2B_ECC_PARAMETER *partyUInfo,
-                      TPM2B_ECC_PARAMETER *partyVInfo,
-                      UINT32 bit_size,
-                      BYTE *key)
+iesys_crypto_KDFe(TPM2_ALG_ID hashAlg,
+                  TPM2B_ECC_PARAMETER *Z,
+                  const char *label,
+                  TPM2B_ECC_PARAMETER *partyUInfo,
+                  TPM2B_ECC_PARAMETER *partyVInfo,
+                  UINT32 bit_size,
+                  BYTE *key)
 {
     TSS2_RC r = TSS2_RC_SUCCESS;
     size_t hash_len;
@@ -927,13 +406,10 @@
 
     LOG_DEBUG("IESYS KDFe hashAlg: %i label: %s bitLength: %i",
               hashAlg, label, bit_size);
-
     if (partyUInfo != NULL)
         LOGBLOB_DEBUG(&partyUInfo->buffer[0], partyUInfo->size, "partyUInfo");
-
     if (partyVInfo != NULL)
         LOGBLOB_DEBUG(&partyVInfo->buffer[0], partyVInfo->size, "partyVInfo");
-
     r = iesys_crypto_hash_get_digest_size(hashAlg, &hash_len);
     return_if_error(r, "Hash algorithm not supported.");
 
@@ -989,502 +465,6 @@
     return r;
 }
 
-/** Encryption of a buffer using a public (RSA) key.
- *
- * Encrypting a buffer using a public key is used for example during
- * Esys_StartAuthSession in order to encrypt the salt value.
- * @param[in] key The key to be used for encryption.
- * @param[in] in_size The size of the buffer to be encrypted.
- * @param[in] in_buffer The data buffer to be encrypted.
- * @param[in] max_out_size The maximum size for the output encrypted buffer.
- * @param[out] out_buffer The encrypted buffer.
- * @param[out] out_size The size of the encrypted output.
- * @param[in] label The label used in the encryption scheme.
- * @retval TSS2_RC_SUCCESS on success
- * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
- */
-TSS2_RC
-iesys_cryptogcry_pk_encrypt(TPM2B_PUBLIC * key,
-                            size_t in_size,
-                            BYTE * in_buffer,
-                            size_t max_out_size,
-                            BYTE * out_buffer,
-                            size_t * out_size, const char *label)
-{
-    TSS2_RC r;
-    gcry_error_t err;
-    char *hash_alg;
-    size_t lsize = 0;
-    BYTE exponent[4] = { 0x00, 0x01, 0x00, 0x01 };
-    char *padding;
-    gcry_sexp_t sexp_data, sexp_key, sexp_cipher, sexp_cipher_a;
-    if (label != NULL)
-        lsize = strlen(label) + 1;
-    switch (key->publicArea.nameAlg) {
-    case TPM2_ALG_SHA1:
-        hash_alg = "sha1";
-        break;
-    case TPM2_ALG_SHA256:
-        hash_alg = "sha256";
-        break;
-    default:
-        LOG_ERROR("Hash alg not implemented");
-        return TSS2_ESYS_RC_BAD_VALUE;
-    }
-    switch (key->publicArea.parameters.rsaDetail.scheme.scheme) {
-    case TPM2_ALG_NULL:
-        padding = "raw";
-        break;
-    case TPM2_ALG_RSAES:
-        padding = "pkcs1";
-        break;
-    case TPM2_ALG_OAEP:
-        padding = "oaep";
-        break;
-    default:
-        LOG_ERROR("Illegal RSA scheme");
-        return TSS2_ESYS_RC_BAD_VALUE;
-    }
-    size_t offset = 0;
-    r = Tss2_MU_UINT32_Marshal(key->publicArea.parameters.rsaDetail.exponent,
-                               &exponent[0], sizeof(UINT32), &offset);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Marsahling");
-        return r;
-    }
-    err = gcry_sexp_build(&sexp_data, NULL,
-                          "(data (flags %s) (hash-algo %s) (label %b) (value %b) )",
-                          padding, hash_alg, lsize, label, (int)in_size,
-                          in_buffer);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_sexp_build");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    err = gcry_sexp_build(&sexp_key, NULL, "(public-key (rsa (n %b) (e %b)))",
-                          (int)key->publicArea.unique.rsa.size,
-                          &key->publicArea.unique.rsa.buffer[0], 4, exponent);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_sexp_build");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    err = gcry_pk_encrypt(&sexp_cipher, sexp_data, sexp_key);
-    if (err != GPG_ERR_NO_ERROR) {
-        fprintf (stderr, "Failure: %s/%s\n",
-                 gcry_strsource (err),
-                 gcry_strerror (err));
-        LOG_ERROR("Function gcry_pk_encrypt");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    sexp_cipher_a = gcry_sexp_find_token(sexp_cipher, "a", 0);
-    gcry_mpi_t mpi_cipher =
-        gcry_sexp_nth_mpi(sexp_cipher_a, 1, GCRYMPI_FMT_USG);
-    err = gcry_mpi_print(GCRYMPI_FMT_USG, &out_buffer[0], max_out_size,
-                         out_size, mpi_cipher);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_mpi_print");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    free(sexp_data);
-    free(sexp_key);
-    free(sexp_cipher);
-    free(sexp_cipher_a);
-    return TSS2_RC_SUCCESS;
-}
-
-/** Computation of ephemeral ECC key and shared secret Z.
- *
- * According to the description in  TPM spec part 1 C 6.1 a shared secret
- * between application and TPM is computed (ECDH). An ephemeral ECC key and a
- * TPM keyare used for the ECDH key exchange.
- * @param[in] key The key to be used for ECDH key exchange.
- * @param[in] max_out_size the max size for the output of the public key of the
- *            computed ephemeral key.
- * @param[out] Z The computed shared secret.
- * @param[out] Q The public part of the ephemeral key in TPM format.
- * @param[out] out_buffer The public part of the ephemeral key will be marshaled
- *             to this buffer.
- * @param[out] out_size The size of the marshaled output.
- * @retval TSS2_RC_SUCCESS on success
- * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
- */
-TSS2_RC
-iesys_cryptogcry_get_ecdh_point(TPM2B_PUBLIC *key,
-                                size_t max_out_size,
-                                TPM2B_ECC_PARAMETER *Z,
-                                TPMS_ECC_POINT *Q,
-                                BYTE * out_buffer,
-                                size_t * out_size)
-{
-/*
- * Format strings for some gcrypt sexps have to be created with sprintf due to
- * a bug in libgcrypt. %s does not work in libgcypt with these sexps.
- */
-#define SEXP_GENKEY_ECC  "(genkey (ecc (curve %s)))"
-#define SEXP_ECC_POINT "(ecc (curve %s) (q.x  %sb) (q.y %sb))"
-
-    TSS2_RC r;
-    char *curveId;
-    gcry_sexp_t mpi_tpm_sq = NULL;     /* sexp for public part of TPM  key*/
-    gcry_sexp_t mpi_sd = NULL;         /* sexp for private part of ephemeral key */
-    gcry_sexp_t mpi_s_pub_q = NULL;    /* sexp for public part of ephemeral key */
-    gcry_mpi_point_t mpi_q = NULL;     /* public point of ephemeral key */
-    gcry_mpi_point_t mpi_tpm_q = NULL; /* public point of TPM key */
-    gcry_mpi_t mpi_d = NULL;           /* private part of ephemeral key */
-    gcry_mpi_point_t mpi_qd = NULL;    /* result of mpi_tpm_q * mpi_d */
-    gcry_ctx_t ctx = NULL;             /* context for ec curves */
-    size_t size_x, size_y;
-    size_t offset = 0;
-    gcry_mpi_t mpi_x = gcry_mpi_new(521);  /* big number for x coordinate */
-    gcry_mpi_t mpi_y = gcry_mpi_new(521);  /* big number for y coordinate */
-
-    /* Set libcrypt constant fo curve type */
-    switch (key->publicArea.parameters.eccDetail.curveID) {
-    case TPM2_ECC_NIST_P192:
-        curveId = "\"NIST P-192\"";
-        break;
-    case TPM2_ECC_NIST_P224:
-        curveId = "\"NIST P-224\"";
-        break;
-    case TPM2_ECC_NIST_P256:
-        curveId = "\"NIST P-256\"";
-        break;
-    case TPM2_ECC_NIST_P384:
-        curveId = "\"NIST P-384\"";
-        break;
-    case TPM2_ECC_NIST_P521:
-        curveId = "\"NIST P-521\"";
-        break;
-    default:
-        LOG_ERROR("Illegal ECC curve ID");
-        return TSS2_ESYS_RC_BAD_VALUE;
-    }
-
-    /* compute ephemeral ecc key */
-    gcry_sexp_t ekey_spec = NULL, ekey_pair = NULL;
-    { /* scope for sexp_ecc_key */
-        char sexp_ecc_key [sizeof(SEXP_GENKEY_ECC)+strlen(curveId)
-                           -1];  /* -1 = (-2 for %s +1 for \0) */
-
-        if (sprintf(&sexp_ecc_key[0], SEXP_GENKEY_ECC, curveId) < 1) {
-            goto_error(r, TSS2_ESYS_RC_MEMORY, "asprintf", cleanup);
-        }
-
-        if (gcry_sexp_build(&ekey_spec, NULL,
-                            sexp_ecc_key) != GPG_ERR_NO_ERROR) {
-            goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "gcry_sexp_build", cleanup);
-        }
-    }
-
-    if (gcry_pk_genkey (&ekey_pair, ekey_spec) != GPG_ERR_NO_ERROR) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create ephemeral ecc key",
-                   cleanup);
-    }
-
-    /* Get private ephemeral key d  */
-    mpi_sd = gcry_sexp_find_token(ekey_pair, "d", 0);
-    if (mpi_sd == NULL) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
-                   "Get private part of ecc key", cleanup);
-    }
-    mpi_d = gcry_sexp_nth_mpi(mpi_sd, 1, GCRYMPI_FMT_USG);
-    if (mpi_d == NULL) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
-                   "Get private part of ecc key from sexp", cleanup);
-    }
-
-    /* Construct ephemeral public key */
-    mpi_s_pub_q = gcry_sexp_find_token(ekey_pair, "public-key", 0);
-    if (mpi_s_pub_q == NULL) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get public part ecc key",
-                   cleanup);
-    }
-
-    if (gcry_mpi_ec_new (&ctx, mpi_s_pub_q, curveId) != GPG_ERR_NO_ERROR) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create ec", cleanup);
-    }
-    mpi_q =  gcry_mpi_ec_get_point ("q", ctx, 1);
-    if (mpi_q == NULL) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get ecc point", cleanup);
-    }
-
-    /* Check whether point is on curve */
-    if (!gcry_mpi_ec_curve_point(mpi_q, ctx)) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Point not on curve", cleanup);
-    }
-
-    /* Store ephemeral public key in Q */
-    if (gcry_mpi_ec_get_affine (mpi_x, mpi_y, mpi_q, ctx)) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Point is at infinity",
-                   cleanup);
-    }
-
-    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Q->x.buffer[0], max_out_size,
-                       &size_x, mpi_x) != GPG_ERR_NO_ERROR) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get x part of point",
-                   cleanup);
-    }
-
-    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Q->y.buffer[0], max_out_size,
-                       &size_y, mpi_y) != GPG_ERR_NO_ERROR) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get y part of point",
-                   cleanup);
-    }
-    Q->x.size = size_x;
-    Q->y.size = size_y;
-    SAFE_FREE(ctx);
-    { /* scope for sexp_point */
-
-        /* Get public point from TPM key */
-        char sexp_point [sizeof(SEXP_ECC_POINT) + strlen(curveId)
-                         + key->publicArea.unique.ecc.x.size
-                         + key->publicArea.unique.ecc.y.size
-                         - 5];  /* -1 = (-4 for 2*%sb -2 for %s +1 for \0) */
-
-        if (sprintf(&sexp_point[0], SEXP_ECC_POINT,
-                    curveId, "%", "%") <1 ) {
-            goto_error(r, TSS2_ESYS_RC_MEMORY, "asprintf", cleanup);
-        }
-
-        if ( gcry_sexp_build(&mpi_tpm_sq, NULL,
-                              sexp_point,
-                              key->publicArea.unique.ecc.x.size,
-                              &key->publicArea.unique.ecc.x.buffer[0],
-                              key->publicArea.unique.ecc.y.size,
-                             &key->publicArea.unique.ecc.y.buffer[0])) {
-            goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
-                       "Function gcry_mpi_scan", cleanup);
-
-        }
-    }
-    offset = 0;
-    r = Tss2_MU_TPMS_ECC_POINT_Marshal(Q,  &out_buffer[0], max_out_size, &offset);
-    return_if_error(r, "Error marshaling");
-    *out_size = offset;
-
-    /* Multiply d and Q */
-    if (gcry_mpi_ec_new (&ctx, mpi_tpm_sq, curveId)) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "create ec curve", cleanup);
-    }
-    mpi_tpm_q =  gcry_mpi_ec_get_point ("q", ctx, 1);
-    mpi_qd = gcry_mpi_point_new(256);
-    gcry_mpi_ec_mul(mpi_qd , mpi_d, mpi_tpm_q, ctx);
-
-    /* Store the x coordinate of d*Q in Z which will be used for KDFe */
-    if (gcry_mpi_ec_get_affine (mpi_x, mpi_y, mpi_qd, ctx)) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
-                   "Point is at infinity", cleanup);
-    }
-
-    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Z->buffer[0], TPM2_MAX_ECC_KEY_BYTES,
-                       &size_x, mpi_x)) {
-        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
-                   "Get x coordinate d*Q", cleanup);
-    }
-
-    Z->size = size_x;
-    LOGBLOB_DEBUG(&Z->buffer[0], size_x, "Z (Q*d)");
-
- cleanup:
-    SAFE_FREE(ctx);
-    SAFE_FREE(mpi_x);
-    SAFE_FREE(mpi_y);
-    SAFE_FREE(mpi_tpm_q);
-    SAFE_FREE(mpi_qd);
-    SAFE_FREE(mpi_q);
-    SAFE_FREE(mpi_tpm_q);
-    SAFE_FREE(mpi_tpm_sq);
-    SAFE_FREE(ekey_spec);
-    SAFE_FREE(mpi_s_pub_q);
-
-    return r;
-}
-
-/** Initialize AES context for encryption / decryption.
- *
- * @param[out] handle for AES context
- * @param[in] key key used for AES.
- * @param[in] tpm_sym_alg AES type in TSS2 notation.
- * @param[in] key_bits Key size in bits.
- * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CBC or CFB).
- * @param[in] iv_len Length of initialization vector (iv) in byte.
- * @param[in] iv The initialization vector.
- * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE for invalid
- *         parameters, TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto
- *         library.
- */
-TSS2_RC
-iesys_cryptogcry_sym_aes_init(gcry_cipher_hd_t * cipher_hd,
-                              uint8_t * key,
-                              TPM2_ALG_ID tpm_sym_alg,
-                              TPMI_AES_KEY_BITS key_bits,
-                              TPM2_ALG_ID tpm_mode,
-                              size_t iv_len, uint8_t * iv)
-{
-
-    LOGBLOB_TRACE(key, (key_bits + 7) / 8, "IESYS AES key");
-    LOGBLOB_TRACE(iv, iv_len, "IESYS AES iv");
-    int algo, mode, len;
-    size_t key_len = 0;
-    gcry_error_t err;
-    switch (tpm_sym_alg) {
-    case TPM2_ALG_AES:
-        switch (key_bits) {
-        case 128:
-            algo = GCRY_CIPHER_AES128;
-            len = 128;
-            break;
-        case 192:
-            algo = GCRY_CIPHER_AES192;
-            len = 192;
-            break;
-        case 256:
-            algo = GCRY_CIPHER_AES256;
-            len = 256;
-            break;
-        default:
-            LOG_ERROR("Illegal key length.");
-            return TSS2_ESYS_RC_BAD_VALUE;
-        }
-        switch (tpm_mode) {
-        case TPM2_ALG_CBC:
-            mode = GCRY_CIPHER_MODE_CBC;
-            break;
-        case TPM2_ALG_CFB:
-            mode = GCRY_CIPHER_MODE_CFB;
-            break;
-        default:
-            LOG_ERROR("Illegal symmetric algorithm.");
-            return TSS2_ESYS_RC_BAD_VALUE;
-        }
-        break;
-    default:
-        LOG_ERROR("Illegal symmetric algorithm.");
-        return TSS2_ESYS_RC_BAD_VALUE;
-    }
-    key_len = (len + 7) / 8;
-    err = gcry_cipher_open(cipher_hd, algo, mode, 0);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Opening gcrypt context");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    if (iv_len != 0) {
-        err = gcry_cipher_setiv(*cipher_hd, &iv[0], iv_len);
-        if (err != GPG_ERR_NO_ERROR) {
-            LOG_ERROR("Function gcry_cipher_setiv");
-            return TSS2_ESYS_RC_GENERAL_FAILURE;
-        }
-    }
-    err = gcry_cipher_setkey(*cipher_hd, key, key_len);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_cipher_setkey");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    return TSS2_RC_SUCCESS;
-}
-
-/** Encrypt data with AES.
- *
- * @param[in] key key used for AES.
- * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
- * @param[in] key_bits Key size in bits.
- * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CBC or CFB).
- * @param[in] blk_len Length Block length of AES.
- * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored
- *                in this buffer.
- * @param[in] buffer_size size of data to be encrypted.
- * @param[in] iv The initialization vector. The size is equal to blk_len.
- * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_sym_aes_encrypt(uint8_t * key,
-                                 TPM2_ALG_ID tpm_sym_alg,
-                                 TPMI_AES_KEY_BITS key_bits,
-                                 TPM2_ALG_ID tpm_mode,
-                                 size_t blk_len,
-                                 uint8_t * buffer,
-                                 size_t buffer_size,
-                                 uint8_t * iv)
-{
-    gcry_cipher_hd_t cipher_hd;
-    gcry_error_t err;
-    TSS2_RC r;
-
-    if (key == NULL || buffer == NULL) {
-        LOG_ERROR("Bad reference");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    r = iesys_cryptogcry_sym_aes_init(&cipher_hd, key, tpm_sym_alg,
-                                      key_bits, tpm_mode, blk_len, iv);
-    if (r != TSS2_RC_SUCCESS)
-        return r;
-    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input");
-    err = gcry_cipher_encrypt(cipher_hd, buffer, buffer_size, NULL, 0);
-    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output");
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_cipher_encrypt");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    gcry_cipher_close(cipher_hd);
-    return TSS2_RC_SUCCESS;
-}
-
-/** Decrypt data with AES.
- *
- * @param[in] key key used for AES.
- * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
- * @param[in] key_bits Key size in bits.
- * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CBC or CFB).
- * @param[in] blk_len Length Block length of AES.
- * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored
- *                in this buffer.
- * @param[in] buffer_size size of data to be encrypted.
- * @param[in] iv The initialization vector. The size is equal to blk_len.
- * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
- * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
- * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
- */
-TSS2_RC
-iesys_cryptogcry_sym_aes_decrypt(uint8_t * key,
-                                 TPM2_ALG_ID tpm_sym_alg,
-                                 TPMI_AES_KEY_BITS key_bits,
-                                 TPM2_ALG_ID tpm_mode,
-                                 size_t blk_len,
-                                 uint8_t * buffer,
-                                 size_t buffer_size,
-                                 uint8_t * iv)
-{
-    gcry_cipher_hd_t cipher_hd;
-    gcry_error_t err;
-    TSS2_RC r;
-
-    if (tpm_sym_alg != TPM2_ALG_AES) {
-        LOG_ERROR("AES expected");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-
-    if (key == NULL || buffer == NULL) {
-        LOG_ERROR("Bad reference");
-        return TSS2_ESYS_RC_BAD_REFERENCE;
-    }
-
-    r = iesys_cryptogcry_sym_aes_init(&cipher_hd, key, tpm_sym_alg,
-                                      key_bits, tpm_mode, blk_len, iv);
-    if (r != TSS2_RC_SUCCESS)
-        return r;
-    err = gcry_cipher_decrypt(cipher_hd, buffer, buffer_size, NULL, 0);
-    if (err != GPG_ERR_NO_ERROR) {
-        LOG_ERROR("Function gcry_cipher_decrypt");
-        return TSS2_ESYS_RC_GENERAL_FAILURE;
-    }
-    gcry_cipher_close(cipher_hd);
-    return TSS2_RC_SUCCESS;
-}
-
 /** Encryption/Decryption using XOR obfuscation.
  *
  * The application of this function to data encrypted with this function will
diff --git a/src/tss2-esys/esys_crypto.h b/src/tss2-esys/esys_crypto.h
index 468744b..e3a6f7a 100644
--- a/src/tss2-esys/esys_crypto.h
+++ b/src/tss2-esys/esys_crypto.h
@@ -1,14 +1,19 @@
 /* SPDX-License-Identifier: BSD-2 */
 /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
  * All rights reserved.
- *******************************************************************************/
+ ******************************************************************************/
 #ifndef ESYS_CRYPTO_H
 #define ESYS_CRYPTO_H
 
 #include <stddef.h>
 #include "tss2_tpm2_types.h"
 #include "tss2-sys/sysapi_util.h"
+#ifdef OSSL
+#include "esys_crypto_ossl.h"
+#else
+#include "esys_crypto_gcrypt.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -16,80 +21,8 @@
 
 #define AES_BLOCK_SIZE_IN_BYTES 16
 
-typedef struct _IESYS_CRYPTO_CONTEXT IESYS_CRYPTO_CONTEXT_BLOB;
-
 TSS2_RC iesys_crypto_hash_get_digest_size(TPM2_ALG_ID hashAlg, size_t *size);
 
-
-TSS2_RC iesys_cryptogcry_hash_start(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    TPM2_ALG_ID hashAlg);
-
-TSS2_RC iesys_cryptogcry_hash_update(
-    IESYS_CRYPTO_CONTEXT_BLOB *context,
-    const uint8_t *buffer, size_t size);
-
-TSS2_RC iesys_cryptogcry_hash_update2b(
-    IESYS_CRYPTO_CONTEXT_BLOB *context,
-    TPM2B *b);
-
-TSS2_RC iesys_cryptogcry_hash_finish(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    uint8_t *buffer,
-    size_t *size);
-
-TSS2_RC iesys_cryptogcry_hash_finish2b(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    TPM2B *b);
-
-void iesys_cryptogcry_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
-
-#define iesys_crypto_hash_start iesys_cryptogcry_hash_start
-#define iesys_crypto_hash_update iesys_cryptogcry_hash_update
-#define iesys_crypto_hash_update2b iesys_cryptogcry_hash_update2b
-#define iesys_crypto_hash_finish iesys_cryptogcry_hash_finish
-#define iesys_crypto_hash_finish2b iesys_cryptogcry_hash_finish2b
-#define iesys_crypto_hash_abort iesys_cryptogcry_hash_abort
-
-TSS2_RC iesys_cryptogcry_hmac_start(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    TPM2_ALG_ID hmacAlg,
-    const uint8_t *key,
-    size_t size);
-
-TSS2_RC iesys_cryptogcry_hmac_start2b(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    TPM2_ALG_ID hmacAlg,
-    TPM2B *b);
-
-TSS2_RC iesys_cryptogcry_hmac_update(
-    IESYS_CRYPTO_CONTEXT_BLOB *context,
-    const uint8_t *buffer,
-    size_t size);
-
-TSS2_RC iesys_cryptogcry_hmac_update2b(
-    IESYS_CRYPTO_CONTEXT_BLOB *context,
-    TPM2B *b);
-
-TSS2_RC iesys_cryptogcry_hmac_finish(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    uint8_t *buffer,
-    size_t *size);
-
-TSS2_RC iesys_cryptogcry_hmac_finish2b(
-    IESYS_CRYPTO_CONTEXT_BLOB **context,
-    TPM2B *b);
-
-void iesys_cryptogcry_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
-
-#define iesys_crypto_hmac_start iesys_cryptogcry_hmac_start
-#define iesys_crypto_hmac_start2b iesys_cryptogcry_hmac_start2b
-#define iesys_crypto_hmac_update iesys_cryptogcry_hmac_update
-#define iesys_crypto_hmac_update2b iesys_cryptogcry_hmac_update2b
-#define iesys_crypto_hmac_finish iesys_cryptogcry_hmac_finish
-#define iesys_crypto_hmac_finish2b iesys_cryptogcry_hmac_finish2b
-#define iesys_crypto_hmac_abort iesys_cryptogcry_hmac_abort
-
 TSS2_RC iesys_crypto_pHash(
     TPM2_ALG_ID alg,
     const uint8_t rcBuffer[4],
@@ -125,21 +58,6 @@
     TPMA_SESSION sessionAttributes,
     TPM2B_AUTH *hmac);
 
-TSS2_RC iesys_cryptogcry_random2b(TPM2B_NONCE *nonce, size_t num_bytes);
-#define iesys_crypto_random2b iesys_cryptogcry_random2b
-
-TSS2_RC iesys_cryptogcry_pk_encrypt(
-    TPM2B_PUBLIC *key,
-    size_t in_size,
-    BYTE *in_buffer,
-    size_t max_out_size,
-    BYTE *out_buffer,
-    size_t *out_size,
-    const char *label);
-
-#define iesys_crypto_pk_encrypt iesys_cryptogcry_pk_encrypt
-
-
 TSS2_RC iesys_crypto_KDFaHmac(
     TPM2_ALG_ID alg,
     uint8_t *hmacKey,
@@ -164,35 +82,6 @@
     BYTE *outKey,
     BOOL use_digest_size);
 
-TSS2_RC iesys_cryptogcry_KDFe(
-    TPM2_ALG_ID hashAlg,
-    TPM2B_ECC_PARAMETER *Z,
-    const char *label,
-    TPM2B_ECC_PARAMETER *partyUInfo,
-    TPM2B_ECC_PARAMETER *partyVInfo,
-    UINT32 bit_size,
-    BYTE *key);
-
-TSS2_RC iesys_cryptogcry_sym_aes_encrypt(
-    uint8_t *key,
-    TPM2_ALG_ID tpm_sym_alg,
-    TPMI_AES_KEY_BITS key_bits,
-    TPM2_ALG_ID tpm_mode,
-    size_t blk_len,
-    uint8_t *dst,
-    size_t dst_size,
-    uint8_t *iv);
-
-TSS2_RC iesys_cryptogcry_sym_aes_decrypt(
-    uint8_t *key,
-    TPM2_ALG_ID tpm_sym_alg,
-    TPMI_AES_KEY_BITS key_bits,
-    TPM2_ALG_ID tpm_mode,
-    size_t blk_len,
-    uint8_t *dst,
-    size_t dst_size,
-    uint8_t *iv);
-
 TSS2_RC iesys_xor_parameter_obfuscation(
     TPM2_ALG_ID hash_alg,
     uint8_t *key,
@@ -202,17 +91,14 @@
     BYTE *data,
     size_t data_size);
 
-TSS2_RC iesys_cryptogcry_get_ecdh_point(
-    TPM2B_PUBLIC * key,
-    size_t max_out_size,
+TSS2_RC iesys_crypto_KDFe(
+    TPM2_ALG_ID hashAlg,
     TPM2B_ECC_PARAMETER *Z,
-    TPMS_ECC_POINT *Q,
-    BYTE * out_buffer,
-    size_t * out_size);
-
-#define iesys_crypto_get_ecdh_point iesys_cryptogcry_get_ecdh_point
-#define iesys_crypto_sym_aes_encrypt iesys_cryptogcry_sym_aes_encrypt
-#define iesys_crypto_sym_aes_decrypt iesys_cryptogcry_sym_aes_decrypt
+    const char *label,
+    TPM2B_ECC_PARAMETER *partyUInfo,
+    TPM2B_ECC_PARAMETER *partyVInfo,
+    UINT32 bit_size,
+    BYTE *key);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/src/tss2-esys/esys_crypto_gcrypt.c b/src/tss2-esys/esys_crypto_gcrypt.c
new file mode 100644
index 0000000..abf8f6f
--- /dev/null
+++ b/src/tss2-esys/esys_crypto_gcrypt.c
@@ -0,0 +1,1036 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+
+#define _GNU_SOURCE
+
+#include <gcrypt.h>
+#include <stdio.h>
+
+#include "tss2_esys.h"
+
+#include "esys_crypto.h"
+#include "esys_iutil.h"
+#include "esys_mu.h"
+#define LOGMODULE esys
+#include "util/log.h"
+
+/** Context to hold temporary values for iesys_crypto */
+typedef struct _IESYS_CRYPTO_CONTEXT {
+    enum {
+        IESYS_CRYPTOGCRY_TYPE_HASH = 1,
+        IESYS_CRYPTOGCRY_TYPE_HMAC,
+    } type; /**< The type of context to hold; hash or hmac */
+    union {
+        struct {
+            gcry_md_hd_t gcry_context;
+            int gcry_hash_alg;
+            size_t hash_len;
+        } hash; /**< the state variables for a hash context */
+        struct {
+            gcry_mac_hd_t gcry_context;
+            int gcry_hmac_alg;
+            size_t hmac_len;
+        } hmac; /**< the state variables for an hmac context */
+    };
+} IESYS_CRYPTOGCRY_CONTEXT;
+
+/** Provide the context for the computation of a hash digest.
+ *
+ * The context will be created and initialized according to the hash function.
+ * @param[out] context The created context (callee-allocated).
+ * @param[in] hashAlg The hash algorithm for the creation of the context.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_VALUE or TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                            TPM2_ALG_ID hashAlg)
+{
+    LOG_TRACE("call: context=%p hashAlg=%"PRIu16, context, hashAlg);
+    return_if_null(context, "Context is NULL", TSS2_ESYS_RC_BAD_REFERENCE);
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext;
+    mycontext = calloc(1, sizeof(IESYS_CRYPTOGCRY_CONTEXT));
+    return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
+    mycontext->type = IESYS_CRYPTOGCRY_TYPE_HASH;
+
+    switch (hashAlg) {
+    case TPM2_ALG_SHA1:
+        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA1;
+        break;
+    case TPM2_ALG_SHA256:
+        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA256;
+        break;
+    case TPM2_ALG_SHA384:
+        mycontext->hash.gcry_hash_alg = GCRY_MD_SHA384;
+        break;
+    default:
+        LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", hashAlg);
+        free(mycontext);
+        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
+    }
+    int hash_len = gcry_md_get_algo_dlen(mycontext->hash.gcry_hash_alg);
+    if (hash_len <= 0) {
+        LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", hashAlg);
+        free(mycontext);
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    mycontext->hash.hash_len = hash_len;
+
+    gcry_error_t r = gcry_md_open(&mycontext->hash.gcry_context,
+                                  mycontext->hash.gcry_hash_alg, 0);
+    if (r != 0) {
+        LOG_ERROR("GCry error.");
+        free(mycontext);
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    if (context == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Update the digest value of a digest object from a byte buffer.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] buffer The data for the update.
+ * @param[in] size The size of the data buffer.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptogcry_hash_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
+                             const uint8_t * buffer, size_t size)
+{
+    LOG_TRACE("called for context %p, buffer %p and size %zd", context, buffer,
+              size);
+    if (context == NULL || buffer == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext = (IESYS_CRYPTOGCRY_CONTEXT *) context;
+    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    LOGBLOB_TRACE(buffer, size, "Updating hash with");
+
+    gcry_md_write(mycontext->hash.gcry_context, buffer, size);
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Update the digest value of a digest object from a TPM2B object.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] b The TPM2B object for the update.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptogcry_hash_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptogcry_hash_update(context, &b->buffer[0], b->size);
+    return ret;
+}
+
+/** Get the digest value of a digest object and close the context.
+ *
+ * The digest value will written to a passed buffer and the resources of the
+ * digest object are released.
+ * @param[in,out] context The context of the digest object to be released
+ * @param[out] buffer The buffer for the digest value (caller-allocated).
+ * @param[out] size The size of the digest.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hash_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                             uint8_t * buffer, size_t * size)
+{
+    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
+              context, buffer, size);
+    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext = * context;
+    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (*size < mycontext->hash.hash_len) {
+        LOG_ERROR("Buffer too small");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    uint8_t *cpHash = gcry_md_read(mycontext->hash.gcry_context,
+                                   mycontext->hash.gcry_hash_alg);
+    if (cpHash == NULL) {
+        LOG_ERROR("GCry error.");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    LOGBLOB_TRACE(cpHash, mycontext->hash.hash_len, "read hash result");
+
+    *size = mycontext->hash.hash_len;
+    memmove(buffer, cpHash, *size);
+
+    gcry_md_close(mycontext->hash.gcry_context);
+
+    free(mycontext);
+    *context = NULL;
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Get the digest value of a digest object and close the context.
+ *
+ * The digest value will written to a passed TPM2B object and the
+ * digest object are released.
+ * @param[in,out] context The context of the digest object to be released
+ * @param[out] b The TPM2B object for the digest (caller-allocated).
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hash_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || *context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    size_t s = b->size;
+    TSS2_RC ret = iesys_cryptogcry_hash_finish(context, &b->buffer[0], &s);
+    b->size = s;
+    return ret;
+}
+
+/** Release the resources of a digest object.
+ *
+ * The assigned resources will be released and the context will be set to NULL.
+ * @param[in,out] context The context of the digest object.
+ */
+void
+iesys_cryptogcry_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
+{
+    LOG_TRACE("called for context-pointer %p", context);
+    if (context == NULL || *context == NULL) {
+        LOG_DEBUG("Null-Pointer passed");
+        return;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
+        (IESYS_CRYPTOGCRY_CONTEXT *) * context;
+    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HASH) {
+        LOG_DEBUG("bad context");
+        return;
+    }
+
+    gcry_md_close(mycontext->hash.gcry_context);
+    free(mycontext);
+    *context = NULL;
+}
+
+/* HMAC */
+
+/** Provide the context an HMAC digest object from a byte buffer key.
+ *
+ * The context will be created and initialized according to the hash function
+ * and the used HMAC key.
+ * @param[out] context The created context (callee-allocated).
+ * @param[in] hmacAlg The hash algorithm for the HMAC computation.
+ * @param[in] key The byte buffer of the HMAC key.
+ * @param[in] size The size of the HMAC key.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                            TPM2_ALG_ID hmacAlg,
+                            const uint8_t * key, size_t size)
+{
+    TSS2_RC r;
+
+    LOG_TRACE("called for context-pointer %p and hmacAlg %d", context, hmacAlg);
+    LOGBLOB_TRACE(key, size, "Starting  hmac with");
+    if (context == NULL || key == NULL) {
+        LOG_ERROR("Null-Pointer passed in for context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
+        calloc(1, sizeof(IESYS_CRYPTOGCRY_CONTEXT));
+    if (mycontext == NULL) {
+        LOG_ERROR("Out of Memory");
+        return TSS2_ESYS_RC_MEMORY;
+    }
+
+    switch (hmacAlg) {
+    case TPM2_ALG_SHA1:
+        mycontext->hmac.gcry_hmac_alg = GCRY_MAC_HMAC_SHA1;
+        break;
+    case TPM2_ALG_SHA256:
+        mycontext->hmac.gcry_hmac_alg = GCRY_MAC_HMAC_SHA256;
+        break;
+    default:
+        LOG_ERROR("Unsupported hmac algo.");
+        free(mycontext);
+        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
+    }
+
+    int hmac_len = gcry_mac_get_algo_maclen(mycontext->hmac.gcry_hmac_alg);
+    if (hmac_len <= 0) {
+        LOG_ERROR("GCry error.");
+        free(mycontext);
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    mycontext->type = IESYS_CRYPTOGCRY_TYPE_HMAC;
+    mycontext->hmac.hmac_len = hmac_len;
+
+    r = gcry_mac_open(&mycontext->hmac.gcry_context,
+                      mycontext->hmac.gcry_hmac_alg, 0, NULL);
+    if (r != 0) {
+        LOG_ERROR("GCry error.");
+        free(mycontext);
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    r = gcry_mac_setkey(mycontext->hmac.gcry_context, key, size);
+    if (r != 0) {
+        LOG_ERROR("GCry error.");
+        gcry_mac_close(mycontext->hmac.gcry_context);
+        free(mycontext);
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Provide the context an HMAC digest object from a byte TPM2B key.
+ *
+ * The context will be created and initialized according to the hash function
+ * and the used HMAC key.
+ * @param[out] context The created context.
+ * @param[in] hmacAlg The hash algorithm for the HMAC computation.
+ * @param[in] key The TPM2B object of the HMAC key.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_start2b(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                              TPM2_ALG_ID hmacAlg, TPM2B * key)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, key);
+    if (context == NULL || key == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptogcry_hmac_start(context, hmacAlg, &key->buffer[0],
+                                              key->size);
+    return ret;
+}
+
+/** Update and HMAC digest value from a byte buffer.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm and the key of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] buffer The data for the update.
+ * @param[in] size The size of the data buffer.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
+                             const uint8_t * buffer, size_t size)
+{
+    LOG_TRACE("called for context %p, buffer %p and size %zd",
+              context, buffer, size);
+    if (context == NULL || buffer == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext = (IESYS_CRYPTOGCRY_CONTEXT *) context;
+    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    LOGBLOB_TRACE(buffer, size, "Updating hmac with");
+
+    if (GPG_ERR_NO_ERROR != gcry_mac_write(mycontext->hmac.gcry_context, buffer, size)) {
+        return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "Gcrypt hmac update");
+    }
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Update and HMAC digest value from a TPM2B object.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm and the key of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] b The TPM2B object for the update.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptogcry_hmac_update(context, &b->buffer[0], b->size);
+    return ret;
+}
+
+/** Write the HMAC digest value to a byte buffer and close the context.
+ *
+ * The digest value will written to a passed buffer and the resources of the
+ * HMAC object are released.
+ * @param[in,out] context The context of the HMAC object.
+ * @param[out] buffer The buffer for the digest value (caller-allocated).
+ * @param[out] size The size of the digest.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_BAD_SIZE If the size passed is lower than the HMAC length.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                             uint8_t * buffer, size_t * size)
+{
+    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
+              context, buffer, size);
+    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOGCRY_CONTEXT *mycontext =
+        (IESYS_CRYPTOGCRY_CONTEXT *) * context;
+    if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (*size < mycontext->hmac.hmac_len) {
+        LOG_ERROR("Buffer too small");
+        return TSS2_ESYS_RC_BAD_SIZE;
+    }
+
+    TSS2_RC r = gcry_mac_read(mycontext->hmac.gcry_context, buffer, size);
+    if (r != 0) {
+        LOG_ERROR("GCry error.");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    LOGBLOB_TRACE(buffer, *size, "read hmac result");
+
+    gcry_mac_close(mycontext->hmac.gcry_context);
+
+    free(mycontext);
+    *context = NULL;
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Write the HMAC digest value to a TPM2B object and close the context.
+ *
+ * The digest value will written to a passed TPM2B object and the resources of
+ * the HMAC object are released.
+ * @param[in,out] context The context of the HMAC object.
+ * @param[out] hmac The buffer for the digest value (caller-allocated).
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_BAD_SIZE if the size passed is lower than the HMAC length.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_hmac_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * hmac)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, hmac);
+    if (context == NULL || *context == NULL || hmac == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    size_t s = hmac->size;
+    TSS2_RC ret = iesys_cryptogcry_hmac_finish(context, &hmac->buffer[0], &s);
+    hmac->size = s;
+    return ret;
+}
+
+/** Release the resources of an HAMC object.
+ *
+ * The assigned resources will be released and the context will be set to NULL.
+ * @param[in,out] context The context of the HMAC object.
+ */
+void
+iesys_cryptogcry_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
+{
+    LOG_TRACE("called for context-pointer %p", context);
+    if (context == NULL || *context == NULL) {
+        LOG_DEBUG("Null-Pointer passed");
+        return;
+    }
+    if (*context != NULL) {
+        IESYS_CRYPTOGCRY_CONTEXT *mycontext =
+            (IESYS_CRYPTOGCRY_CONTEXT *) * context;
+        if (mycontext->type != IESYS_CRYPTOGCRY_TYPE_HMAC) {
+            LOG_DEBUG("bad context");
+            return;
+        }
+
+        gcry_mac_close(mycontext->hmac.gcry_context);
+
+        free(mycontext);
+        *context = NULL;
+    }
+}
+
+/** Compute random TPM2B data.
+ *
+ * The random data will be generated and written to a passed TPM2B structure.
+ * @param[out] nonce The TPM2B structure for the random data (caller-allocated).
+ * @param[in] num_bytes The number of bytes to be generated.
+ * @retval TSS2_RC_SUCCESS on success.
+ */
+TSS2_RC
+iesys_cryptogcry_random2b(TPM2B_NONCE * nonce, size_t num_bytes)
+{
+    if (num_bytes == 0) {
+        nonce->size = sizeof(TPMU_HA);
+    } else {
+        nonce->size = num_bytes;
+    }
+    /*
+     * possible values for random level:
+     *  GCRY_WEAK_RANDOM GCRY_STRONG_RANDOM  GCRY_VERY_STRONG_RANDOM
+     */
+    gcry_randomize(&nonce->buffer[0], nonce->size, GCRY_STRONG_RANDOM);
+    return TSS2_RC_SUCCESS;
+}
+
+/** Encryption of a buffer using a public (RSA) key.
+ *
+ * Encrypting a buffer using a public key is used for example during
+ * Esys_StartAuthSession in order to encrypt the salt value.
+ * @param[in] key The key to be used for encryption.
+ * @param[in] in_size The size of the buffer to be encrypted.
+ * @param[in] in_buffer The data buffer to be encrypted.
+ * @param[in] max_out_size The maximum size for the output encrypted buffer.
+ * @param[out] out_buffer The encrypted buffer.
+ * @param[out] out_size The size of the encrypted output.
+ * @param[in] label The label used in the encryption scheme.
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
+ */
+TSS2_RC
+iesys_cryptogcry_pk_encrypt(TPM2B_PUBLIC * key,
+                            size_t in_size,
+                            BYTE * in_buffer,
+                            size_t max_out_size,
+                            BYTE * out_buffer,
+                            size_t * out_size, const char *label)
+{
+    TSS2_RC r;
+    gcry_error_t err;
+    char *hash_alg;
+    size_t lsize = 0;
+    BYTE exponent[4] = { 0x00, 0x01, 0x00, 0x01 };
+    char *padding;
+    gcry_sexp_t sexp_data, sexp_key, sexp_cipher, sexp_cipher_a;
+    if (label != NULL)
+        lsize = strlen(label) + 1;
+    switch (key->publicArea.nameAlg) {
+    case TPM2_ALG_SHA1:
+        hash_alg = "sha1";
+        break;
+    case TPM2_ALG_SHA256:
+        hash_alg = "sha256";
+        break;
+    default:
+        LOG_ERROR("Hash alg not implemented");
+        return TSS2_ESYS_RC_BAD_VALUE;
+    }
+    switch (key->publicArea.parameters.rsaDetail.scheme.scheme) {
+    case TPM2_ALG_NULL:
+        padding = "raw";
+        break;
+    case TPM2_ALG_RSAES:
+        padding = "pkcs1";
+        break;
+    case TPM2_ALG_OAEP:
+        padding = "oaep";
+        break;
+    default:
+        LOG_ERROR("Illegal RSA scheme");
+        return TSS2_ESYS_RC_BAD_VALUE;
+    }
+    size_t offset = 0;
+    r = Tss2_MU_UINT32_Marshal(key->publicArea.parameters.rsaDetail.exponent,
+                               &exponent[0], sizeof(UINT32), &offset);
+    if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Marshaling");
+        return r;
+    }
+    err = gcry_sexp_build(&sexp_data, NULL,
+                          "(data (flags %s) (hash-algo %s) (label %b) (value %b) )",
+                          padding, hash_alg, lsize, label, (int)in_size,
+                          in_buffer);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_sexp_build");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    err = gcry_sexp_build(&sexp_key, NULL, "(public-key (rsa (n %b) (e %b)))",
+                          (int)key->publicArea.unique.rsa.size,
+                          &key->publicArea.unique.rsa.buffer[0], 4, exponent);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_sexp_build");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    err = gcry_pk_encrypt(&sexp_cipher, sexp_data, sexp_key);
+    if (err != GPG_ERR_NO_ERROR) {
+        fprintf (stderr, "Failure: %s/%s\n",
+                 gcry_strsource (err),
+                 gcry_strerror (err));
+        LOG_ERROR("Function gcry_pk_encrypt");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    sexp_cipher_a = gcry_sexp_find_token(sexp_cipher, "a", 0);
+    gcry_mpi_t mpi_cipher =
+        gcry_sexp_nth_mpi(sexp_cipher_a, 1, GCRYMPI_FMT_USG);
+    err = gcry_mpi_print(GCRYMPI_FMT_USG, &out_buffer[0], max_out_size,
+                         out_size, mpi_cipher);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_mpi_print");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    free(sexp_data);
+    free(sexp_key);
+    free(sexp_cipher);
+    free(sexp_cipher_a);
+    return TSS2_RC_SUCCESS;
+}
+
+/** Computation of ephemeral ECC key and shared secret Z.
+ *
+ * According to the description in  TPM spec part 1 C 6.1 a shared secret
+ * between application and TPM is computed (ECDH). An ephemeral ECC key and a
+ * TPM keyare used for the ECDH key exchange.
+ * @param[in] key The key to be used for ECDH key exchange.
+ * @param[in] max_out_size the max size for the output of the public key of the
+ *            computed ephemeral key.
+ * @param[out] Z The computed shared secret.
+ * @param[out] Q The public part of the ephemeral key in TPM format.
+ * @param[out] out_buffer The public part of the ephemeral key will be marshaled
+ *             to this buffer.
+ * @param[out] out_size The size of the marshaled output.
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
+ */
+TSS2_RC
+iesys_cryptogcry_get_ecdh_point(TPM2B_PUBLIC *key,
+                                size_t max_out_size,
+                                TPM2B_ECC_PARAMETER *Z,
+                                TPMS_ECC_POINT *Q,
+                                BYTE * out_buffer,
+                                size_t * out_size)
+{
+/*
+ * Format strings for some gcrypt sexps have to be created with sprintf due to
+ * a bug in libgcrypt. %s does not work in libgcypt with these sexps.
+ */
+#define SEXP_GENKEY_ECC  "(genkey (ecc (curve %s)))"
+#define SEXP_ECC_POINT "(ecc (curve %s) (q.x  %sb) (q.y %sb))"
+
+    TSS2_RC r;
+    char *curveId;
+    gcry_sexp_t mpi_tpm_sq = NULL;     /* sexp for public part of TPM  key*/
+    gcry_sexp_t mpi_sd = NULL;         /* sexp for private part of ephemeral key */
+    gcry_sexp_t mpi_s_pub_q = NULL;    /* sexp for public part of ephemeral key */
+    gcry_mpi_point_t mpi_q = NULL;     /* public point of ephemeral key */
+    gcry_mpi_point_t mpi_tpm_q = NULL; /* public point of TPM key */
+    gcry_mpi_t mpi_d = NULL;           /* private part of ephemeral key */
+    gcry_mpi_point_t mpi_qd = NULL;    /* result of mpi_tpm_q * mpi_d */
+    gcry_ctx_t ctx = NULL;             /* context for ec curves */
+    size_t size_x, size_y;
+    size_t offset = 0;
+    gcry_mpi_t mpi_x = gcry_mpi_new(521);  /* big number for x coordinate */
+    gcry_mpi_t mpi_y = gcry_mpi_new(521);  /* big number for y coordinate */
+
+    /* Set libcrypt constant for curve type */
+    switch (key->publicArea.parameters.eccDetail.curveID) {
+    case TPM2_ECC_NIST_P192:
+        curveId = "\"NIST P-192\"";
+        break;
+    case TPM2_ECC_NIST_P224:
+        curveId = "\"NIST P-224\"";
+        break;
+    case TPM2_ECC_NIST_P256:
+        curveId = "\"NIST P-256\"";
+        break;
+    case TPM2_ECC_NIST_P384:
+        curveId = "\"NIST P-384\"";
+        break;
+    case TPM2_ECC_NIST_P521:
+        curveId = "\"NIST P-521\"";
+        break;
+    default:
+        LOG_ERROR("Illegal ECC curve ID");
+        return TSS2_ESYS_RC_BAD_VALUE;
+    }
+
+    /* compute ephemeral ecc key */
+    gcry_sexp_t ekey_spec = NULL, ekey_pair = NULL;
+    { /* scope for sexp_ecc_key */
+        char sexp_ecc_key [sizeof(SEXP_GENKEY_ECC)+strlen(curveId)
+                           -1];  // -1 = (-2 for %s +1 for \0)
+
+        if (sprintf(&sexp_ecc_key[0], SEXP_GENKEY_ECC, curveId) < 1) {
+            goto_error(r, TSS2_ESYS_RC_MEMORY, "asprintf", cleanup);
+        }
+
+        if (gcry_sexp_build(&ekey_spec, NULL,
+                            sexp_ecc_key) != GPG_ERR_NO_ERROR) {
+            goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "gcry_sexp_build", cleanup);
+        }
+    }
+
+    if (gcry_pk_genkey (&ekey_pair, ekey_spec) != GPG_ERR_NO_ERROR) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create ephemeral ecc key",
+                   cleanup);
+    }
+
+    /* Get private ephemeral key d  */
+    mpi_sd = gcry_sexp_find_token(ekey_pair, "d", 0);
+    if (mpi_sd == NULL) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Get private part of ecc key", cleanup);
+    }
+    mpi_d = gcry_sexp_nth_mpi(mpi_sd, 1, GCRYMPI_FMT_USG);
+    if (mpi_d == NULL) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Get private part of ecc key from sexp", cleanup);
+    }
+
+    /* Construct ephemeral public key */
+    mpi_s_pub_q = gcry_sexp_find_token(ekey_pair, "public-key", 0);
+    if (mpi_s_pub_q == NULL) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get public part ecc key",
+                   cleanup);
+    }
+
+    if (gcry_mpi_ec_new (&ctx, mpi_s_pub_q, curveId) != GPG_ERR_NO_ERROR) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create ec", cleanup);
+    }
+    mpi_q =  gcry_mpi_ec_get_point ("q", ctx, 1);
+    if (mpi_q == NULL) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get ecc point", cleanup);
+    }
+
+    /* Check whether point is on curve */
+    if (!gcry_mpi_ec_curve_point(mpi_q, ctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Point not on curve", cleanup);
+    }
+
+    /* Store ephemeral public key in Q */
+    if (gcry_mpi_ec_get_affine (mpi_x, mpi_y, mpi_q, ctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Point is at infinity",
+                   cleanup);
+    }
+
+    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Q->x.buffer[0], max_out_size,
+                       &size_x, mpi_x) != GPG_ERR_NO_ERROR) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get x part of point",
+                   cleanup);
+    }
+
+    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Q->y.buffer[0], max_out_size,
+                       &size_y, mpi_y) != GPG_ERR_NO_ERROR) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get y part of point",
+                   cleanup);
+    }
+    Q->x.size = size_x;
+    Q->y.size = size_y;
+    SAFE_FREE(ctx);
+    { /* scope for sexp_point */
+
+        /* Get public point from TPM key */
+        char sexp_point [sizeof(SEXP_ECC_POINT) + strlen(curveId)
+                         + key->publicArea.unique.ecc.x.size
+                         + key->publicArea.unique.ecc.y.size
+                         - 5];  /* -1 = (-4 for 2*%sb -2 for %s +1 for \0) */
+
+        if (sprintf(&sexp_point[0], SEXP_ECC_POINT,
+                    curveId, "%", "%") <1 ) {
+            goto_error(r, TSS2_ESYS_RC_MEMORY, "asprintf", cleanup);
+        }
+
+        if ( gcry_sexp_build(&mpi_tpm_sq, NULL,
+                              sexp_point,
+                              key->publicArea.unique.ecc.x.size,
+                              &key->publicArea.unique.ecc.x.buffer[0],
+                              key->publicArea.unique.ecc.y.size,
+                             &key->publicArea.unique.ecc.y.buffer[0])) {
+            goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                       "Function gcry_mpi_scan", cleanup);
+
+        }
+    }
+    offset = 0;
+    r = Tss2_MU_TPMS_ECC_POINT_Marshal(Q,  &out_buffer[0], max_out_size, &offset);
+    return_if_error(r, "Error marshaling");
+    *out_size = offset;
+
+    /* Multiply d and Q */
+    if (gcry_mpi_ec_new (&ctx, mpi_tpm_sq, curveId)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "create ec curve", cleanup);
+    }
+    mpi_tpm_q =  gcry_mpi_ec_get_point ("q", ctx, 1);
+    mpi_qd = gcry_mpi_point_new(256);
+    gcry_mpi_ec_mul(mpi_qd , mpi_d, mpi_tpm_q, ctx);
+
+    /* Store the x coordinate of d*Q in Z which will be used for KDFe */
+    if (gcry_mpi_ec_get_affine (mpi_x, mpi_y, mpi_qd, ctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Point is at infinity", cleanup);
+    }
+
+    if (gcry_mpi_print(GCRYMPI_FMT_USG, &Z->buffer[0], TPM2_MAX_ECC_KEY_BYTES,
+                       &size_x, mpi_x)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Get x coordinate d*Q", cleanup);
+    }
+
+    Z->size = size_x;
+    LOGBLOB_DEBUG(&Z->buffer[0], size_x, "Z (Q*d)");
+
+ cleanup:
+    SAFE_FREE(ctx);
+    SAFE_FREE(mpi_x);
+    SAFE_FREE(mpi_y);
+    SAFE_FREE(mpi_tpm_q);
+    SAFE_FREE(mpi_qd);
+    SAFE_FREE(mpi_q);
+    SAFE_FREE(mpi_tpm_q);
+    SAFE_FREE(mpi_tpm_sq);
+    SAFE_FREE(ekey_spec);
+    SAFE_FREE(mpi_s_pub_q);
+
+    return r;
+}
+
+/** Initialize AES context for encryption / decryption.
+ *
+ * @param[out] handle for AES context
+ * @param[in] key key used for AES.
+ * @param[in] tpm_sym_alg AES type in TSS2 notation.
+ * @param[in] key_bits Key size in bits.
+ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB).
+ *         For parameter encryption only CFB can be used.
+ * @param[in] iv_len Length of initialization vector (iv) in byte.
+ * @param[in] iv The initialization vector.
+ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE for invalid
+ *         parameters, TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto
+ *         library.
+ */
+TSS2_RC
+iesys_cryptogcry_sym_aes_init(gcry_cipher_hd_t * cipher_hd,
+                              uint8_t * key,
+                              TPM2_ALG_ID tpm_sym_alg,
+                              TPMI_AES_KEY_BITS key_bits,
+                              TPM2_ALG_ID tpm_mode,
+                              size_t iv_len, uint8_t * iv)
+{
+
+    LOGBLOB_TRACE(key, (key_bits + 7) / 8, "IESYS AES key");
+    LOGBLOB_TRACE(iv, iv_len, "IESYS AES iv");
+    int algo, mode, len;
+    size_t key_len = 0;
+    gcry_error_t err;
+    switch (tpm_sym_alg) {
+    case TPM2_ALG_AES:
+        switch (key_bits) {
+        case 128:
+            algo = GCRY_CIPHER_AES128;
+            len = 128;
+            break;
+        case 192:
+            algo = GCRY_CIPHER_AES192;
+            len = 192;
+            break;
+        case 256:
+            algo = GCRY_CIPHER_AES256;
+            len = 256;
+            break;
+        default:
+            LOG_ERROR("Illegal key length.");
+            return TSS2_ESYS_RC_BAD_VALUE;
+        }
+        switch (tpm_mode) {
+        case TPM2_ALG_CFB:
+            mode = GCRY_CIPHER_MODE_CFB;
+            break;
+        default:
+            LOG_ERROR("Illegal symmetric algorithm.");
+            return TSS2_ESYS_RC_BAD_VALUE;
+        }
+        break;
+    default:
+        LOG_ERROR("Illegal symmetric algorithm.");
+        return TSS2_ESYS_RC_BAD_VALUE;
+    }
+    key_len = (len + 7) / 8;
+    err = gcry_cipher_open(cipher_hd, algo, mode, 0);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Opening gcrypt context");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    if (iv_len != 0) {
+        err = gcry_cipher_setiv(*cipher_hd, &iv[0], iv_len);
+        if (err != GPG_ERR_NO_ERROR) {
+            LOG_ERROR("Function gcry_cipher_setiv");
+            return TSS2_ESYS_RC_GENERAL_FAILURE;
+        }
+    }
+    err = gcry_cipher_setkey(*cipher_hd, key, key_len);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_cipher_setkey");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    return TSS2_RC_SUCCESS;
+}
+
+/** Encrypt data with AES.
+ *
+ * @param[in] key key used for AES.
+ * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
+ * @param[in] key_bits Key size in bits.
+ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation.
+ * @param[in] blk_len Length Block length of AES.
+ * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored
+ *                in this buffer.
+ * @param[in] buffer_size size of data to be encrypted.
+ * @param[in] iv The initialization vector. The size is equal to blk_len.
+ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_sym_aes_encrypt(uint8_t * key,
+                                 TPM2_ALG_ID tpm_sym_alg,
+                                 TPMI_AES_KEY_BITS key_bits,
+                                 TPM2_ALG_ID tpm_mode,
+                                 size_t blk_len,
+                                 uint8_t * buffer,
+                                 size_t buffer_size,
+                                 uint8_t * iv)
+{
+    gcry_cipher_hd_t cipher_hd;
+    gcry_error_t err;
+    TSS2_RC r;
+
+    if (key == NULL || buffer == NULL) {
+        LOG_ERROR("Bad reference");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    r = iesys_cryptogcry_sym_aes_init(&cipher_hd, key, tpm_sym_alg,
+                                      key_bits, tpm_mode, blk_len, iv);
+    if (r != TSS2_RC_SUCCESS)
+        return r;
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input");
+    err = gcry_cipher_encrypt(cipher_hd, buffer, buffer_size, NULL, 0);
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output");
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_cipher_encrypt");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    gcry_cipher_close(cipher_hd);
+    return TSS2_RC_SUCCESS;
+}
+
+/** Decrypt data with AES.
+ *
+ * @param[in] key key used for AES.
+ * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
+ * @param[in] key_bits Key size in bits.
+ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB).
+ * @param[in] blk_len Length Block length of AES.
+ * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored
+ *                in this buffer.
+ * @param[in] buffer_size size of data to be encrypted.
+ * @param[in] iv The initialization vector. The size is equal to blk_len.
+ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptogcry_sym_aes_decrypt(uint8_t * key,
+                                 TPM2_ALG_ID tpm_sym_alg,
+                                 TPMI_AES_KEY_BITS key_bits,
+                                 TPM2_ALG_ID tpm_mode,
+                                 size_t blk_len,
+                                 uint8_t * buffer,
+                                 size_t buffer_size,
+                                 uint8_t * iv)
+{
+    gcry_cipher_hd_t cipher_hd;
+    gcry_error_t err;
+    TSS2_RC r;
+
+    if (tpm_sym_alg != TPM2_ALG_AES) {
+        LOG_ERROR("AES expected");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    if (key == NULL || buffer == NULL) {
+        LOG_ERROR("Bad reference");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    r = iesys_cryptogcry_sym_aes_init(&cipher_hd, key, tpm_sym_alg,
+                                      key_bits, tpm_mode, blk_len, iv);
+    if (r != TSS2_RC_SUCCESS)
+        return r;
+    err = gcry_cipher_decrypt(cipher_hd, buffer, buffer_size, NULL, 0);
+    if (err != GPG_ERR_NO_ERROR) {
+        LOG_ERROR("Function gcry_cipher_decrypt");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+    gcry_cipher_close(cipher_hd);
+    return TSS2_RC_SUCCESS;
+}
diff --git a/src/tss2-esys/esys_crypto_gcrypt.h b/src/tss2-esys/esys_crypto_gcrypt.h
new file mode 100644
index 0000000..663ffb8
--- /dev/null
+++ b/src/tss2-esys/esys_crypto_gcrypt.h
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+#ifndef ESYS_CRYPTO_GCRYPT_H
+#define ESYS_CRYPTO_GCRYPT_H
+
+#include <stddef.h>
+#include "tss2_tpm2_types.h"
+#include "tss2-sys/sysapi_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _IESYS_CRYPTO_CONTEXT IESYS_CRYPTO_CONTEXT_BLOB;
+
+TSS2_RC iesys_cryptogcry_hash_start(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hashAlg);
+
+TSS2_RC iesys_cryptogcry_hash_update(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    const uint8_t *buffer, size_t size);
+
+TSS2_RC iesys_cryptogcry_hash_update2b(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptogcry_hash_finish(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    uint8_t *buffer,
+    size_t *size);
+
+TSS2_RC iesys_cryptogcry_hash_finish2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2B *b);
+
+void iesys_cryptogcry_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
+
+#define iesys_crypto_hash_start iesys_cryptogcry_hash_start
+#define iesys_crypto_hash_update iesys_cryptogcry_hash_update
+#define iesys_crypto_hash_update2b iesys_cryptogcry_hash_update2b
+#define iesys_crypto_hash_finish iesys_cryptogcry_hash_finish
+#define iesys_crypto_hash_finish2b iesys_cryptogcry_hash_finish2b
+#define iesys_crypto_hash_abort iesys_cryptogcry_hash_abort
+
+TSS2_RC iesys_cryptogcry_hmac_start(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hmacAlg,
+    const uint8_t *key,
+    size_t size);
+
+TSS2_RC iesys_cryptogcry_hmac_start2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hmacAlg,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptogcry_hmac_update(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    const uint8_t *buffer,
+    size_t size);
+
+TSS2_RC iesys_cryptogcry_hmac_update2b(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptogcry_hmac_finish(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    uint8_t *buffer,
+    size_t *size);
+
+TSS2_RC iesys_cryptogcry_hmac_finish2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2B *b);
+
+void iesys_cryptogcry_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
+
+#define iesys_crypto_hmac_start iesys_cryptogcry_hmac_start
+#define iesys_crypto_hmac_start2b iesys_cryptogcry_hmac_start2b
+#define iesys_crypto_hmac_update iesys_cryptogcry_hmac_update
+#define iesys_crypto_hmac_update2b iesys_cryptogcry_hmac_update2b
+#define iesys_crypto_hmac_finish iesys_cryptogcry_hmac_finish
+#define iesys_crypto_hmac_finish2b iesys_cryptogcry_hmac_finish2b
+#define iesys_crypto_hmac_abort iesys_cryptogcry_hmac_abort
+
+TSS2_RC iesys_cryptogcry_random2b(TPM2B_NONCE *nonce, size_t num_bytes);
+#define iesys_crypto_random2b iesys_cryptogcry_random2b
+
+TSS2_RC iesys_cryptogcry_pk_encrypt(
+    TPM2B_PUBLIC *key,
+    size_t in_size,
+    BYTE *in_buffer,
+    size_t max_out_size,
+    BYTE *out_buffer,
+    size_t *out_size,
+    const char *label);
+
+#define iesys_crypto_pk_encrypt iesys_cryptogcry_pk_encrypt
+
+TSS2_RC iesys_cryptogcry_sym_aes_encrypt(
+    uint8_t *key,
+    TPM2_ALG_ID tpm_sym_alg,
+    TPMI_AES_KEY_BITS key_bits,
+    TPM2_ALG_ID tpm_mode,
+    size_t blk_len,
+    uint8_t *dst,
+    size_t dst_size,
+    uint8_t *iv);
+
+TSS2_RC iesys_cryptogcry_sym_aes_decrypt(
+    uint8_t *key,
+    TPM2_ALG_ID tpm_sym_alg,
+    TPMI_AES_KEY_BITS key_bits,
+    TPM2_ALG_ID tpm_mode,
+    size_t blk_len,
+    uint8_t *dst,
+    size_t dst_size,
+    uint8_t *iv);
+
+TSS2_RC iesys_cryptogcry_get_ecdh_point(
+    TPM2B_PUBLIC *key,
+    size_t max_out_size,
+    TPM2B_ECC_PARAMETER *Z,
+    TPMS_ECC_POINT *Q,
+    BYTE * out_buffer,
+    size_t * out_size);
+
+#define iesys_crypto_get_ecdh_point iesys_cryptogcry_get_ecdh_point
+#define iesys_crypto_sym_aes_encrypt iesys_cryptogcry_sym_aes_encrypt
+#define iesys_crypto_sym_aes_decrypt iesys_cryptogcry_sym_aes_decrypt
+
+#endif /* ESYS_CRYPTO_GCRYPT_H */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
diff --git a/src/tss2-esys/esys_crypto_ossl.c b/src/tss2-esys/esys_crypto_ossl.c
new file mode 100644
index 0000000..86fe749
--- /dev/null
+++ b/src/tss2-esys/esys_crypto_ossl.c
@@ -0,0 +1,1120 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+
+#define _GNU_SOURCE
+
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/rsa.h>
+#include <openssl/engine.h>
+#include <stdio.h>
+
+#include "tss2_esys.h"
+
+#include "esys_crypto.h"
+#include "esys_crypto_ossl.h"
+
+#include "esys_iutil.h"
+#include "esys_mu.h"
+#define LOGMODULE esys
+#include "util/log.h"
+#include "esys_crypto_ossl.h"
+
+static ENGINE *engine = NULL;
+
+ENGINE *get_engine()
+{
+    if (engine)
+        return engine;
+    engine = ENGINE_by_id("openssl");
+    return engine;
+}
+
+int BN_bn2binpad(const BIGNUM *bn, unsigned char *bin, int bin_length)
+{
+    int len_bn = BN_num_bytes(bn);
+    int offset = bin_length - len_bn;
+    memset(bin,0,offset);
+    BN_bn2bin(bn, bin);
+    return 1;
+}
+
+/** Context to hold temporary values for iesys_crypto */
+typedef struct _IESYS_CRYPTO_CONTEXT {
+    enum {
+        IESYS_CRYPTOSSL_TYPE_HASH = 1,
+        IESYS_CRYPTOSSL_TYPE_HMAC,
+    } type; /**< The type of context to hold; hash or hmac */
+    union {
+        struct {
+            EVP_MD_CTX  *ossl_context;
+            const EVP_MD *ossl_hash_alg;
+            size_t hash_len;
+        } hash; /**< the state variables for a hash context */
+        struct {
+            EVP_MD_CTX *ossl_context;
+            const EVP_MD *ossl_hash_alg;
+            size_t hmac_len;
+        } hmac; /**< the state variables for an hmac context */
+    };
+} IESYS_CRYPTOSSL_CONTEXT;
+
+size_t
+hash_get_digest_size(TPM2_ALG_ID hashAlg)
+{
+    switch (hashAlg) {
+    case TPM2_ALG_SHA1:
+        return TPM2_SHA1_DIGEST_SIZE;
+        break;
+    case TPM2_ALG_SHA256:
+        return TPM2_SHA256_DIGEST_SIZE;
+        break;
+    case TPM2_ALG_SHA384:
+        return TPM2_SHA384_DIGEST_SIZE;
+        break;
+    case TPM2_ALG_SHA512:
+        return TPM2_SHA512_DIGEST_SIZE;
+        break;
+    case TPM2_ALG_SM3_256:
+        return TPM2_SM3_256_DIGEST_SIZE;
+        break;
+    default:
+        return 0;
+    }
+}
+
+const EVP_MD *
+get_ossl_hash_md(TPM2_ALG_ID hashAlg)
+{
+    switch (hashAlg) {
+    case TPM2_ALG_SHA1:
+        return EVP_sha1();
+        break;
+    case TPM2_ALG_SHA256:
+        return EVP_sha256();
+        break;
+    case TPM2_ALG_SHA384:
+        return EVP_sha384();
+        break;
+    case TPM2_ALG_SHA512:
+        return EVP_sha512();
+        break;
+    default:
+        return NULL;
+    }
+}
+
+/** Provide the context for the computation of a hash digest.
+ *
+ * The context will be created and initialized according to the hash function.
+ * @param[out] context The created context (callee-allocated).
+ * @param[in] hashAlg The hash algorithm for the creation of the context.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_VALUE or TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                           TPM2_ALG_ID hashAlg)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    LOG_TRACE("call: context=%p hashAlg=%"PRIu16, context, hashAlg);
+    return_if_null(context, "Context is NULL", TSS2_ESYS_RC_BAD_REFERENCE);
+    return_if_null(context, "Null-Pointer passed for context", TSS2_ESYS_RC_BAD_REFERENCE);
+    IESYS_CRYPTOSSL_CONTEXT *mycontext;
+    mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT));
+    return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
+    mycontext->type = IESYS_CRYPTOSSL_TYPE_HASH;
+
+    if (!(mycontext->hash.ossl_hash_alg = get_ossl_hash_md(hashAlg))) {
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
+                   "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
+    }
+
+    if (!(mycontext->hash.hash_len = hash_get_digest_size(hashAlg))) {
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
+                   "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
+    }
+
+    if (!(mycontext->hash.ossl_context =  EVP_MD_CTX_create())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Error EVP_MD_CTX_create", cleanup);
+    }
+
+    if (1 != EVP_DigestInit_ex(mycontext->hash.ossl_context,
+                               mycontext->hash.ossl_hash_alg,
+                               get_engine())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Errror EVP_DigestInit_ex", cleanup);
+    }
+
+    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
+
+    return TSS2_RC_SUCCESS;
+
+ cleanup:
+    if (mycontext->hash.ossl_context)
+        EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
+    SAFE_FREE(mycontext);
+
+    return r;
+}
+
+/** Update the digest value of a digest object from a byte buffer.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm of the context. <
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] buffer The data for the update.
+ * @param[in] size The size of the data buffer.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptossl_hash_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
+                            const uint8_t * buffer, size_t size)
+{
+    LOG_TRACE("called for context %p, buffer %p and size %zd", context, buffer,
+              size);
+    if (context == NULL || buffer == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext = (IESYS_CRYPTOSSL_CONTEXT *) context;
+    if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    LOGBLOB_TRACE(buffer, size, "Updating hash with");
+
+    if (1 != EVP_DigestUpdate(mycontext->hash.ossl_context, buffer, size)) {
+        return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "OSSL hash update");
+    }
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Update the digest value of a digest object from a TPM2B object.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] b The TPM2B object for the update.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptossl_hash_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptossl_hash_update(context, &b->buffer[0], b->size);
+    return ret;
+}
+
+/** Get the digest value of a digest object and close the context.
+ *
+ * The digest value will written to a passed buffer and the resources of the
+ * digest object are released.
+ * @param[in,out] context The context of the digest object to be released
+ * @param[out] buffer The buffer for the digest value (caller-allocated).
+ * @param[out] size The size of the digest.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hash_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                            uint8_t * buffer, size_t * size)
+{
+    unsigned int digest_size = 0;
+
+    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
+              context, buffer, size);
+    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext = * context;
+    if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (*size < mycontext->hash.hash_len) {
+        LOG_ERROR("Buffer too small");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (1 != EVP_DigestFinal_ex(mycontext->hash.ossl_context, buffer, &digest_size)) {
+        LOG_ERROR("Ossl error.");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    if (digest_size != mycontext->hash.hash_len) {
+        LOG_ERROR("Invalid size computed by EVP_DigestFinal_ex");
+        return TSS2_ESYS_RC_GENERAL_FAILURE;
+    }
+
+    LOGBLOB_TRACE(buffer, mycontext->hash.hash_len, "read hash result");
+
+    *size = mycontext->hash.hash_len;
+    EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
+    free(mycontext);
+    *context = NULL;
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Get the digest value of a digest object and close the context.
+ *
+ * The digest value will written to a passed TPM2B object and the
+ * digest object are released.
+ * @param[in,out] context The context of the digest object to be released
+ * @param[out] b The TPM2B object for the digest (caller-allocated).
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hash_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || *context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    size_t s = b->size;
+    TSS2_RC ret = iesys_cryptossl_hash_finish(context, &b->buffer[0], &s);
+    b->size = s;
+    return ret;
+}
+
+/** Release the resources of a digest object.
+ *
+ * The assigned resources will be released and the context will be set to NULL.
+ * @param[in,out] context The context of the digest object.
+ */
+void
+iesys_cryptossl_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
+{
+    LOG_TRACE("called for context-pointer %p", context);
+    if (context == NULL || *context == NULL) {
+        LOG_DEBUG("Null-Pointer passed");
+        return;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext =
+        (IESYS_CRYPTOSSL_CONTEXT *) * context;
+    if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) {
+        LOG_DEBUG("bad context");
+        return;
+    }
+
+    EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
+    free(mycontext);
+    *context = NULL;
+}
+
+/* HMAC */
+
+/** Provide the context an HMAC digest object from a byte buffer key.
+ *
+ * The context will be created and initialized according to the hash function
+ * and the used HMAC key.
+ * @param[out] context The created context (callee-allocated).
+ * @param[in] hmacAlg The hash algorithm for the HMAC computation.
+ * @param[in] key The byte buffer of the HMAC key.
+ * @param[in] size The size of the HMAC key.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                           TPM2_ALG_ID hashAlg,
+                           const uint8_t * key, size_t size)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    EVP_PKEY *hkey = NULL;
+
+
+    LOG_TRACE("called for context-pointer %p and hmacAlg %d", context, hashAlg);
+    LOGBLOB_TRACE(key, size, "Starting  hmac with");
+    if (context == NULL || key == NULL) {
+        LOG_ERROR("Null-Pointer passed in for context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT));
+    return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
+
+    if (!(mycontext->hmac.ossl_hash_alg = get_ossl_hash_md(hashAlg))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
+    }
+
+    if (!(mycontext->hmac.hmac_len = hash_get_digest_size(hashAlg))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
+    }
+
+    if (!(mycontext->hmac.ossl_context =  EVP_MD_CTX_create())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "Error EVP_MD_CTX_create", cleanup);
+    }
+
+    if (!(hkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, get_engine(), key, size))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "EVP_PKEY_new_mac_key", cleanup);
+    }
+
+    if(1 != EVP_DigestSignInit(mycontext->hmac.ossl_context, NULL,
+                               mycontext->hmac.ossl_hash_alg, get_engine(), hkey)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
+                   "DigestSignInit", cleanup);
+    }
+
+    mycontext->type = IESYS_CRYPTOSSL_TYPE_HMAC;
+
+    *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext;
+
+    return TSS2_RC_SUCCESS;
+
+ cleanup:
+    if (mycontext->hmac.ossl_context)
+        EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
+    if(hkey)
+        EVP_PKEY_free(hkey);
+    SAFE_FREE(mycontext);
+    return r;
+}
+
+/** Provide the context an HMAC digest object from a byte TPM2B key.
+ *
+ * The context will be created and initialized according to the hash function
+ * and the used HMAC key.
+ * @param[out] context The created context.
+ * @param[in] hmacAlg The hash algorithm for the HMAC computation.
+ * @param[in] key The TPM2B object of the HMAC key.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_start2b(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                             TPM2_ALG_ID hmacAlg, TPM2B * key)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, key);
+    if (context == NULL || key == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptossl_hmac_start(context, hmacAlg, &key->buffer[0],
+                                             key->size);
+    return ret;
+}
+
+/** Update and HMAC digest value from a byte buffer.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm and the key of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] buffer The data for the update.
+ * @param[in] size The size of the data buffer.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
+                            const uint8_t * buffer, size_t size)
+{
+    LOG_TRACE("called for context %p, buffer %p and size %zd",
+              context, buffer, size);
+    if (context == NULL || buffer == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext = (IESYS_CRYPTOSSL_CONTEXT *) context;
+    if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    LOGBLOB_TRACE(buffer, size, "Updating hmac with");
+
+    /* Call update with the message */
+    if(1 != EVP_DigestSignUpdate(mycontext->hmac.ossl_context, buffer, size)) {
+        return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "OSSL HMAC update");
+    }
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Update and HMAC digest value from a TPM2B object.
+ *
+ * The context of a digest object will be updated according to the hash
+ * algorithm and the key of the context.
+ * @param[in,out] context The context of the digest object which will be updated.
+ * @param[in] b The TPM2B object for the update.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b);
+    if (context == NULL || b == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    TSS2_RC ret = iesys_cryptossl_hmac_update(context, &b->buffer[0], b->size);
+    return ret;
+}
+
+/** Write the HMAC digest value to a byte buffer and close the context.
+ *
+ * The digest value will written to a passed buffer and the resources of the
+ * HMAC object are released.
+ * @param[in,out] context The context of the HMAC object.
+ * @param[out] buffer The buffer for the digest value (caller-allocated).
+ * @param[out] size The size of the digest.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_BAD_SIZE If the size passed is lower than the HMAC length.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
+                            uint8_t * buffer, size_t * size)
+{
+
+    TSS2_RC r = TSS2_RC_SUCCESS;
+
+    LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p",
+              context, buffer, size);
+    if (context == NULL || *context == NULL || buffer == NULL || size == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    IESYS_CRYPTOSSL_CONTEXT *mycontext =
+        (IESYS_CRYPTOSSL_CONTEXT *) * context;
+    if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) {
+        LOG_ERROR("bad context");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (*size < mycontext->hmac.hmac_len) {
+        LOG_ERROR("Buffer too small");
+        return TSS2_ESYS_RC_BAD_SIZE;
+    }
+
+    if (1 != EVP_DigestSignFinal(mycontext->hmac.ossl_context, buffer, size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "DigestSignFinal", cleanup);
+    }
+
+    LOGBLOB_TRACE(buffer, *size, "read hmac result");
+
+ cleanup:
+    EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
+    SAFE_FREE(mycontext);
+    *context = NULL;
+    return r;
+}
+
+/** Write the HMAC digest value to a TPM2B object and close the context.
+ *
+ * The digest value will written to a passed TPM2B object and the resources of
+ * the HMAC object are released.
+ * @param[in,out] context The context of the HMAC object.
+ * @param[out] hmac The buffer for the digest value (caller-allocated).
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
+ * @retval TSS2_ESYS_RC_BAD_SIZE if the size passed is lower than the HMAC length.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_hmac_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * hmac)
+{
+    LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, hmac);
+    if (context == NULL || *context == NULL || hmac == NULL) {
+        LOG_ERROR("Null-Pointer passed");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+    size_t s = hmac->size;
+    TSS2_RC ret = iesys_cryptossl_hmac_finish(context, &hmac->buffer[0], &s);
+    hmac->size = s;
+    return ret;
+}
+
+/** Release the resources of an HAMC object.
+ *
+ * The assigned resources will be released and the context will be set to NULL.
+ * @param[in,out] context The context of the HMAC object.
+ */
+void
+iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
+{
+    LOG_TRACE("called for context-pointer %p", context);
+    if (context == NULL || *context == NULL) {
+        LOG_DEBUG("Null-Pointer passed");
+        return;
+    }
+    if (*context != NULL) {
+        IESYS_CRYPTOSSL_CONTEXT *mycontext =
+            (IESYS_CRYPTOSSL_CONTEXT *) * context;
+        if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) {
+            LOG_DEBUG("bad context");
+            return;
+        }
+
+        EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
+
+        free(mycontext);
+        *context = NULL;
+    }
+}
+
+/** Compute random TPM2B data.
+ *
+ * The random data will be generated and written to a passed TPM2B structure.
+ * @param[out] nonce The TPM2B structure for the random data (caller-allocated).
+ * @param[in] num_bytes The number of bytes to be generated.
+ * @retval TSS2_RC_SUCCESS on success.
+ */
+TSS2_RC
+iesys_cryptossl_random2b(TPM2B_NONCE * nonce, size_t num_bytes)
+{
+    if (num_bytes == 0) {
+        nonce->size = sizeof(TPMU_HA);
+    } else {
+        nonce->size = num_bytes;
+    }
+    if (1 != RAND_bytes(&nonce->buffer[0], nonce->size)) {
+        return_error(TSS2_ESYS_RC_GENERAL_FAILURE,
+                     "Failure in random number generator.");
+    }
+
+    return TSS2_RC_SUCCESS;
+}
+
+/** Encryption of a buffer using a public (RSA) key.
+ *
+ * Encrypting a buffer using a public key is used for example during
+ * Esys_StartAuthSession in order to encrypt the salt value.
+ * @param[in] key The key to be used for encryption.
+ * @param[in] in_size The size of the buffer to be encrypted.
+ * @param[in] in_buffer The data buffer to be encrypted.
+ * @param[in] max_out_size The maximum size for the output encrypted buffer.
+ * @param[out] out_buffer The encrypted buffer.
+ * @param[out] out_size The size of the encrypted output.
+ * @param[in] label The label used in the encryption scheme.
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
+ */
+TSS2_RC
+iesys_cryptossl_pk_encrypt(TPM2B_PUBLIC * pub_tpm_key,
+                           size_t in_size,
+                           BYTE * in_buffer,
+                           size_t max_out_size,
+                           BYTE * out_buffer,
+                           size_t * out_size, const char *label)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    const EVP_MD * hashAlg = NULL;
+    RSA * rsa_key = NULL;
+    EVP_PKEY *evp_rsa_key = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    BIGNUM* bne = BN_new();
+    int padding;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+    BIGNUM *n = NULL;
+#endif
+    if (!(hashAlg = get_ossl_hash_md(pub_tpm_key->publicArea.nameAlg))) {
+        LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", pub_tpm_key->publicArea.nameAlg);
+        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
+    }
+
+    switch (pub_tpm_key->publicArea.parameters.rsaDetail.scheme.scheme) {
+    case TPM2_ALG_NULL:
+        padding = RSA_NO_PADDING;
+        break;
+    case TPM2_ALG_RSAES:
+        padding = RSA_PKCS1_PADDING;
+        break;
+    case TPM2_ALG_OAEP:
+        padding = RSA_PKCS1_OAEP_PADDING;
+        break;
+    default:
+        goto_error(r, TSS2_ESYS_RC_BAD_VALUE, "Illegal RSA scheme", cleanup);
+    }
+
+    if(1 != BN_set_word(bne, pub_tpm_key->publicArea.parameters.rsaDetail.exponent)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set exponent.", cleanup);
+    }
+
+    if (!(rsa_key = RSA_new())) {
+        goto_error(r, TSS2_ESYS_RC_MEMORY, "Could not allocate RSA key", cleanup);
+    }
+
+    if (1 != RSA_generate_key_ex(rsa_key, pub_tpm_key->publicArea.parameters.rsaDetail.keyBits, bne, NULL)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not generate RSA key", cleanup);
+    }
+
+    if (!(evp_rsa_key = EVP_PKEY_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not create evp key.", cleanup);
+    }
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    rsa_key->n = BN_bin2bn(pub_tpm_key->publicArea.unique.rsa.buffer,
+                           pub_tpm_key->publicArea.unique.rsa.size,
+                           NULL);
+#else
+    if (!(n = BN_bin2bn(pub_tpm_key->publicArea.unique.rsa.buffer,
+                        pub_tpm_key->publicArea.unique.rsa.size,
+                        NULL))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not create rsa n.", cleanup);
+    }
+
+    if (1 != RSA_set0_key(rsa_key, n, NULL, NULL)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set rsa n.", cleanup);
+    }
+#endif
+
+    if (1 != EVP_PKEY_set1_RSA(evp_rsa_key, rsa_key)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set rsa key.", cleanup);
+    }
+
+    if (!(ctx = EVP_PKEY_CTX_new(evp_rsa_key, get_engine()))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not create evp context.", cleanup);
+    }
+
+    if (1 != EVP_PKEY_encrypt_init(ctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not init encrypt context.", cleanup);
+    }
+
+    if (1 != EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set RSA passing.", cleanup);
+    }
+
+    if (1 != EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label, strlen(label)+1)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set RSA label.", cleanup);
+    }
+
+    if (1 != EVP_PKEY_CTX_set_rsa_oaep_md(ctx, hashAlg)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not set hash algorithm.", cleanup);
+    }
+
+    /* Determine out size */
+    if (1 != EVP_PKEY_encrypt(ctx, NULL, out_size, in_buffer, in_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not determine ciper size.", cleanup);
+    }
+
+    if ((size_t)*out_size > max_out_size) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypted data too big", cleanup);
+    }
+
+    /* Encrypt data */
+    if (1 != EVP_PKEY_encrypt(ctx, out_buffer, out_size, in_buffer, in_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not encrypt data.", cleanup);
+    }
+
+    return TSS2_RC_SUCCESS;
+
+ cleanup:
+    OSSL_FREE(ctx, EVP_PKEY_CTX);
+    OSSL_FREE(rsa_key, RSA);
+    OSSL_FREE(evp_rsa_key, EVP_PKEY);
+    OSSL_FREE(bne, BN);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+    OSSL_FREE(n, BN);
+#endif
+    return r;
+}
+
+/** Computation of OSSL ec public point from TPM public point.
+ *
+ * @param[in] group The definition of the used ec curve.
+ * @param[in] key The TPM public key.
+ * @param[out] The TPM's public point in OSSL format.
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
+ */
+TSS2_RC
+tpm_pub_to_ossl_pub(EC_GROUP *group, TPM2B_PUBLIC *key, EC_POINT **tpm_pub_key)
+{
+
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    BIGNUM *bn_x = NULL;
+    BIGNUM *bn_y = NULL;
+    BN_CTX *bctx = NULL;
+
+    bctx = BN_CTX_new();
+
+    /* Create the big numbers for the coordinates of the point */
+    if (!(bn_x = BN_bin2bn(&key->publicArea.unique.ecc.x.buffer[0],
+                           key->publicArea.unique.ecc.x.size,
+                           NULL))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create big num from byte buffer.", cleanup);
+    }
+
+    if (!(bn_y = BN_bin2bn(&key->publicArea.unique.ecc.y.buffer[0],
+                           key->publicArea.unique.ecc.y.size,
+                           NULL))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create big num from byte buffer.", cleanup);
+    }
+
+    /* Create the ec point with the affine coordinates of the TPM point */
+    if (!(*tpm_pub_key = EC_POINT_new(group))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create point.", cleanup);
+    }
+
+    if (1 != EC_POINT_set_affine_coordinates_GFp(group, *tpm_pub_key, bn_x, bn_y, bctx)) {
+        OSSL_FREE(*tpm_pub_key, EC_POINT);
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set affine coordinates", cleanup);
+    }
+
+    if (1 != EC_POINT_is_on_curve(group, *tpm_pub_key, bctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "The TPM point is not on the curve", cleanup);
+    }
+
+ cleanup:
+    OSSL_FREE(bn_x, BN);
+    OSSL_FREE(bn_y, BN);
+    OSSL_FREE(bctx, BN_CTX);
+
+    return r;
+}
+
+/** Computation of ephemeral ECC key and shared secret Z.
+ *
+ * According to the description in  TPM spec part 1 C 6.1 a shared secret
+ * between application and TPM is computed (ECDH). An ephemeral ECC key and a
+ * TPM keyare used for the ECDH key exchange.
+ * @param[in] key The key to be used for ECDH key exchange.
+ * @param[in] max_out_size the max size for the output of the public key of the
+ *            computed ephemeral key.
+ * @param[out] Z The computed shared secret.
+ * @param[out] Q The public part of the ephemeral key in TPM format.
+ * @param[out] out_buffer The public part of the ephemeral key will be marshaled
+ *             to this buffer.
+ * @param[out] out_size The size of the marshaled output.
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented.
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed.
+ */
+TSS2_RC
+iesys_cryptossl_get_ecdh_point(TPM2B_PUBLIC *key,
+                               size_t max_out_size,
+                               TPM2B_ECC_PARAMETER *Z,
+                               TPMS_ECC_POINT *Q,
+                               BYTE * out_buffer,
+                               size_t * out_size)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    BN_CTX *bctx = NULL;                  /* Context used for big number operations */
+    EC_GROUP *group = NULL;               /* Group defines the used curve */
+    EC_KEY *eph_ec_key = NULL;            /* Ephemeral ec key of application */
+    const EC_POINT *eph_pub_key = NULL;   /* Public part of ephemeral key */
+    EC_POINT *tpm_pub_key = NULL;         /* Public part of TPM key */
+    BIGNUM *bn_x = NULL;
+    BIGNUM *bn_y = NULL;
+    size_t key_size;
+    int curveId;
+    size_t offset;
+
+    OpenSSL_add_all_algorithms();
+
+    /* Set ossl constant for curve type and create group for curve */
+    switch (key->publicArea.parameters.eccDetail.curveID) {
+    case TPM2_ECC_NIST_P192:
+        curveId = NID_X9_62_prime192v1;
+        key_size = 24;
+        break;
+    case TPM2_ECC_NIST_P224:
+        curveId = NID_secp224r1;
+        key_size = 38;
+        break;
+    case TPM2_ECC_NIST_P256:
+        curveId = NID_X9_62_prime256v1;
+        key_size = 32;
+        break;
+    case TPM2_ECC_NIST_P384:
+        curveId = NID_secp384r1;
+        key_size = 48;
+        break;
+    case TPM2_ECC_NIST_P521:
+        curveId = NID_secp521r1;
+        key_size = 66;
+        break;
+    default:
+        LOG_ERROR("ECC curve not implemented.");
+        return TSS2_ESYS_RC_NOT_IMPLEMENTED;
+    }
+
+    if (!(group = EC_GROUP_new_by_curve_name(curveId))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create group for curve", cleanup);
+    }
+
+    /* Create ephemeral key */
+    if (!(eph_ec_key = EC_KEY_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create ec key", cleanup);
+    }
+    if (1 !=   EC_KEY_set_group(eph_ec_key , group)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set group", cleanup);
+    }
+
+    if (1 != EC_KEY_generate_key(eph_ec_key)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Generate ec key", cleanup);
+    }
+
+    if (!(eph_pub_key =  EC_KEY_get0_public_key(eph_ec_key))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get public key", cleanup);
+    }
+
+    if (1 != EC_POINT_is_on_curve(group, eph_pub_key, bctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Ephemeral public key is on curve", cleanup);
+    }
+
+    /* Write affine coordinates of ephemeral pub key to TPM point Q */
+    if (!(bctx = BN_CTX_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create bignum context", cleanup);
+    }
+
+    if (!(bn_x = BN_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create bignum", cleanup);
+    }
+
+    if (!(bn_y = BN_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create bignum", cleanup);
+    }
+
+    if (1 != EC_POINT_get_affine_coordinates_GFp(group, eph_pub_key, bn_x,
+                                                 bn_y, bctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get affine x coordinate", cleanup);
+    }
+
+    if (1 != BN_bn2binpad(bn_x, &Q->x.buffer[0], key_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Write big num byte buffer", cleanup);
+    }
+
+    if (1 != BN_bn2binpad(bn_y, &Q->y.buffer[0], key_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Write big num byte buffer", cleanup);
+    }
+
+    Q->x.size = key_size;
+    Q->y.size = key_size;
+
+    /* Create an OSSL EC point from the TPM public point */
+    r = tpm_pub_to_ossl_pub(group, key, &tpm_pub_key);
+    goto_if_error(r, "Convert TPM pub point to ossl pub point", cleanup);
+
+    /* Multiply the ephemeral private key with TPM public key */
+    EC_POINT *mul_eph_tpm = NULL;
+    const BIGNUM * eph_priv_key = EC_KEY_get0_private_key(eph_ec_key);
+
+    if (!(mul_eph_tpm = EC_POINT_new(group))) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create point.", cleanup);
+    }
+
+    if (1 != EC_POINT_mul(group, mul_eph_tpm, NULL, tpm_pub_key, eph_priv_key, bctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "ec point multiplication", cleanup);
+    }
+
+    /* Write the x-part of the affine coordinate to Z */
+    if (1 != EC_POINT_get_affine_coordinates_GFp(group, mul_eph_tpm, bn_x,
+                                                 bn_y, bctx)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get affine x coordinate", cleanup);
+    }
+
+    if (1 != BN_bn2binpad(bn_x, &Z->buffer[0], key_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Write big num byte buffer", cleanup);
+    }
+
+    Z->size = key_size;
+
+    /* Write the public ephemeral key in TPM format to out buffer */
+    offset = 0;
+    r = Tss2_MU_TPMS_ECC_POINT_Marshal(Q,  &out_buffer[0], max_out_size, &offset);
+    goto_if_error(r, "Error marshaling", cleanup);
+    *out_size = offset;
+
+ cleanup:
+    OSSL_FREE(group,EC_GROUP);
+    OSSL_FREE(eph_ec_key, EC_KEY);
+    /* Note: free of eph_pub_key already done by free of eph_ec_key */
+    OSSL_FREE(bn_x, BN);
+    OSSL_FREE(bn_y, BN);
+    return r;
+}
+
+/** Encrypt data with AES.
+ *
+ * @param[in] key key used for AES.
+ * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
+ * @param[in] key_bits Key size in bits.
+ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB).
+ *            For parameter encryption only CFB can be used.
+ * @param[in] blk_len Length Block length of AES.
+ * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored
+ *                in this buffer.
+ * @param[in] buffer_size size of data to be encrypted.
+ * @param[in] iv The initialization vector. The size is equal to blk_len.
+ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_sym_aes_encrypt(uint8_t * key,
+                                TPM2_ALG_ID tpm_sym_alg,
+                                TPMI_AES_KEY_BITS key_bits,
+                                TPM2_ALG_ID tpm_mode,
+                                size_t blk_len,
+                                uint8_t * buffer,
+                                size_t buffer_size,
+                                uint8_t * iv)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    const EVP_CIPHER  *cipher_alg = NULL;
+    EVP_CIPHER_CTX *ctx = NULL;
+    int cipher_len;
+
+    /* Parameter blk_len needed for other crypto libraries */
+    (void)blk_len;
+
+    if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_128_cfb();
+    else if (key_bits == 192 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_192_cfb();
+    else if (key_bits == 256 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_256_cfb();
+    else {
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, "AES algorithm not implemented.", cleanup);
+    }
+
+    if (tpm_sym_alg != TPM2_ALG_AES) {
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, "AES encrypt called with wrong algorithm.", cleanup);
+    }
+
+    /* Create and initialize the context */
+    if(!(ctx = EVP_CIPHER_CTX_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Initialize cipher context", cleanup);
+    }
+    if (key == NULL || buffer == NULL) {
+        LOG_ERROR("Bad reference");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (1 != EVP_EncryptInit_ex(ctx, cipher_alg, get_engine(), key, iv)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Initialize cipher operation", cleanup);
+    }
+    if (1 != EVP_EncryptInit_ex(ctx, NULL, get_engine(), key, iv)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set key and iv", cleanup);
+    }
+
+    /* Perform the encryption */
+    if (1 != EVP_EncryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup);
+    }
+
+    if (1 != EVP_EncryptFinal_ex(ctx, buffer, &cipher_len)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup);
+    }
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input");
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output");
+
+ cleanup:
+
+    OSSL_FREE(ctx,EVP_CIPHER_CTX);
+
+    return r;
+}
+
+/** Decrypt data with AES.
+ *
+ * @param[in] key key used for AES.
+ * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES).
+ * @param[in] key_bits Key size in bits.
+ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB).
+ *            For parameter encryption only CFB can be used.
+ * @param[in] blk_len Length Block length of AES.
+ * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored
+ *                in this buffer.
+ * @param[in] buffer_size size of data to be encrypted.
+ * @param[in] iv The initialization vector. The size is equal to blk_len.
+ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters,
+ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
+ */
+TSS2_RC
+iesys_cryptossl_sym_aes_decrypt(uint8_t * key,
+                                TPM2_ALG_ID tpm_sym_alg,
+                                TPMI_AES_KEY_BITS key_bits,
+                                TPM2_ALG_ID tpm_mode,
+                                size_t blk_len,
+                                uint8_t * buffer,
+                                size_t buffer_size,
+                                uint8_t * iv)
+{
+    TSS2_RC r = TSS2_RC_SUCCESS;
+    const EVP_CIPHER *cipher_alg = NULL;
+    EVP_CIPHER_CTX *ctx = NULL;
+    int cipher_len = 0;
+
+    /* Parameter blk_len needed for other crypto libraries */
+    (void)blk_len;
+
+    if (tpm_sym_alg != TPM2_ALG_AES) {
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, "AES encrypt called with wrong algorithm.", cleanup);
+    }
+
+    if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_128_cfb();
+    else if (key_bits == 192 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_192_cfb();
+    else if (key_bits == 256 && tpm_mode == TPM2_ALG_CFB)
+        cipher_alg = EVP_aes_256_cfb();
+    else {
+
+        goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, "AES algorithm not implemented.", cleanup);
+    }
+
+    /* Create and initialize the context */
+    if(!(ctx = EVP_CIPHER_CTX_new())) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Initialize cipher context", cleanup);
+    }
+    if (key == NULL || buffer == NULL) {
+        LOG_ERROR("Bad reference");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
+
+    if (1 != EVP_DecryptInit_ex(ctx, cipher_alg, get_engine(), key, iv)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Initialize cipher operation", cleanup);
+    }
+
+    if (1 != EVP_DecryptInit_ex(ctx, NULL, get_engine(), key, iv)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set key and iv", cleanup);
+    }
+
+    /* Perform the decryption */
+    if (1 != EVP_DecryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup);
+    }
+
+    if (1 != EVP_DecryptFinal_ex(ctx, buffer, &cipher_len)) {
+        goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup);
+    }
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input");
+    LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output");
+
+ cleanup:
+
+    OSSL_FREE(ctx,EVP_CIPHER_CTX);
+    return r;
+}
diff --git a/src/tss2-esys/esys_crypto_ossl.h b/src/tss2-esys/esys_crypto_ossl.h
new file mode 100644
index 0000000..1519eda
--- /dev/null
+++ b/src/tss2-esys/esys_crypto_ossl.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+#ifndef ESYS_CRYPTO_OSSL_H
+#define ESYS_CRYPTO_OSSL_H
+
+#include <stddef.h>
+#include "tss2_tpm2_types.h"
+#include "tss2-sys/sysapi_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OSSL_FREE(S,TYPE) if((S) != NULL) {TYPE##_free((void*) (S)); (S)=NULL;}
+
+typedef struct _IESYS_CRYPTO_CONTEXT IESYS_CRYPTO_CONTEXT_BLOB;
+
+TSS2_RC iesys_cryptossl_hash_start(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hashAlg);
+
+TSS2_RC iesys_cryptossl_hash_update(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    const uint8_t *buffer, size_t size);
+
+TSS2_RC iesys_cryptossl_hash_update2b(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptossl_hash_finish(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    uint8_t *buffer,
+    size_t *size);
+
+TSS2_RC iesys_cryptossl_hash_finish2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2B *b);
+
+void iesys_cryptossl_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
+
+#define iesys_crypto_pk_encrypt iesys_cryptossl_pk_encrypt
+#define iesys_crypto_hash_start iesys_cryptossl_hash_start
+#define iesys_crypto_hash_update iesys_cryptossl_hash_update
+#define iesys_crypto_hash_update2b iesys_cryptossl_hash_update2b
+#define iesys_crypto_hash_finish iesys_cryptossl_hash_finish
+#define iesys_crypto_hash_finish2b iesys_cryptossl_hash_finish2b
+#define iesys_crypto_hash_abort iesys_cryptossl_hash_abort
+
+TSS2_RC iesys_cryptossl_hmac_start(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hmacAlg,
+    const uint8_t *key,
+    size_t size);
+
+TSS2_RC iesys_cryptossl_hmac_start2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2_ALG_ID hmacAlg,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptossl_hmac_update(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    const uint8_t *buffer,
+    size_t size);
+
+TSS2_RC iesys_cryptossl_hmac_update2b(
+    IESYS_CRYPTO_CONTEXT_BLOB *context,
+    TPM2B *b);
+
+TSS2_RC iesys_cryptossl_hmac_finish(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    uint8_t *buffer,
+    size_t *size);
+
+TSS2_RC iesys_cryptossl_hmac_finish2b(
+    IESYS_CRYPTO_CONTEXT_BLOB **context,
+    TPM2B *b);
+
+void iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB **context);
+
+#define iesys_crypto_hmac_start iesys_cryptossl_hmac_start
+#define iesys_crypto_hmac_start2b iesys_cryptossl_hmac_start2b
+#define iesys_crypto_hmac_update iesys_cryptossl_hmac_update
+#define iesys_crypto_hmac_update2b iesys_cryptossl_hmac_update2b
+#define iesys_crypto_hmac_finish iesys_cryptossl_hmac_finish
+#define iesys_crypto_hmac_finish2b iesys_cryptossl_hmac_finish2b
+#define iesys_crypto_hmac_abort iesys_cryptossl_hmac_abort
+
+TSS2_RC iesys_cryptossl_random2b(TPM2B_NONCE *nonce, size_t num_bytes);
+
+TSS2_RC iesys_cryptossl_pk_encrypt(
+    TPM2B_PUBLIC *key,
+    size_t in_size,
+    BYTE *in_buffer,
+    size_t max_out_size,
+    BYTE *out_buffer,
+    size_t *out_size,
+    const char *label);
+
+
+TSS2_RC iesys_cryptossl_sym_aes_encrypt(
+    uint8_t *key,
+    TPM2_ALG_ID tpm_sym_alg,
+    TPMI_AES_KEY_BITS key_bits,
+    TPM2_ALG_ID tpm_mode,
+    size_t blk_len,
+    uint8_t *dst,
+    size_t dst_size,
+    uint8_t *iv);
+
+TSS2_RC iesys_cryptossl_sym_aes_decrypt(
+    uint8_t *key,
+    TPM2_ALG_ID tpm_sym_alg,
+    TPMI_AES_KEY_BITS key_bits,
+    TPM2_ALG_ID tpm_mode,
+    size_t blk_len,
+    uint8_t *dst,
+    size_t dst_size,
+    uint8_t *iv);
+
+TSS2_RC iesys_cryptossl_get_ecdh_point(
+    TPM2B_PUBLIC *key,
+    size_t max_out_size,
+    TPM2B_ECC_PARAMETER *Z,
+    TPMS_ECC_POINT *Q,
+    BYTE * out_buffer,
+    size_t * out_size);
+
+#define iesys_crypto_random2b iesys_cryptossl_random2b
+#define iesys_crypto_get_ecdh_point iesys_cryptossl_get_ecdh_point
+#define iesys_crypto_sym_aes_encrypt iesys_cryptossl_sym_aes_encrypt
+#define iesys_crypto_sym_aes_decrypt iesys_cryptossl_sym_aes_decrypt
+
+#endif /* ESYS_CRYPTO_OSSL_H */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
diff --git a/src/tss2-esys/esys_iutil.c b/src/tss2-esys/esys_iutil.c
index a254d8a..f254b91 100644
--- a/src/tss2-esys/esys_iutil.c
+++ b/src/tss2-esys/esys_iutil.c
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: BSD-2 */
 /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
  * All rights reserved.
- *******************************************************************************/
+ ******************************************************************************/
 #include <inttypes.h>
 
 #include "tss2_esys.h"
@@ -504,12 +504,12 @@
         encryptedSalt->size = cSize;
 
         /* Compute salt from Z with KDFe */
-        r = iesys_cryptogcry_KDFe(tpmKeyNode->rsrc.misc.
-                                  rsrc_key_pub.publicArea.nameAlg,
-                                  &Z, "SECRET", &Q.x,
-                                  &pub.publicArea.unique.ecc.x,
-                                  keyHash_size*8,
-                                  &esys_context->salt.buffer[0]);
+        r = iesys_crypto_KDFe(tpmKeyNode->rsrc.misc.
+                              rsrc_key_pub.publicArea.nameAlg,
+                              &Z, "SECRET", &Q.x,
+                              &pub.publicArea.unique.ecc.x,
+                              keyHash_size*8,
+                              &esys_context->salt.buffer[0]);
         return_if_error(r, "During KDFe computation.");
         esys_context->salt.size = keyHash_size;
         break;
@@ -649,6 +649,7 @@
                                                     &encrypt_buffer[0],
                                                     paramSize);
                 return_if_error(r, "XOR obfuscation not possible.");
+
             } else {
                 return_error(TSS2_ESYS_RC_BAD_VALUE,
                              "Invalid symmetric algorithm (should be XOR or AES)");
@@ -656,6 +657,7 @@
             r = Tss2_Sys_SetDecryptParam(esys_context->sys, paramSize,
                                          &encrypt_buffer[0]);
             return_if_error(r, "Set encrypt parameter not possible");
+
         }
     }
     return r;
@@ -676,7 +678,7 @@
  * @retval TSS2_ESYS_RC_NOT_IMPLEMENTED if hash algorithm is not implemented.
  * @retval TSS2_SYS_RC_* for SAPI errors.
  */
-TSS2_RC
+ TSS2_RC
 iesys_decrypt_param(ESYS_CONTEXT * esys_context,
                     const uint8_t * rpBuffer, size_t rpBuffer_size)
 {
@@ -925,12 +927,12 @@
     /* Then if we are a bound session, the auth value is not appended to the end
        of the session value for HMAC computation. The size of the key will not be
        increased.*/
-    if (iesys_is_object_bound(name, auth_value,
+   if (iesys_is_object_bound(name, auth_value,
                               session) &&
         /* type_policy_session set to POLICY_AUTH by command PolicyAuthValue */
         (session->rsrc.misc.rsrc_session.type_policy_session != POLICY_AUTH))
         return;
-    session->rsrc.misc.rsrc_session.sizeHmacValue += auth_value->size;
+   session->rsrc.misc.rsrc_session.sizeHmacValue += auth_value->size;
 }
 
 /**
@@ -1037,7 +1039,7 @@
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    /* TODO: Check if RESUBMISSION BELONGS HERE OR IN THE FINISH METHOD. */
+    /* TODO: Check if RESUBMISSION BELONGS HERE OR RATHER INTO THE FINISH METHOD. */
     if (esys_context->state == _ESYS_STATE_RESUBMISSION) {
         esys_context->submissionCount++;
         LOG_DEBUG("The command will be resubmitted for the %i time.",
@@ -1355,7 +1357,7 @@
     r = iesys_crypto_hash_update(cryptoContext, &buffer[0], offset);
     return_if_error(r, "crypto hash update");
 
-    r = iesys_cryptogcry_hash_finish(&cryptoContext, &name->name[len_alg_id],
+    r = iesys_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
                                      &size);
     return_if_error(r, "crypto hash finish");
 
@@ -1403,7 +1405,7 @@
     r = iesys_crypto_hash_update(cryptoContext, &buffer[0], offset);
     return_if_error(r, "crypto hash update");
 
-    r = iesys_cryptogcry_hash_finish(&cryptoContext, &name->name[len_alg_id],
+    r = iesys_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
                                      &size);
     return_if_error(r, "crypto hash finish");
 
diff --git a/src/tss2-esys/esys_iutil.h b/src/tss2-esys/esys_iutil.h
index 1f9cb6d..6fbd374 100644
--- a/src/tss2-esys/esys_iutil.h
+++ b/src/tss2-esys/esys_iutil.h
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: BSD-2 */
 /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
  * All rights reserved.
- *******************************************************************************/
+ ******************************************************************************/
 #ifndef ESYS_IUTIL_H
 #define ESYS_IUTIL_H
 
@@ -63,9 +63,9 @@
         goto label;  \
     }
 
-#define goto_error(r,v,msg,label) \
+#define goto_error(r,v,msg,label, ...)              \
     { r = v;  \
-      LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
+      LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
       goto label; \
     }