[libsecret: 1/2] Add TPM2 API and its implementations to egg




commit 63907d907ee9b37f498b762e08efd37ba1f59c6f
Author: Dhanuka Warusadura <csx tuta io>
Date:   Fri Jul 2 17:30:06 2021 +0530

    Add TPM2 API and its implementations to egg
    
    These changes define the TPM2 API and add its implementations
    to the incubation area (egg/).
    
    Summary of the public API:
    `egg_tpm2_initialize`: Start a TPM context.
    `egg_tpm2_finalize`: End a TPM context.
    `egg_tpm2_generate_master_password`: Generate and returns an
    encrypted master password in `GBytes` format. TSS Marshaling,
    GVariant serialization is used.
    `egg_tpm2_decrypt_master_password`: Decrypts a master password
    generated from `egg_tpm2_generate_master_password`. TSS
    Unmarshaling, GVariant deserialization is used.
    
    TPM2 API: TSS Enhanced System API (ESAPI)
    
    Proposal: [extend file backend to use TPM2 derived encryption 
keys](https://gitlab.gnome.org/Teams/Engagement/gsoc-2021/-/issues/13)
    
    Related MRs: [#86](https://gitlab.gnome.org/GNOME/libsecret/-/merge_requests/86)
    
    Related Issues: [#63](https://gitlab.gnome.org/GNOME/libsecret/-/issues/63)

 .gitlab-ci.yml    |   4 +-
 egg/egg-tpm2.c    | 484 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 egg/egg-tpm2.h    |  39 +++++
 egg/meson.build   |  14 ++
 egg/test-tpm2.c   |  78 +++++++++
 meson.build       |  15 ++
 meson_options.txt |   1 +
 7 files changed, 633 insertions(+), 2 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d1a68d4..731d02d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,7 @@ stages:
   - deploy
 
 variables:
-  DEPENDENCIES: dbus-x11 diffutils gcc gjs meson ninja-build python3-dbus python3-gobject redhat-rpm-config
+  DEPENDENCIES: dbus-x11 diffutils gcc gjs meson ninja-build python3-dbus python3-gobject redhat-rpm-config 
tpm2-tss-devel
   CPPCHECK_OPTIONS: "--enable=warning --enable=style --enable=performance --enable=portability --std=c99 
--template='{id}:{file}:{line},{severity},{message}'"
 
 fedora:Werror:
@@ -24,7 +24,7 @@ fedora:Werror:
     - eval `dbus-launch --sh-syntax`
     - 'tpm2-abrmd --logger=stdout --tcti=swtpm: --session --allow-root --flush-all &'
     - 'export TCTI=tabrmd:bus_type=session'
-    - meson _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations
+    - meson _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations -Dtpm2=true
     - meson compile -C _build
     - meson test -C _build
   artifacts:
diff --git a/egg/egg-tpm2.c b/egg/egg-tpm2.c
new file mode 100644
index 0000000..2812aea
--- /dev/null
+++ b/egg/egg-tpm2.c
@@ -0,0 +1,484 @@
+/* libsecret - TSS interface implementations for libsecret
+ *
+ * Copyright (C) 2021 Dhanuka Warusadura
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301  USA
+ *
+ * Author: Dhanuka Warusadura
+*/
+
+#include "config.h"
+#include "egg-tpm2.h"
+#include <tss2/tss2_esys.h>
+#include <tss2/tss2_mu.h>
+#include <tss2/tss2_rc.h>
+#include <tss2/tss2_tctildr.h>
+
+#define MAX_BYTE_SIZE 64
+
+struct EggTpm2Context {
+       TSS2_TCTI_CONTEXT *tcti_context;
+       ESYS_CONTEXT *esys_context;
+       ESYS_TR primary_key;
+};
+
+static gboolean
+egg_tpm2_generate_primary_key(EggTpm2Context *context,
+                             GError **error)
+{
+       TSS2_RC ret;
+
+       TPM2B_SENSITIVE_CREATE sensitive_params = {
+               .size = 0,
+               .sensitive = {
+                       .userAuth = {
+                               .size = 0,
+                               .buffer = {0},
+                       },
+                       .data = {
+                               .size = 0,
+                               .buffer = {0},
+                       },
+               },
+       };
+
+       TPM2B_PUBLIC public_key_param = {
+               .size = 0,
+               .publicArea = {
+                       .type = TPM2_ALG_RSA,
+                       .nameAlg = TPM2_ALG_SHA256,
+                       .objectAttributes = (
+                               TPMA_OBJECT_USERWITHAUTH |
+                               TPMA_OBJECT_RESTRICTED |
+                               TPMA_OBJECT_DECRYPT |
+                               TPMA_OBJECT_FIXEDTPM |
+                               TPMA_OBJECT_FIXEDPARENT |
+                               TPMA_OBJECT_SENSITIVEDATAORIGIN),
+                       .authPolicy = {
+                               .size = 0,
+                       },
+                       .parameters.rsaDetail = {
+                               .symmetric = {
+                                       .algorithm = TPM2_ALG_AES,
+                                       .keyBits.aes = 128,
+                                       .mode.aes = TPM2_ALG_CFB
+                               },
+                               .scheme = {
+                                       .scheme = TPM2_ALG_NULL
+                               },
+                               .keyBits = 2048,
+                               .exponent = 0,
+                       },
+                       .unique.rsa = {
+                               .size = 0,
+                               .buffer = {},
+                       },
+               },
+       };
+
+       TPM2B_DATA outside_info = {
+               .size = 0,
+               .buffer = {},
+       };
+
+       TPML_PCR_SELECTION pcrs = {
+               .count = 0,
+       };
+
+       TPM2B_PUBLIC *public;
+       TPM2B_CREATION_DATA *creation_data;
+       TPM2B_DIGEST *hash;
+       TPMT_TK_CREATION *ticket;
+
+       ret = Esys_CreatePrimary(context->esys_context, ESYS_TR_RH_OWNER,
+                                ESYS_TR_PASSWORD, ESYS_TR_NONE,
+                                ESYS_TR_NONE, &sensitive_params,
+                                &public_key_param, &outside_info,
+                                &pcrs, &context->primary_key, &public,
+                                &creation_data, &hash, &ticket);
+
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_CreatePrimary: %s", Tss2_RC_Decode(ret));
+               return FALSE;
+       }
+
+       Esys_Free(public);
+       Esys_Free(creation_data);
+       Esys_Free(hash);
+       Esys_Free(ticket);
+
+       return TRUE;
+}
+
+static GBytes *
+egg_tpm2_generate_random_data(EggTpm2Context *context,
+                              GError **error)
+{
+       gboolean status = FALSE;
+       TSS2_RC ret;
+       TPM2B_DIGEST *random_data;
+       GBytes *bytes;
+
+       status = egg_tpm2_generate_primary_key(context, error);
+       if (!status)
+               return NULL;
+
+       ret = Esys_GetRandom(context->esys_context, ESYS_TR_NONE,
+                            ESYS_TR_NONE, ESYS_TR_NONE, MAX_BYTE_SIZE,
+                            &random_data);
+
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_GetRandom: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       bytes = g_bytes_new(random_data->buffer, random_data->size);
+       Esys_Free(random_data);
+
+       return bytes;
+}
+
+EggTpm2Context *
+egg_tpm2_initialize(GError **error)
+{
+       TSS2_RC ret;
+       EggTpm2Context *context;
+       gsize n_context;
+       const gchar *tcti_conf;
+
+       n_context = 1;
+       context = g_new(EggTpm2Context, n_context);
+       tcti_conf = g_getenv("TCTI");
+       ret = Tss2_TctiLdr_Initialize(tcti_conf, &context->tcti_context);
+
+       if (ret != TSS2_RC_SUCCESS) {
+               egg_tpm2_finalize(context);
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Tss2_TctiLdr_Initialize: %s",
+                           Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       ret = Esys_Initialize(&context->esys_context,
+                             context->tcti_context, NULL);
+       if (ret != TSS2_RC_SUCCESS) {
+               egg_tpm2_finalize(context);
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_Initialize: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       ret = Esys_Startup(context->esys_context, TPM2_SU_CLEAR);
+       if (ret != TSS2_RC_SUCCESS) {
+               egg_tpm2_finalize(context);
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_Startup: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       return context;
+}
+
+void
+egg_tpm2_finalize(EggTpm2Context *context)
+{
+       if (context->esys_context)
+               Esys_Finalize(&context->esys_context);
+
+       if (context->tcti_context)
+               Tss2_TctiLdr_Finalize(&context->tcti_context);
+
+       g_free(context);
+}
+
+GBytes *
+egg_tpm2_generate_master_password(EggTpm2Context *context,
+                                  GError **error)
+{
+       TSS2_RC ret;
+       TPM2B_PRIVATE *out_private;
+       TPM2B_PUBLIC *out_public;
+       TPM2B_CREATION_DATA *creation_data;
+       TPM2B_DIGEST *hash;
+       TPMT_TK_CREATION *ticket;
+       gconstpointer data;
+       gsize size;
+       GBytes *input;
+       GBytes *output;
+
+       TPM2B_SENSITIVE_CREATE in_sensitive = {
+               .size = 0,
+               .sensitive = {
+                       .data = {
+                               .size = MAX_BYTE_SIZE
+                       }
+               }
+       };
+
+       TPM2B_PUBLIC in_public = {
+               .size = 0,
+               .publicArea = {
+                       .type = TPM2_ALG_KEYEDHASH,
+                       .nameAlg = TPM2_ALG_SHA256,
+                       .objectAttributes = (
+                               TPMA_OBJECT_USERWITHAUTH |
+                               TPMA_OBJECT_FIXEDTPM |
+                               TPMA_OBJECT_FIXEDPARENT),
+                       .authPolicy = {
+                               .size = 0,
+                       },
+                       .parameters.keyedHashDetail = {
+                               .scheme = {
+                                       .scheme = TPM2_ALG_NULL,
+                                       .details = {
+                                               .hmac = {
+                                                       .hashAlg =
+                                                               TPM2_ALG_SHA256
+                                               }
+                                       }
+                               }
+                       },
+                       .unique.keyedHash = {
+                               .size = 0,
+                               .buffer = {},
+                       },
+               }
+       };
+
+       TPM2B_DATA outside_info = {
+               .size = 0,
+               .buffer = {}
+       };
+
+       TPML_PCR_SELECTION pcrs = {
+               .count = 0
+       };
+
+       input = egg_tpm2_generate_random_data(context, error);
+       if (!input) {
+               g_bytes_unref(input);
+               return NULL;
+       }
+
+       data = g_bytes_get_data(input, &size);
+       g_bytes_unref(input);
+
+       if (size > sizeof(in_sensitive.sensitive.data.buffer)) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_ARGUMENT,
+                                   "Input is too long");
+               return NULL;
+       }
+
+       memcpy(in_sensitive.sensitive.data.buffer, data, size);
+       in_sensitive.sensitive.data.size = size;
+
+       ret = Esys_Create(context->esys_context, context->primary_key,
+                         ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
+                         &in_sensitive, &in_public, &outside_info,
+                         &pcrs, &out_private, &out_public, &creation_data,
+                         &hash, &ticket);
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_Create: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       gsize out_private_offset = 0;
+       gsize out_public_offset = 0;
+       GVariant *out_private_variant;
+       GVariant *out_public_variant;
+       GVariant *variant;
+
+       guint8 marshaled_out_private[sizeof(*out_private)];
+       guint8 marshaled_out_public[sizeof(*out_public)];
+
+       ret = Tss2_MU_TPM2B_PRIVATE_Marshal(out_private,
+                                           marshaled_out_private,
+                                           sizeof(marshaled_out_private),
+                                           &out_private_offset);
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Tss2_MU_TPM2B_PRIVATE_Marshal: %s",
+                           Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       out_private_variant = g_variant_new_fixed_array(
+                       G_VARIANT_TYPE_BYTE,
+                       marshaled_out_private,
+                       out_private_offset,
+                       sizeof(guint8));
+
+       ret = Tss2_MU_TPM2B_PUBLIC_Marshal(out_public,
+                                          marshaled_out_public,
+                                          sizeof(marshaled_out_public),
+                                          &out_public_offset);
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Tss2_MU_TPM2B_PUBLIC_Marshal: %s",
+                           Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       out_public_variant = g_variant_new_fixed_array(
+                       G_VARIANT_TYPE_BYTE,
+                       marshaled_out_public,
+                       out_public_offset,
+                       sizeof(guint8));
+
+       variant = g_variant_new("(u@ayu@ay)",
+                               out_private_offset, out_private_variant,
+                               out_public_offset, out_public_variant);
+
+       output = g_variant_get_data_as_bytes(variant);
+
+       g_variant_unref(variant);
+       Esys_Free(out_public);
+       Esys_Free(out_private);
+       Esys_Free(creation_data);
+       Esys_Free(hash);
+       Esys_Free(ticket);
+
+       return output;
+}
+
+GBytes *
+egg_tpm2_decrypt_master_password(EggTpm2Context *context,
+                                 GBytes *input,
+                                 GError **error)
+{
+       TSS2_RC ret;
+       GBytes *output;
+       TPM2B_SENSITIVE_DATA *out_data;
+       GVariant *variant;
+       gconstpointer data;
+       gsize out_private_offset = 0;
+       gsize out_public_offset = 0;
+       gsize count = 0;
+       gsize offset = 0;
+       GVariant *out_private_variant;
+       GVariant *out_public_variant;
+       ESYS_TR out_key;
+
+       variant = g_variant_new_from_bytes(G_VARIANT_TYPE(
+                                          "(uayuay)"),
+                                          input,
+                                          TRUE);
+
+       g_variant_get(variant, "(u@ayu@ay)",
+                     &out_private_offset, &out_private_variant,
+                     &out_public_offset, &out_public_variant);
+       g_variant_unref(variant);
+
+       data = g_variant_get_fixed_array(out_private_variant,
+                                        &count,
+                                        sizeof(guint8));
+       guint8 *marshaled_out_private = g_memdup(data, count);
+       count = 0;
+
+       TPM2B_PRIVATE out_private = {
+               .size = 0
+       };
+       ret = Tss2_MU_TPM2B_PRIVATE_Unmarshal(marshaled_out_private,
+                                             out_private_offset,
+                                             &offset,
+                                             &out_private);
+
+       g_variant_unref(out_private_variant);
+       g_free(marshaled_out_private);
+
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Tss2_MU_TPM2B_PRIVATE_Unmarshal: %s",
+                           Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       offset = 0;
+       data = g_variant_get_fixed_array(out_public_variant,
+                                        &count,
+                                        sizeof(guint8));
+       guint8 *marshaled_out_public = g_memdup(data, count);
+
+       TPM2B_PUBLIC out_public = {
+               .size = 0
+       };
+       ret = Tss2_MU_TPM2B_PUBLIC_Unmarshal(marshaled_out_public,
+                                            out_public_offset,
+                                            &offset,
+                                            &out_public);
+
+       g_variant_unref(out_public_variant);
+       g_free(marshaled_out_public);
+
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Tss2_MU_TPM2B_PUBLIC_Unmarshal: %s",
+                           Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       ret = Esys_Load(context->esys_context, context->primary_key,
+                       ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
+                       &out_private, &out_public, &out_key);
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_Load: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       ret = Esys_Unseal(context->esys_context, out_key,
+                         ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
+                         &out_data);
+       if (ret != TSS2_RC_SUCCESS) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Esys_Unseal: %s", Tss2_RC_Decode(ret));
+               return NULL;
+       }
+
+       output = g_bytes_new(out_data->buffer, out_data->size);
+       Esys_Free(out_data);
+
+       return output;
+}
diff --git a/egg/egg-tpm2.h b/egg/egg-tpm2.h
new file mode 100644
index 0000000..43409cd
--- /dev/null
+++ b/egg/egg-tpm2.h
@@ -0,0 +1,39 @@
+/* libsecret - TSS interface for libsecret
+ *
+ * Copyright (C) 2021 Dhanuka Warusadura
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301  USA
+ *
+ * Author: Dhanuka Warusadura
+*/
+
+#ifndef EGG_TPM2_H_
+#define EGG_TPM2_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+typedef struct EggTpm2Context EggTpm2Context;
+
+EggTpm2Context *egg_tpm2_initialize               (GError **);
+void           egg_tpm2_finalize                  (EggTpm2Context *);
+GBytes         *egg_tpm2_generate_master_password (EggTpm2Context *,
+                                                  GError **);
+GBytes         *egg_tpm2_decrypt_master_password  (EggTpm2Context *,
+                                                  GBytes *,
+                                                  GError **);
+
+#endif
diff --git a/egg/meson.build b/egg/meson.build
index ac7c024..d2badac 100644
--- a/egg/meson.build
+++ b/egg/meson.build
@@ -18,6 +18,14 @@ if get_option('gcrypt')
   libegg_deps += gcrypt_dep
 endif
 
+if get_option('tpm2')
+  libegg_sources += [
+    'egg-tpm2.c',
+  ]
+
+  libegg_deps += tss2_deps
+endif
+
 libegg = static_library('egg',
   libegg_sources,
   dependencies: libegg_deps,
@@ -37,6 +45,12 @@ if get_option('gcrypt')
   ]
 endif
 
+if get_option('tpm2')
+  test_names += [
+    'test-tpm2',
+  ]
+endif
+
 foreach _test : test_names
 
   test_bin = executable(_test,
diff --git a/egg/test-tpm2.c b/egg/test-tpm2.c
new file mode 100644
index 0000000..218c310
--- /dev/null
+++ b/egg/test-tpm2.c
@@ -0,0 +1,78 @@
+/* libsecret - Test TSS interface for libsecret
+ *
+ * Copyright (C) 2021 Dhanuka Warusadura
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301  USA
+ *
+ * Author: Dhanuka Warusadura
+*/
+
+#include "egg-tpm2.h"
+
+void
+test_egg_tpm2_generate_master_password(void)
+{
+       EggTpm2Context *context;
+       GBytes *result;
+
+       GError *error = NULL;
+       g_assert_no_error(error);
+       context = egg_tpm2_initialize(&error);
+       g_assert_nonnull(context);
+       result = egg_tpm2_generate_master_password(context, &error);
+       g_assert_nonnull(result);
+       egg_tpm2_finalize(context);
+       g_bytes_unref(result);
+}
+
+void
+test_egg_tpm2_decrypt_master_password(void)
+{
+       EggTpm2Context *context;
+       GBytes *result, *decrypted1, *decrypted2;
+
+       GError *error = NULL;
+       g_assert_no_error(error);
+       context = egg_tpm2_initialize(&error);
+       g_assert_nonnull(context);
+       result = egg_tpm2_generate_master_password(context, &error);
+       g_assert_nonnull(result);
+       decrypted1 = egg_tpm2_decrypt_master_password(context, result,
+                                                     &error);
+       g_assert_nonnull(decrypted1);
+       decrypted2 = egg_tpm2_decrypt_master_password(context, result,
+                                                     &error);
+       g_assert_nonnull(decrypted2);
+       g_assert(g_bytes_equal(decrypted1, decrypted2));
+       egg_tpm2_finalize(context);
+       g_bytes_unref(result);
+       g_bytes_unref(decrypted1);
+       g_bytes_unref(decrypted2);
+}
+
+int
+main (int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+       g_test_add_func(
+                       "/tpm/test_egg_tpm2_generate_master_password",
+                       test_egg_tpm2_generate_master_password);
+       g_test_add_func(
+                       "/tpm/test_egg_tpm2_decrypt_master_password",
+                       test_egg_tpm2_decrypt_master_password);
+
+       return g_test_run();
+}
diff --git a/meson.build b/meson.build
index 909d0a1..f659a47 100644
--- a/meson.build
+++ b/meson.build
@@ -36,6 +36,17 @@ gcrypt_dep = dependency('libgcrypt',
   required: get_option('gcrypt'),
 )
 
+min_tss2_version = '3.0.3'
+tss2_esys = dependency('tss2-esys', version: '>=' + min_tss2_version, required: get_option('tpm2'))
+tss2_mu = dependency('tss2-mu', version: '>=' + min_tss2_version, required: get_option('tpm2'))
+tss2_rc = dependency('tss2-rc', version: '>=' + min_tss2_version, required: get_option('tpm2'))
+tss2_tctildr = dependency('tss2-tctildr', version: '>=' + min_tss2_version, required: get_option('tpm2'))
+
+tss2_deps = []
+if tss2_esys.found() and tss2_mu.found() and tss2_rc.found() and tss2_tctildr.found()
+  tss2_deps += [tss2_esys, tss2_mu, tss2_rc, tss2_tctildr]
+endif
+
 # Libraries
 math = meson.get_compiler('c').find_library('m')
 
@@ -48,9 +59,13 @@ conf.set_quoted('PACKAGE_NAME', meson.project_name())
 conf.set_quoted('PACKAGE_STRING', meson.project_name())
 conf.set_quoted('PACKAGE_VERSION', meson.project_version())
 conf.set('WITH_GCRYPT', get_option('gcrypt'))
+conf.set('WITH_TPM', get_option('tpm2'))
 if get_option('gcrypt')
   conf.set_quoted('LIBGCRYPT_VERSION', min_libgcrypt_version)
 endif
+if get_option('tpm2')
+  conf.set_quoted('TSS2_VERSION', min_tss2_version)
+endif
 conf.set('WITH_DEBUG', get_option('debugging'))
 conf.set('_DEBUG', get_option('debugging'))
 conf.set('HAVE_MLOCK', meson.get_compiler('c').has_function('mlock'))
diff --git a/meson_options.txt b/meson_options.txt
index 8858a33..24c8f02 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -6,3 +6,4 @@ option('gtk_doc', type: 'boolean', value: true, description: 'Build reference do
 option('introspection', type: 'boolean', value: true, description: 'Create GIR file.')
 option('bashcompdir', type: 'string', value: '', description: 'Override default location for bash completion 
files')
 option('bash_completion', type: 'feature', value: 'auto', description: 'Install bash completion files')
+option('tpm2', type: 'boolean', value: false, description: 'With TPM2 Software Stack')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]