You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
719 lines
23 KiB
719 lines
23 KiB
From f5e5ab910b8b1d69f962ca033d1295c3e1e1e131 Mon Sep 17 00:00:00 2001 |
|
From: Daiki Ueno <ueno@gnu.org> |
|
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 <ueno@gnu.org> |
|
--- |
|
configure.ac | 11 +- |
|
lib/Makefile.am | 6 +- |
|
lib/tpm2.c | 2 +- |
|
lib/tpm2.h | 2 +- |
|
lib/tpm2_esys.c | 273 ++++++++++++++++++++++++++++++++++++-------- |
|
tests/Makefile.am | 3 +- |
|
tests/sanity-lib.sh | 40 +++++++ |
|
tests/tpm2.sh | 14 ++- |
|
8 files changed, 296 insertions(+), 55 deletions(-) |
|
create mode 100644 tests/sanity-lib.sh |
|
|
|
diff --git a/configure.ac b/configure.ac |
|
index 53c3aefca1..721ff208f0 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.]), |
|
@@ -892,6 +894,7 @@ if test "$with_tpm2" != "no"; then |
|
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 +923,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 +961,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 +1319,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..4000c1b76e 100644 |
|
--- a/lib/tpm2_esys.c |
|
+++ b/lib/tpm2_esys.c |
|
@@ -72,6 +72,170 @@ |
|
#include <tss2/tss2_esys.h> |
|
#include <tss2/tss2_tctildr.h> |
|
|
|
+#include <dlfcn.h> |
|
+ |
|
+/* 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; |
|
+ |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_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); |
|
+static void (*_gnutls_tss2_Esys_Free)(void *__ptr); |
|
+static TSS2_RC (*_gnutls_tss2_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, |
|
+ ESYS_TR handle, |
|
+ TPM2B_AUTH const *authValue); |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_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); |
|
+static TSS2_RC (*_gnutls_tss2_Esys_Initialize)(ESYS_CONTEXT **esys_context, |
|
+ TSS2_TCTI_CONTEXT *tcti, |
|
+ TSS2_ABI_VERSION *abiVersion); |
|
+static TSS2_RC (*_gnutls_tss2_Esys_Startup)(ESYS_CONTEXT *esysContext, |
|
+ TPM2_SU startupType); |
|
+static TSS2_RC (*_gnutls_tss2_Esys_TR_FromTPMPublic)(ESYS_CONTEXT *esysContext, |
|
+ TPM2_HANDLE tpm_handle, |
|
+ ESYS_TR optionalSession1, |
|
+ ESYS_TR optionalSession2, |
|
+ ESYS_TR optionalSession3, |
|
+ ESYS_TR *object); |
|
+static TSS2_RC (*_gnutls_tss2_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); |
|
+static TSS2_RC (*_gnutls_tss2_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); |
|
+static TSS2_RC (*_gnutls_tss2_Esys_FlushContext)(ESYS_CONTEXT *esysContext, |
|
+ ESYS_TR flushHandle); |
|
+static void (*_gnutls_tss2_Esys_Finalize)(ESYS_CONTEXT **context); |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_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); |
|
+static TSS2_RC (*_gnutls_tss2_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); |
|
+ |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], |
|
+ size_t buffer_size, |
|
+ size_t *offset, |
|
+ TPM2B_PRIVATE *dest); |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], |
|
+ size_t buffer_size, |
|
+ size_t *offset, |
|
+ TPM2B_PUBLIC *dest); |
|
+ |
|
+static TSS2_RC |
|
+(*_gnutls_tss2_Tss2_TctiLdr_Initialize)(const char *nameConf, |
|
+ TSS2_TCTI_CONTEXT **context); |
|
+static void (*_gnutls_tss2_Tss2_TctiLdr_Finalize)(TSS2_TCTI_CONTEXT **context); |
|
+ |
|
+#define DLSYM_TSS2(sys, sym) \ |
|
+ _gnutls_tss2_##sym = dlsym(_gnutls_tss2_##sys##_dlhandle, #sym); \ |
|
+ if (!_gnutls_tss2_##sym) { \ |
|
+ return -1; \ |
|
+ } |
|
+ |
|
+static int |
|
+init_tss2_funcs(void) |
|
+{ |
|
+ 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"); |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ |
|
+ DLSYM_TSS2(esys, Esys_GetCapability) |
|
+ DLSYM_TSS2(esys, Esys_Free) |
|
+ DLSYM_TSS2(esys, Esys_TR_SetAuth) |
|
+ DLSYM_TSS2(esys, Esys_CreatePrimary) |
|
+ DLSYM_TSS2(esys, Esys_Initialize) |
|
+ DLSYM_TSS2(esys, Esys_Startup) |
|
+ DLSYM_TSS2(esys, Esys_TR_FromTPMPublic) |
|
+ DLSYM_TSS2(esys, Esys_ReadPublic) |
|
+ DLSYM_TSS2(esys, Esys_Load) |
|
+ DLSYM_TSS2(esys, Esys_FlushContext) |
|
+ DLSYM_TSS2(esys, Esys_Finalize) |
|
+ DLSYM_TSS2(esys, Esys_RSA_Decrypt) |
|
+ DLSYM_TSS2(esys, Esys_Sign) |
|
+ |
|
+ if (!_gnutls_tss2_mu_dlhandle) { |
|
+ _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"); |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ |
|
+ DLSYM_TSS2(mu, Tss2_MU_TPM2B_PRIVATE_Unmarshal) |
|
+ DLSYM_TSS2(mu, Tss2_MU_TPM2B_PUBLIC_Unmarshal) |
|
+ |
|
+ if (!_gnutls_tss2_tctildr_dlhandle) { |
|
+ _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"); |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ |
|
+ DLSYM_TSS2(tctildr, Tss2_TctiLdr_Initialize) |
|
+ DLSYM_TSS2(tctildr, Tss2_TctiLdr_Finalize) |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
struct tpm2_info_st { |
|
TPM2B_PUBLIC pub; |
|
TPM2B_PRIVATE priv; |
|
@@ -227,10 +391,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_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 +403,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_Free(capability_data); |
|
return &primary_template_ecc; |
|
} |
|
} |
|
@@ -247,12 +411,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_Free(capability_data); |
|
return &primary_template_rsa; |
|
} |
|
} |
|
|
|
- Esys_Free(capability_data); |
|
+ _gnutls_tss2_Esys_Free(capability_data); |
|
_gnutls_debug_log("tpm2: unable to find primary template\n"); |
|
return NULL; |
|
} |
|
@@ -320,7 +484,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_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 +493,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_CreatePrimary(ctx, hierarchy, |
|
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, |
|
&primary_sensitive, |
|
primary_template, |
|
@@ -359,14 +523,14 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, |
|
|
|
_gnutls_debug_log("tpm2: establishing connection with TPM\n"); |
|
|
|
- rc = Esys_Initialize(ctx, tcti_ctx, NULL); |
|
+ rc = _gnutls_tss2_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_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 +545,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_TR_FromTPMPublic(*ctx, info->parent, |
|
ESYS_TR_NONE, |
|
ESYS_TR_NONE, |
|
ESYS_TR_NONE, |
|
@@ -399,7 +563,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_ReadPublic(*ctx, parent_handle, |
|
ESYS_TR_NONE, |
|
ESYS_TR_NONE, |
|
ESYS_TR_NONE, |
|
@@ -408,7 +572,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_Free(pub); |
|
} |
|
reauth: |
|
if (info->need_ownerauth) { |
|
@@ -420,7 +584,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_TR_SetAuth(*ctx, parent_handle, &info->ownerauth); |
|
if (rc) { |
|
gnutls_assert(); |
|
_gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", |
|
@@ -432,7 +596,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_Load(*ctx, parent_handle, |
|
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, |
|
&info->priv, &info->pub, |
|
key_handle); |
|
@@ -450,7 +614,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_FlushContext(*ctx, parent_handle); |
|
if (rc) { |
|
_gnutls_debug_log("tpm2: Esys_FlushContext for generated primary failed: 0x%x\n", |
|
rc); |
|
@@ -461,14 +625,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_FlushContext(*ctx, parent_handle); |
|
} |
|
if (*key_handle != ESYS_TR_NONE) { |
|
- Esys_FlushContext(*ctx, *key_handle); |
|
+ _gnutls_tss2_Esys_FlushContext(*ctx, *key_handle); |
|
} |
|
*key_handle = ESYS_TR_NONE; |
|
|
|
- Esys_Finalize(ctx); |
|
+ _gnutls_tss2_Esys_Finalize(ctx); |
|
return GNUTLS_E_TPM_ERROR; |
|
} |
|
|
|
@@ -488,7 +652,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_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 +738,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_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 +755,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_Free(tsig); |
|
|
|
if (key_handle != ESYS_TR_NONE) { |
|
- Esys_FlushContext(ectx, key_handle); |
|
+ _gnutls_tss2_Esys_FlushContext(ectx, key_handle); |
|
} |
|
|
|
if (ectx) { |
|
- Esys_Finalize(&ectx); |
|
+ _gnutls_tss2_Esys_Finalize(&ectx); |
|
} |
|
|
|
return ret; |
|
@@ -661,7 +825,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_Sign(ectx, key_handle, |
|
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, |
|
&digest, &in_scheme, &validation, |
|
&tsig); |
|
@@ -682,31 +846,23 @@ 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_Free(tsig); |
|
|
|
if (key_handle != ESYS_TR_NONE) { |
|
- Esys_FlushContext(ectx, key_handle); |
|
+ _gnutls_tss2_Esys_FlushContext(ectx, key_handle); |
|
} |
|
|
|
if (ectx) { |
|
- Esys_Finalize(&ectx); |
|
+ _gnutls_tss2_Esys_Finalize(&ectx); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
-GNUTLS_ONCE(tcti_once); |
|
- |
|
-void |
|
-tpm2_tcti_deinit(void) |
|
-{ |
|
- if (tcti_ctx) { |
|
- Tss2_TctiLdr_Finalize(&tcti_ctx); |
|
- } |
|
-} |
|
+GNUTLS_ONCE(tpm2_esys_once); |
|
|
|
static void |
|
-tcti_once_init(void) |
|
+tpm2_esys_once_init(void) |
|
{ |
|
const char *tcti; |
|
const char * const tcti_vars[] = { |
|
@@ -718,6 +874,11 @@ tcti_once_init(void) |
|
size_t i; |
|
TSS2_RC rc; |
|
|
|
+ if (init_tss2_funcs() < 0) { |
|
+ _gnutls_debug_log("tpm2: unable to initialize TSS2 functions\n"); |
|
+ return; |
|
+ } |
|
+ |
|
for (i = 0; i < sizeof(tcti_vars) / sizeof(tcti_vars[0]); i++) { |
|
tcti = secure_getenv(tcti_vars[i]); |
|
if (tcti && *tcti != '\0') { |
|
@@ -727,7 +888,7 @@ tcti_once_init(void) |
|
} |
|
} |
|
if (tcti && *tcti != '\0') { |
|
- rc = Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); |
|
+ rc = _gnutls_tss2_Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); |
|
if (rc) { |
|
_gnutls_debug_log("tpm2: TSS2_TctiLdr_Initialize failed: 0x%x\n", |
|
rc); |
|
@@ -735,13 +896,35 @@ tcti_once_init(void) |
|
} |
|
} |
|
|
|
+/* called by the global destructor through _gnutls_tpm2_deinit */ |
|
+void |
|
+tpm2_esys_deinit(void) |
|
+{ |
|
+ if (tcti_ctx) { |
|
+ _gnutls_tss2_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) |
|
{ |
|
TSS2_RC rc; |
|
|
|
- (void)gnutls_once(&tcti_once, tcti_once_init); |
|
+ (void)gnutls_once(&tpm2_esys_once, tpm2_esys_once_init); |
|
|
|
if (!tcti_ctx) { |
|
return gnutls_assert_val(GNUTLS_E_TPM_ERROR); |
|
@@ -757,16 +940,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_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_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); |
|
diff --git a/tests/Makefile.am b/tests/Makefile.am |
|
index 529f1cc077..64ce470a02 100644 |
|
--- a/tests/Makefile.am |
|
+++ b/tests/Makefile.am |
|
@@ -515,7 +515,8 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start |
|
psktool.sh ocsp-tests/ocsp-load-chain.sh gnutls-cli-save-data.sh gnutls-cli-debug.sh \ |
|
sni-resume.sh ocsp-tests/ocsptool.sh cert-reencoding.sh pkcs7-cat.sh long-crl.sh \ |
|
serv-udp.sh logfile-option.sh gnutls-cli-resume.sh profile-tests.sh \ |
|
- server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh |
|
+ server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh \ |
|
+ sanity-lib.sh |
|
|
|
if !DISABLE_SYSTEM_CONFIG |
|
dist_check_SCRIPTS += system-override-sig.sh system-override-hash.sh \ |
|
diff --git a/tests/sanity-lib.sh b/tests/sanity-lib.sh |
|
new file mode 100644 |
|
index 0000000000..1e3612781b |
|
--- /dev/null |
|
+++ b/tests/sanity-lib.sh |
|
@@ -0,0 +1,40 @@ |
|
+#!/bin/sh |
|
+ |
|
+# Copyright (C) 2022 Red Hat, Inc. |
|
+# |
|
+# Author: Daiki Ueno |
|
+# |
|
+# This file is part of GnuTLS. |
|
+# |
|
+# GnuTLS is free software; you can redistribute it and/or modify it |
|
+# under the terms of the GNU General Public License as published by the |
|
+# Free Software Foundation; either version 3 of the License, or (at |
|
+# your option) any later version. |
|
+# |
|
+# GnuTLS is distributed in the hope that it will be useful, but |
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
+# General Public License for more details. |
|
+# |
|
+# You should have received a copy of the GNU Lesser General Public License |
|
+# along with this program. If not, see <https://www.gnu.org/licenses/> |
|
+ |
|
+: ${top_builddir=..} |
|
+: ${CLI_DEBUG=../src/gnutls-cli-debug${EXEEXT}} |
|
+: ${LDD=ldd} |
|
+: ${LIBTOOL=libtool} |
|
+ |
|
+if ! test -x "${CLI_DEBUG}"; then |
|
+ exit 77 |
|
+fi |
|
+ |
|
+# ldd.sh doesn't check recursive dependencies |
|
+${LDD} --version >/dev/null || exit 77 |
|
+ |
|
+# We use gnutls-cli-debug, as it has the fewest dependencies among our |
|
+# commands (e.g., gnutls-cli pulls in OpenSSL through libunbound). |
|
+if ${LIBTOOL} --mode=execute ${LDD} ${CLI_DEBUG} | \ |
|
+ grep '^[[:space:]]*\(libcrypto\.\|libssl\.\|libgcrypt\.\)'; then |
|
+ echo "gnutls-cli-debug links to other crypto library" |
|
+ exit 1 |
|
+fi |
|
diff --git a/tests/tpm2.sh b/tests/tpm2.sh |
|
index 854986c552..6f8e44c64b 100755 |
|
--- a/tests/tpm2.sh |
|
+++ b/tests/tpm2.sh |
|
@@ -21,8 +21,6 @@ |
|
# along with GnuTLS; if not, write to the Free Software Foundation, |
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
|
|
-set +e |
|
- |
|
: ${srcdir=.} |
|
: ${CERTTOOL=../src/certtool${EXEEXT}} |
|
KEYPEMFILE=tpmkey.$$.key.pem |
|
@@ -192,6 +190,10 @@ run_tests() |
|
|
|
echo " - Generating ${KEYPEMFILE}" |
|
tpm2tss-genkey -a ${kalg} -o ${OPASS} ${KEYPEMFILE} |
|
+ if [ $? -ne 0 ]; then |
|
+ echo "unable to generate key" |
|
+ return 1 |
|
+ fi |
|
cat ${KEYPEMFILE} |
|
|
|
echo " - Generating certificate based on key" |
|
@@ -200,6 +202,10 @@ run_tests() |
|
"${CERTTOOL}" --generate-self-signed -d 3 \ |
|
--load-privkey "${KEYPEMFILE}" \ |
|
--template "${srcdir}/cert-tests/templates/template-test.tmpl" |
|
+ if [ $? -ne 0 ]; then |
|
+ echo "unable to generate certificate" |
|
+ return 1 |
|
+ fi |
|
|
|
if test "${kalg}" = "rsa";then |
|
echo " - Generating RSA-PSS certificate based on key" |
|
@@ -207,6 +213,10 @@ run_tests() |
|
--load-privkey "${KEYPEMFILE}" \ |
|
--sign-params rsa-pss \ |
|
--template "${srcdir}/cert-tests/templates/template-test.tmpl" |
|
+ if [ $? -ne 0 ]; then |
|
+ echo "unable to generate certificate" |
|
+ return 1 |
|
+ fi |
|
fi |
|
|
|
stop_swtpm |
|
-- |
|
2.34.1 |
|
|
|
|