From ce3e58a2d031aed838d05f259652d9852250ad53 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 24 Feb 2022 14:08:53 +0100 Subject: [PATCH] Use dlopen for loading libtss2* to avoid OpenSSL dependency Resolves: #2057490 Signed-off-by: Daiki Ueno --- gnutls-3.7.3-libtss2-dlopen.patch | 661 ++++++++++++++++++++++++++++++ gnutls.spec | 4 +- 2 files changed, 664 insertions(+), 1 deletion(-) create mode 100644 gnutls-3.7.3-libtss2-dlopen.patch diff --git a/gnutls-3.7.3-libtss2-dlopen.patch b/gnutls-3.7.3-libtss2-dlopen.patch new file mode 100644 index 0000000..49fe740 --- /dev/null +++ b/gnutls-3.7.3-libtss2-dlopen.patch @@ -0,0 +1,661 @@ +From 1719288f7e57d6b9593ef0c01fdcf7ac304c099f Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Wed, 23 Feb 2022 19:48:52 +0100 +Subject: [PATCH] tpm2: dynamically load tss2 libraries as needed + +libtss2-esys links to OpenSSL or mbed TLS for cryptography, which may +cause packaging issues. This instead dlopen's tss2 libraries as +needed so non-TPM applications continue working without loading +multiple crypto libraries. + +Signed-off-by: Daiki Ueno +--- + configure.ac | 12 +- + lib/Makefile.am | 6 +- + lib/tpm2.c | 2 +- + lib/tpm2.h | 2 +- + lib/tpm2_esys.c | 330 ++++++++++++++++++++++++++++++++++++++++++------ + 5 files changed, 303 insertions(+), 49 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 53c3aefca1..be51b376a6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -882,6 +882,8 @@ AM_CONDITIONAL(P11KIT_0_23_11_API, $PKG_CONFIG --atleast-version=0.23.11 p11-kit + + AM_CONDITIONAL(ENABLE_PKCS11, test "$with_p11_kit" != "no") + ++need_ltlibdl=no ++ + AC_ARG_WITH(tpm2, + AS_HELP_STRING([--without-tpm2], + [Disable TPM2 support.]), +@@ -889,9 +891,11 @@ AC_ARG_WITH(tpm2, + if test "$with_tpm2" != "no"; then + PKG_CHECK_MODULES(TSS2, [tss2-esys tss2-mu tss2-tctildr], + [have_tpm2=yes], [have_tpm2=no]) ++ PKG_CHECK_EXISTS([tss2-esys], , [have_tpm2=no]) + if test "$have_tpm2" = "yes"; then + tss2lib="tss2-esys tss2-mu tss2-tctildr" + AC_DEFINE([HAVE_TSS2], 1, [Have TSS2]) ++ need_ltlibdl=yes + elif test "$with_tpm2" = "yes"; then + AC_MSG_ERROR([[ + *** +@@ -920,7 +924,8 @@ if test "$with_tpm" != "no"; then + AC_SUBST([TSS_LIBS], [-ltspi]) + AC_SUBST([TSS_CFLAGS], []) + AC_DEFINE([HAVE_TROUSERS], 1, [Enable TPM]) +- with_tpm=yes], ++ with_tpm=yes, ++ need_ltlibdl=yes], + [AC_MSG_RESULT(no) + AC_MSG_WARN([[ + *** +@@ -957,6 +962,9 @@ fi + AC_DEFINE_UNQUOTED([TROUSERS_LIB], ["$ac_trousers_lib"], [the location of the trousers library]) + AC_SUBST(TROUSERS_LIB) + ++ ++AM_CONDITIONAL(NEED_LTLIBDL, test "$need_ltlibdl" = yes) ++ + # For minitasn1. + AC_CHECK_SIZEOF(unsigned long int, 4) + AC_CHECK_SIZEOF(unsigned int, 4) +@@ -1312,7 +1320,7 @@ AC_MSG_NOTICE([External hardware support: + Random gen. variant: $rnd_variant + PKCS#11 support: $with_p11_kit + TPM support: $with_tpm +- TPM2 support: $have_tpm2 ++ TPM2 support: $with_tpm2 + KTLS support: $enable_ktls + ]) + +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 35df35ee8d..e61ee1b6ae 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -44,7 +44,7 @@ AM_CPPFLAGS = \ + -I$(srcdir)/x509 \ + $(LIBTASN1_CFLAGS) \ + $(P11_KIT_CFLAGS) \ +- $(TPM2_CFLAGS) ++ $(TSS2_CFLAGS) + + if !HAVE_LIBUNISTRING + SUBDIRS += unistring +@@ -156,7 +156,7 @@ libgnutls_la_LIBADD = ../gl/libgnu.la x509/libgnutls_x509.la \ + auth/libgnutls_auth.la algorithms/libgnutls_alg.la \ + extras/libgnutls_extras.la + thirdparty_libadd = $(LTLIBZ) $(LTLIBINTL) $(LIBSOCKET) $(LTLIBNSL) \ +- $(P11_KIT_LIBS) $(LIB_SELECT) $(TSS2_LIBS) $(GNUTLS_LIBS_PRIVATE) ++ $(P11_KIT_LIBS) $(LIB_SELECT) $(GNUTLS_LIBS_PRIVATE) + + if HAVE_LIBIDN2 + thirdparty_libadd += $(LIBIDN2_LIBS) +@@ -203,7 +203,7 @@ all-local: $(hmac_files) + CLEANFILES = $(hmac_files) + endif + +-if ENABLE_TROUSERS ++if NEED_LTLIBDL + thirdparty_libadd += $(LTLIBDL) + endif + +diff --git a/lib/tpm2.c b/lib/tpm2.c +index 076cc7f407..750eadc777 100644 +--- a/lib/tpm2.c ++++ b/lib/tpm2.c +@@ -297,5 +297,5 @@ int _gnutls_load_tpm2_key(gnutls_privkey_t pkey, const gnutls_datum_t *fdata) + + void _gnutls_tpm2_deinit(void) + { +- tpm2_tcti_deinit(); ++ tpm2_esys_deinit(); + } +diff --git a/lib/tpm2.h b/lib/tpm2.h +index e40dc01df7..7966e2d811 100644 +--- a/lib/tpm2.h ++++ b/lib/tpm2.h +@@ -37,7 +37,7 @@ struct tpm2_info_st; + + struct tpm2_info_st *tpm2_info_init(struct pin_info_st *pin); + +-void tpm2_tcti_deinit(void); ++void tpm2_esys_deinit(void); + + void release_tpm2_ctx(struct tpm2_info_st *info); + +diff --git a/lib/tpm2_esys.c b/lib/tpm2_esys.c +index 93e54413ba..e1a54f12a1 100644 +--- a/lib/tpm2_esys.c ++++ b/lib/tpm2_esys.c +@@ -72,6 +72,217 @@ + #include + #include + ++#include ++ ++/* We don't want to link to libtss2-esys, as it brings in other ++ * crypto libraries. Instead, only dlopen it as needed. ++ */ ++ ++static void *_gnutls_tss2_esys_dlhandle; ++static void *_gnutls_tss2_mu_dlhandle; ++static void *_gnutls_tss2_tctildr_dlhandle; ++ ++#define DEFINE_TSS2_FUNC(sys, ret, func, args, argscall) \ ++ typedef ret(*_gnutls_tss2_##sys##_PTR_##func) args; \ ++ static _gnutls_tss2_##sys##_PTR_##func _g_##func = 0; \ ++ static inline ret _gnutls_tss2_##sys##_##func args \ ++ { \ ++ if (unlikely(!_g_##func)) { \ ++ _g_##func = dlsym(_gnutls_tss2_##sys##_dlhandle,\ ++ #func); \ ++ } \ ++ return _g_##func argscall; \ ++ } ++ ++DEFINE_TSS2_FUNC(esys, TSS2_RC, ++ Esys_GetCapability, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ TPM2_CAP capability, ++ UINT32 property, ++ UINT32 propertyCount, ++ TPMI_YES_NO *moreData, ++ TPMS_CAPABILITY_DATA **capabilityData), ++ (esysContext, ++ shandle1, ++ shandle2, ++ shandle3, ++ capability, ++ property, ++ propertyCount, ++ moreData, ++ capabilityData)) ++DEFINE_TSS2_FUNC(esys, void, Esys_Free, (void *__ptr), (__ptr)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_TR_SetAuth, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR handle, ++ TPM2B_AUTH const *authValue), ++ (esysContext, ++ handle, ++ authValue)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_CreatePrimary, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR primaryHandle, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ const TPM2B_SENSITIVE_CREATE *inSensitive, ++ const TPM2B_PUBLIC *inPublic, ++ const TPM2B_DATA *outsideInfo, ++ const TPML_PCR_SELECTION *creationPCR, ++ ESYS_TR *objectHandle, ++ TPM2B_PUBLIC **outPublic, ++ TPM2B_CREATION_DATA **creationData, ++ TPM2B_DIGEST **creationHash, ++ TPMT_TK_CREATION **creationTicket), ++ (esysContext, ++ primaryHandle, ++ shandle1, ++ shandle2, ++ shandle3, ++ inSensitive, ++ inPublic, ++ outsideInfo, ++ creationPCR, ++ objectHandle, ++ outPublic, ++ creationData, ++ creationHash, ++ creationTicket)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_Initialize, ++ (ESYS_CONTEXT **esys_context, ++ TSS2_TCTI_CONTEXT *tcti, ++ TSS2_ABI_VERSION *abiVersion), ++ (esys_context, ++ tcti, ++ abiVersion)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_Startup, ++ (ESYS_CONTEXT *esysContext, ++ TPM2_SU startupType), ++ (esysContext, ++ startupType)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_TR_FromTPMPublic, ++ (ESYS_CONTEXT *esysContext, ++ TPM2_HANDLE tpm_handle, ++ ESYS_TR optionalSession1, ++ ESYS_TR optionalSession2, ++ ESYS_TR optionalSession3, ++ ESYS_TR *object), ++ (esysContext, ++ tpm_handle, ++ optionalSession1, ++ optionalSession2, ++ optionalSession3, ++ object)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_ReadPublic, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR objectHandle, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ TPM2B_PUBLIC **outPublic, ++ TPM2B_NAME **name, ++ TPM2B_NAME **qualifiedName), ++ (esysContext, ++ objectHandle, ++ shandle1, ++ shandle2, ++ shandle3, ++ outPublic, ++ name, ++ qualifiedName)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_Load, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR parentHandle, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ const TPM2B_PRIVATE *inPrivate, ++ const TPM2B_PUBLIC *inPublic, ++ ESYS_TR *objectHandle), ++ (esysContext, ++ parentHandle, ++ shandle1, ++ shandle2, ++ shandle3, ++ inPrivate, ++ inPublic, ++ objectHandle)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_FlushContext, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR flushHandle), ++ (esysContext, ++ flushHandle)) ++DEFINE_TSS2_FUNC(esys, void, Esys_Finalize, (ESYS_CONTEXT **context), (context)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_RSA_Decrypt, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR keyHandle, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ const TPM2B_PUBLIC_KEY_RSA *cipherText, ++ const TPMT_RSA_DECRYPT *inScheme, ++ const TPM2B_DATA *label, ++ TPM2B_PUBLIC_KEY_RSA **message), ++ (esysContext, ++ keyHandle, ++ shandle1, ++ shandle2, ++ shandle3, ++ cipherText, ++ inScheme, ++ label, ++ message)) ++DEFINE_TSS2_FUNC(esys, TSS2_RC, Esys_Sign, ++ (ESYS_CONTEXT *esysContext, ++ ESYS_TR keyHandle, ++ ESYS_TR shandle1, ++ ESYS_TR shandle2, ++ ESYS_TR shandle3, ++ const TPM2B_DIGEST *digest, ++ const TPMT_SIG_SCHEME *inScheme, ++ const TPMT_TK_HASHCHECK *validation, ++ TPMT_SIGNATURE **signature), ++ (esysContext, ++ keyHandle, ++ shandle1, ++ shandle2, ++ shandle3, ++ digest, ++ inScheme, ++ validation, ++ signature)) ++ ++DEFINE_TSS2_FUNC(mu, TSS2_RC, Tss2_MU_TPM2B_PRIVATE_Unmarshal, ++ (uint8_t const buffer[], ++ size_t buffer_size, ++ size_t *offset, ++ TPM2B_PRIVATE *dest), ++ (buffer, ++ buffer_size, ++ offset, ++ dest)) ++DEFINE_TSS2_FUNC(mu, TSS2_RC, Tss2_MU_TPM2B_PUBLIC_Unmarshal, ++ (uint8_t const buffer[], ++ size_t buffer_size, ++ size_t *offset, ++ TPM2B_PUBLIC *dest), ++ (buffer, ++ buffer_size, ++ offset, ++ dest)) ++ ++DEFINE_TSS2_FUNC(tctildr, TSS2_RC, Tss2_TctiLdr_Initialize, ++ (const char *nameConf, ++ TSS2_TCTI_CONTEXT **context), ++ (nameConf, ++ context)) ++DEFINE_TSS2_FUNC(tctildr, void, Tss2_TctiLdr_Finalize, ++ (TSS2_TCTI_CONTEXT **context), ++ (context)) ++ + struct tpm2_info_st { + TPM2B_PUBLIC pub; + TPM2B_PRIVATE priv; +@@ -227,10 +438,10 @@ get_primary_template(ESYS_CONTEXT *ctx) + UINT32 i; + TSS2_RC rc; + +- rc = Esys_GetCapability (ctx, +- ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, +- TPM2_CAP_ALGS, 0, TPM2_MAX_CAP_ALGS, +- NULL, &capability_data); ++ rc = _gnutls_tss2_esys_Esys_GetCapability(ctx, ++ ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, ++ TPM2_CAP_ALGS, 0, TPM2_MAX_CAP_ALGS, ++ NULL, &capability_data); + if (rc) { + _gnutls_debug_log("tpm2: Esys_GetCapability failed: 0x%x\n", rc); + return NULL; +@@ -239,7 +450,7 @@ get_primary_template(ESYS_CONTEXT *ctx) + for (i = 0; i < capability_data->data.algorithms.count; i++) { + if (capability_data->data.algorithms.algProperties[i].alg == + TPM2_ALG_ECC) { +- Esys_Free(capability_data); ++ _gnutls_tss2_esys_Esys_Free(capability_data); + return &primary_template_ecc; + } + } +@@ -247,12 +458,12 @@ get_primary_template(ESYS_CONTEXT *ctx) + for (i = 0; i < capability_data->data.algorithms.count; i++) { + if (capability_data->data.algorithms.algProperties[i].alg == + TPM2_ALG_RSA) { +- Esys_Free(capability_data); ++ _gnutls_tss2_esys_Esys_Free(capability_data); + return &primary_template_rsa; + } + } + +- Esys_Free(capability_data); ++ _gnutls_tss2_esys_Esys_Free(capability_data); + _gnutls_debug_log("tpm2: unable to find primary template\n"); + return NULL; + } +@@ -320,7 +531,7 @@ static int init_tpm2_primary(struct tpm2_info_st *info, + install_tpm_passphrase(&info->ownerauth, pass); + info->need_ownerauth = false; + } +- rc = Esys_TR_SetAuth(ctx, hierarchy, &info->ownerauth); ++ rc = _gnutls_tss2_esys_Esys_TR_SetAuth(ctx, hierarchy, &info->ownerauth); + if (rc) { + _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", rc); + return gnutls_assert_val(GNUTLS_E_TPM_ERROR); +@@ -329,7 +540,7 @@ static int init_tpm2_primary(struct tpm2_info_st *info, + if (!primary_template) { + return gnutls_assert_val(GNUTLS_E_TPM_ERROR); + } +- rc = Esys_CreatePrimary(ctx, hierarchy, ++ rc = _gnutls_tss2_esys_Esys_CreatePrimary(ctx, hierarchy, + ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, + &primary_sensitive, + primary_template, +@@ -355,18 +566,39 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + ESYS_TR parent_handle = ESYS_TR_NONE; + TSS2_RC rc; + ++ if (!_gnutls_tss2_esys_dlhandle) { ++ _gnutls_tss2_esys_dlhandle = ++ dlopen("libtss2-esys.so.0", RTLD_NOW | RTLD_GLOBAL); ++ if (!_gnutls_tss2_esys_dlhandle) { ++ _gnutls_debug_log("tpm2: unable to dlopen libtss2-esys\n"); ++ goto error; ++ } ++ _gnutls_tss2_mu_dlhandle = ++ dlopen("libtss2-mu.so.0", RTLD_NOW | RTLD_GLOBAL); ++ if (!_gnutls_tss2_mu_dlhandle) { ++ _gnutls_debug_log("tpm2: unable to dlopen libtss2-mu\n"); ++ goto error; ++ } ++ _gnutls_tss2_tctildr_dlhandle = ++ dlopen("libtss2-tctildr.so.0", RTLD_NOW | RTLD_GLOBAL); ++ if (!_gnutls_tss2_tctildr_dlhandle) { ++ _gnutls_debug_log("tpm2: unable to dlopen libtss2-tctildr\n"); ++ goto error; ++ } ++ } ++ + *key_handle = ESYS_TR_NONE; + + _gnutls_debug_log("tpm2: establishing connection with TPM\n"); + +- rc = Esys_Initialize(ctx, tcti_ctx, NULL); ++ rc = _gnutls_tss2_esys_Esys_Initialize(ctx, tcti_ctx, NULL); + if (rc) { + gnutls_assert(); + _gnutls_debug_log("tpm2: Esys_Initialize failed: 0x%x\n", rc); + goto error; + } + +- rc = Esys_Startup(*ctx, TPM2_SU_CLEAR); ++ rc = _gnutls_tss2_esys_Esys_Startup(*ctx, TPM2_SU_CLEAR); + if (rc == TPM2_RC_INITIALIZE) { + _gnutls_debug_log("tpm2: was already started up thus false positive failing in tpm2tss log\n"); + } else if (rc) { +@@ -381,7 +613,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + goto error; + } + } else { +- rc = Esys_TR_FromTPMPublic(*ctx, info->parent, ++ rc = _gnutls_tss2_esys_Esys_TR_FromTPMPublic(*ctx, info->parent, + ESYS_TR_NONE, + ESYS_TR_NONE, + ESYS_TR_NONE, +@@ -399,7 +631,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + if (!info->did_ownerauth && !info->ownerauth.size) { + TPM2B_PUBLIC *pub = NULL; + +- rc = Esys_ReadPublic(*ctx, parent_handle, ++ rc = _gnutls_tss2_esys_Esys_ReadPublic(*ctx, parent_handle, + ESYS_TR_NONE, + ESYS_TR_NONE, + ESYS_TR_NONE, +@@ -408,7 +640,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + !(pub->publicArea.objectAttributes & TPMA_OBJECT_NODA)) { + info->need_ownerauth = true; + } +- Esys_Free(pub); ++ _gnutls_tss2_esys_Esys_Free(pub); + } + reauth: + if (info->need_ownerauth) { +@@ -420,7 +652,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + install_tpm_passphrase(&info->ownerauth, pass); + info->need_ownerauth = false; + } +- rc = Esys_TR_SetAuth(*ctx, parent_handle, &info->ownerauth); ++ rc = _gnutls_tss2_esys_Esys_TR_SetAuth(*ctx, parent_handle, &info->ownerauth); + if (rc) { + gnutls_assert(); + _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", +@@ -432,7 +664,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + _gnutls_debug_log("tpm2: loading TPM2 key blob, parent handle 0x%x\n", + parent_handle); + +- rc = Esys_Load(*ctx, parent_handle, ++ rc = _gnutls_tss2_esys_Esys_Load(*ctx, parent_handle, + ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, + &info->priv, &info->pub, + key_handle); +@@ -450,7 +682,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + info->did_ownerauth = true; + + if (parent_is_generated(info->parent)) { +- rc = Esys_FlushContext(*ctx, parent_handle); ++ rc = _gnutls_tss2_esys_Esys_FlushContext(*ctx, parent_handle); + if (rc) { + _gnutls_debug_log("tpm2: Esys_FlushContext for generated primary failed: 0x%x\n", + rc); +@@ -461,14 +693,14 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, + return 0; + error: + if (parent_is_generated(info->parent) && parent_handle != ESYS_TR_NONE) { +- Esys_FlushContext(*ctx, parent_handle); ++ _gnutls_tss2_esys_Esys_FlushContext(*ctx, parent_handle); + } + if (*key_handle != ESYS_TR_NONE) { +- Esys_FlushContext(*ctx, *key_handle); ++ _gnutls_tss2_esys_Esys_FlushContext(*ctx, *key_handle); + } + *key_handle = ESYS_TR_NONE; + +- Esys_Finalize(ctx); ++ _gnutls_tss2_esys_Esys_Finalize(ctx); + return GNUTLS_E_TPM_ERROR; + } + +@@ -488,7 +720,7 @@ auth_tpm2_key(struct tpm2_info_st *info, ESYS_CONTEXT *ctx, ESYS_TR key_handle) + info->need_userauth = false; + } + +- rc = Esys_TR_SetAuth(ctx, key_handle, &info->userauth); ++ rc = _gnutls_tss2_esys_Esys_TR_SetAuth(ctx, key_handle, &info->userauth); + if (rc) { + _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", rc); + return gnutls_assert_val(GNUTLS_E_TPM_ERROR); +@@ -574,7 +806,7 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, + goto out; + } + +- rc = Esys_RSA_Decrypt(ectx, key_handle, ++ rc = _gnutls_tss2_esys_Esys_RSA_Decrypt(ectx, key_handle, + ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, + &digest, &in_scheme, &label, &tsig); + if (rc_is_key_auth_failed(rc)) { +@@ -591,14 +823,14 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, + + ret = _gnutls_set_datum(sig, tsig->buffer, tsig->size); + out: +- Esys_Free(tsig); ++ _gnutls_tss2_esys_Esys_Free(tsig); + + if (key_handle != ESYS_TR_NONE) { +- Esys_FlushContext(ectx, key_handle); ++ _gnutls_tss2_esys_Esys_FlushContext(ectx, key_handle); + } + + if (ectx) { +- Esys_Finalize(&ectx); ++ _gnutls_tss2_esys_Esys_Finalize(&ectx); + } + + return ret; +@@ -661,7 +893,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, + goto out; + } + +- rc = Esys_Sign(ectx, key_handle, ++ rc = _gnutls_tss2_esys_Esys_Sign(ectx, key_handle, + ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, + &digest, &in_scheme, &validation, + &tsig); +@@ -682,14 +914,14 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, + + ret = gnutls_encode_rs_value(sig, &sig_r, &sig_s); + out: +- Esys_Free(tsig); ++ _gnutls_tss2_esys_Esys_Free(tsig); + + if (key_handle != ESYS_TR_NONE) { +- Esys_FlushContext(ectx, key_handle); ++ _gnutls_tss2_esys_Esys_FlushContext(ectx, key_handle); + } + + if (ectx) { +- Esys_Finalize(&ectx); ++ _gnutls_tss2_esys_Esys_Finalize(&ectx); + } + + return ret; +@@ -697,14 +929,6 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, + + GNUTLS_ONCE(tcti_once); + +-void +-tpm2_tcti_deinit(void) +-{ +- if (tcti_ctx) { +- Tss2_TctiLdr_Finalize(&tcti_ctx); +- } +-} +- + static void + tcti_once_init(void) + { +@@ -727,7 +951,7 @@ tcti_once_init(void) + } + } + if (tcti && *tcti != '\0') { +- rc = Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); ++ rc = _gnutls_tss2_tctildr_Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); + if (rc) { + _gnutls_debug_log("tpm2: TSS2_TctiLdr_Initialize failed: 0x%x\n", + rc); +@@ -735,6 +959,28 @@ tcti_once_init(void) + } + } + ++/* called by the global destructor through _gnutls_tpm2_deinit */ ++void ++tpm2_esys_deinit(void) ++{ ++ if (tcti_ctx) { ++ _gnutls_tss2_tctildr_Tss2_TctiLdr_Finalize(&tcti_ctx); ++ tcti_ctx = NULL; ++ } ++ if (_gnutls_tss2_esys_dlhandle) { ++ dlclose(_gnutls_tss2_esys_dlhandle); ++ _gnutls_tss2_esys_dlhandle = NULL; ++ } ++ if (_gnutls_tss2_mu_dlhandle) { ++ dlclose(_gnutls_tss2_mu_dlhandle); ++ _gnutls_tss2_mu_dlhandle = NULL; ++ } ++ if (_gnutls_tss2_tctildr_dlhandle) { ++ dlclose(_gnutls_tss2_tctildr_dlhandle); ++ _gnutls_tss2_tctildr_dlhandle = NULL; ++ } ++} ++ + int install_tpm2_key(struct tpm2_info_st *info, gnutls_privkey_t pkey, + unsigned int parent, bool emptyauth, + gnutls_datum_t *privdata, gnutls_datum_t *pubdata) +@@ -757,16 +1003,16 @@ int install_tpm2_key(struct tpm2_info_st *info, gnutls_privkey_t pkey, + + info->parent = parent; + +- rc = Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL, +- &info->priv); ++ rc = _gnutls_tss2_mu_Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL, ++ &info->priv); + if (rc) { + _gnutls_debug_log("tpm2: failed to import private key data: 0x%x\n", + rc); + return gnutls_assert_val(GNUTLS_E_TPM_ERROR); + } + +- rc = Tss2_MU_TPM2B_PUBLIC_Unmarshal(pubdata->data, pubdata->size, NULL, +- &info->pub); ++ rc = _gnutls_tss2_mu_Tss2_MU_TPM2B_PUBLIC_Unmarshal(pubdata->data, pubdata->size, NULL, ++ &info->pub); + if (rc) { + _gnutls_debug_log("tpm2: failed to import public key data: 0x%x\n", + rc); +-- +2.34.1 + diff --git a/gnutls.spec b/gnutls.spec index b89626e..cc33116 100644 --- a/gnutls.spec +++ b/gnutls.spec @@ -25,11 +25,12 @@ Patch8: gnutls-3.7.3-fix-tests-in-fips.patch Patch9: gnutls-3.7.3-gost-ifdef.patch Patch10: gnutls-3.7.3-max-algos.patch Patch11: gnutls-3.7.3-allowlist-api.patch +Patch12: gnutls-3.7.3-libtss2-dlopen.patch # not upstreamed Patch100: gnutls-3.7.3-disable-config-reload.patch -%bcond_with bootstrap +%bcond_without bootstrap %bcond_without dane %if 0%{?rhel} %bcond_with guile @@ -345,6 +346,7 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null * Wed Feb 23 2022 Daiki Ueno - 3.7.3-7 - Increase GNUTLS_MAX_ALGORITHM_NUM for allowlisting (#2033220) - Ensure allowlisting API is called before priority string is constructed (#2042532) +- Use dlopen for loading libtss2* to avoid OpenSSL dependency (#2057490) * Tue Feb 22 2022 Daiki Ueno - 3.7.3-6 - Compile out GOST algorithm IDs (#1945292)