#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wanalyzer-file-leak"
+GNUTLS_ONCE(keylog_once);
+
+static void
+keylog_once_init(void)
+{
+ const char *keylogfile;
+
+ keylogfile = secure_getenv("SSLKEYLOGFILE");
+ if (keylogfile != NULL && *keylogfile != '\0') {
+ keylog = fopen(keylogfile, "ae");
+ _gnutls_debug_log("unable to open keylog file %s\n",
+ keylogfile);
+ }
+}
+
void _gnutls_nss_keylog_write(gnutls_session_t session,
const char *label,
const uint8_t *secret, size_t secret_size)
{
- static const char *keylogfile = NULL;
- static unsigned checked_env = 0;
-
- if (!checked_env) {
- checked_env = 1;
- keylogfile = secure_getenv("SSLKEYLOGFILE");
- if (keylogfile != NULL)
- keylog = fopen(keylogfile, "ae");
- }
+ (void)gnutls_once(&keylog_once, keylog_once_init);
if (keylog) {
char client_random_hex[2*GNUTLS_RANDOM_SIZE+1];
#include "pin.h"
+/* Functions used outside tpm2.c */
+
+void _gnutls_tpm2_deinit(void);
+int _gnutls_load_tpm2_key(gnutls_privkey_t pkey, const gnutls_datum_t *fdata);
+
+/* Functions only used in tpm2.c */
+
struct tpm2_info_st;
struct tpm2_info_st *tpm2_info_init(struct pin_info_st *pin);
-void release_tpm2_ctx(struct tpm2_info_st *info);
+void tpm2_tcti_deinit(void);
-int _gnutls_load_tpm2_key(gnutls_privkey_t pkey, const gnutls_datum_t *fdata);
+void release_tpm2_ctx(struct tpm2_info_st *info);
int install_tpm2_key(struct tpm2_info_st *info, gnutls_privkey_t pkey,
unsigned int parent, bool emptyauth,
#include <string.h>
#include "tpm2.h"
+#include "locks.h"
#include <tss2/tss2_mu.h>
#include <tss2/tss2_esys.h>
#include <tss2/tss2_tctildr.h>
struct tpm2_info_st {
- TSS2_TCTI_CONTEXT *tcti_ctx;
TPM2B_PUBLIC pub;
TPM2B_PRIVATE priv;
TPM2B_DIGEST userauth;
struct pin_info_st *pin_info;
};
+static TSS2_TCTI_CONTEXT *tcti_ctx;
+
#define PRIMARY_HASH_ALGORITHM TPM2_ALG_SHA256
#define PRIMARY_OBJECT_ATTRIBUTES (TPMA_OBJECT_USERWITHAUTH | \
TPMA_OBJECT_RESTRICTED | \
_gnutls_debug_log("tpm2: establishing connection with TPM\n");
- rc = Esys_Initialize(ctx, info->tcti_ctx, NULL);
+ rc = Esys_Initialize(ctx, tcti_ctx, NULL);
if (rc) {
gnutls_assert();
_gnutls_debug_log("tpm2: Esys_Initialize failed: 0x%x\n", rc);
return ret;
}
-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)
+GNUTLS_ONCE(tcti_once);
+
+void
+tpm2_tcti_deinit(void)
+{
+ if (tcti_ctx) {
+ Tss2_TctiLdr_Finalize(&tcti_ctx);
+ }
+}
+
+static void
+tcti_once_init(void)
{
const char *tcti;
const char * const tcti_vars[] = {
size_t i;
TSS2_RC rc;
- if (!parent_is_persistent(parent) &&
- parent != TPM2_RH_OWNER && parent != TPM2_RH_NULL &&
- parent != TPM2_RH_ENDORSEMENT && parent != TPM2_RH_PLATFORM) {
- _gnutls_debug_log("tpm2: Invalid TPM2 parent handle 0x%08x\n",
- parent);
- return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
- }
-
- info->parent = parent;
-
for (i = 0; i < sizeof(tcti_vars) / sizeof(tcti_vars[0]); i++) {
tcti = secure_getenv(tcti_vars[i]);
if (tcti && *tcti != '\0') {
}
}
if (tcti && *tcti != '\0') {
- rc = Tss2_TctiLdr_Initialize(tcti, &info->tcti_ctx);
+ rc = Tss2_TctiLdr_Initialize(tcti, &tcti_ctx);
if (rc) {
_gnutls_debug_log("tpm2: TSS2_TctiLdr_Initialize failed: 0x%x\n",
rc);
- return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
}
}
+}
+
+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);
+
+ if (!tcti_ctx) {
+ return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
+ }
+
+ if (!parent_is_persistent(parent) &&
+ parent != TPM2_RH_OWNER && parent != TPM2_RH_NULL &&
+ parent != TPM2_RH_ENDORSEMENT && parent != TPM2_RH_PLATFORM) {
+ _gnutls_debug_log("tpm2: Invalid TPM2 parent handle 0x%08x\n",
+ parent);
+ return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
+ }
+
+ info->parent = parent;
rc = Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL,
&info->priv);
sizeof(info->ownerauth.buffer));
zeroize_key(info->userauth.buffer,
sizeof(info->userauth.buffer));
- if (info->tcti_ctx) {
- Tss2_TctiLdr_Finalize(&info->tcti_ctx);
- }
gnutls_free(info);
}
}