]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: add generic wrapper tpm2_context_new_or_warn() that wrpas tpm2_context_new...
authorLennart Poettering <lennart@poettering.net>
Mon, 22 Apr 2024 07:46:23 +0000 (09:46 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 22 Apr 2024 10:40:09 +0000 (12:40 +0200)
We so far just print a short log message that is not very useful, let's
add some recognizable error codes, and output better log messages if we
can't get TPM stuff to work.

Fixes: #31925
12 files changed:
src/analyze/analyze-srk.c
src/cryptenroll/cryptenroll-tpm2.c
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
src/cryptsetup/cryptsetup.c
src/partition/repart.c
src/pcrextend/pcrextend.c
src/pcrlock/pcrlock.c
src/shared/creds-util.c
src/shared/cryptsetup-tpm2.c
src/shared/tpm2-util.c
src/shared/tpm2-util.h
src/tpm2-setup/tpm2-setup.c

index 0e24b416bb4efa77dae6550de00d630e64534a53..6faf2c29a34f283f208d8e3e55e3cbb2fd560a65 100644 (file)
@@ -11,9 +11,9 @@ int verb_srk(int argc, char *argv[], void *userdata) {
         _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
         int r;
 
-        r = tpm2_context_new(/* device= */ NULL, &c);
+        r = tpm2_context_new_or_warn(/* device= */ NULL, &c);
         if (r < 0)
-                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                return r;
 
         r = tpm2_get_srk(
                         c,
index 3ded815fb0778cc706497a1f13ba9b6262d183f1..83a2f4420f5380edbcc472013ca6b001c8daa5aa 100644 (file)
@@ -351,9 +351,9 @@ int enroll_tpm2(struct crypt_device *cd,
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                "Must provide all PCR values when using TPM2 device key.");
         } else {
-                r = tpm2_context_new(device, &tpm2_context);
+                r = tpm2_context_new_or_warn(device, &tpm2_context);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to create TPM2 context: %m");
+                        return r;
 
                 if (!tpm2_pcr_values_has_all_values(hash_pcr_values, n_hash_pcr_values)) {
                         r = tpm2_pcr_read_missing_values(tpm2_context, hash_pcr_values, n_hash_pcr_values);
index d902c591dffc1c333594ca51f024d6b2766bbd32..08f901c5481ad6b21ad50c3744ac13fc92c0723b 100644 (file)
@@ -87,9 +87,9 @@ int acquire_luks2_key(
         }
 
         _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
-        r = tpm2_context_new(device, &tpm2_context);
+        r = tpm2_context_new_or_warn(device, &tpm2_context);
         if (r < 0)
-                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                return r;
 
         r = tpm2_unseal(tpm2_context,
                         hash_pcr_mask,
index 34ad9ebd1455e3bdeee63c16291ea397d1563ce5..89bea30d00aa2e12071d05673e91ef43469af05d 100644 (file)
@@ -919,9 +919,9 @@ static int measure_volume_key(
 
 #if HAVE_TPM2
         _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
-        r = tpm2_context_new(arg_tpm2_device, &c);
+        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
         if (r < 0)
-                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                return r;
 
         _cleanup_strv_free_ char **l = NULL;
         if (strv_isempty(arg_tpm2_measure_banks)) {
index fa556874dffd3b407c47e18b02b02a9c3718adb9..51ae8592fdefe7440ef67e456fd64923ea3c8646 100644 (file)
@@ -4067,9 +4067,9 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                        "Must provide all PCR values when using TPM2 device key.");
                 } else {
-                        r = tpm2_context_new(arg_tpm2_device, &tpm2_context);
+                        r = tpm2_context_new_or_warn(arg_tpm2_device, &tpm2_context);
                         if (r < 0)
-                                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                                return r;
 
                         if (!tpm2_pcr_values_has_all_values(arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values)) {
                                 r = tpm2_pcr_read_missing_values(tpm2_context, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values);
index ead353f5a69704e22f0d312574480fe566991816..ba2b171250ac683eabae4ada36d2cd9cadbcab4f 100644 (file)
@@ -199,7 +199,7 @@ static int extend_now(unsigned pcr, const void *data, size_t size, Tpm2Userspace
         _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
         int r;
 
-        r = tpm2_context_new(arg_tpm2_device, &c);
+        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
         if (r < 0)
                 return r;
 
index 5045ad93e888b8233b584820a4e4c61dce89540b..4e86b527d3b727a8ff5c9f7c581f7c4bfff9f076 100644 (file)
@@ -1228,7 +1228,7 @@ static int event_log_read_pcrs(EventLog *el) {
 
         assert(el);
 
-        r = tpm2_context_new(NULL, &tc);
+        r = tpm2_context_new_or_warn(/* device= */ NULL, &tc);
         if (r < 0)
                 return r;
 
@@ -4490,9 +4490,9 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
         }
 
         _cleanup_(tpm2_context_unrefp) Tpm2Context *tc = NULL;
-        r = tpm2_context_new(NULL, &tc);
+        r = tpm2_context_new_or_warn(/* device= */ NULL, &tc);
         if (r < 0)
-                return log_error_errno(r, "Failed to allocate TPM2 context: %m");
+                return r;
 
         if (!tpm2_supports_command(tc, TPM2_CC_PolicyAuthorizeNV))
                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 does not support PolicyAuthorizeNV command, refusing.");
@@ -4836,7 +4836,7 @@ static int undefine_policy_nv_index(
         assert(srk_blob);
 
         _cleanup_(tpm2_context_unrefp) Tpm2Context *tc = NULL;
-        r = tpm2_context_new(NULL, &tc);
+        r = tpm2_context_new_or_warn(/* device= */ NULL, &tc);
         if (r < 0)
                 return r;
 
index bd2af6d172477df28534fa476871634db3a6d0ca..fd7388127b1dd349d9dbdda5d6a602b6a058ffa2 100644 (file)
@@ -919,9 +919,9 @@ int encrypt_credential_and_warn(
                         tpm2_pubkey_pcr_mask = 0;
 
                 _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
-                r = tpm2_context_new(tpm2_device, &tpm2_context);
+                r = tpm2_context_new_or_warn(tpm2_device, &tpm2_context);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to create TPM2 context: %m");
+                        return r;
 
                 r = tpm2_get_best_pcr_bank(tpm2_context, tpm2_hash_pcr_mask | tpm2_pubkey_pcr_mask, &tpm2_pcr_bank);
                 if (r < 0)
index ee664a95a1abab21815d993457d4e0597fe93b3e..335bb2eb89045f5b3a7bbbd6ca6df838d7b51691 100644 (file)
@@ -143,9 +143,9 @@ int acquire_tpm2_key(
         }
 
         _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
-        r = tpm2_context_new(device, &tpm2_context);
+        r = tpm2_context_new_or_warn(device, &tpm2_context);
         if (r < 0)
-                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                return r;
 
         if (!(flags & TPM2_FLAGS_USE_PIN)) {
                 r = tpm2_unseal(tpm2_context,
index 1e747a07e49252b59830656526c7988c3ec8033f..10a78adfaff41baa482e8aeeeaf441c44363ec78 100644 (file)
@@ -675,7 +675,7 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
 
                 context->tcti_dl = dlopen(fn, RTLD_NOW);
                 if (!context->tcti_dl)
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());
+                        return log_debug_errno(SYNTHETIC_ERRNO(ENOPKG), "Failed to load %s: %s", fn, dlerror());
 
                 log_debug("Loaded '%s' via dlopen()", fn);
 
@@ -691,7 +691,7 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
 
                 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
 
-                rc = info->init(NULL, &sz, NULL);
+                rc = info->init(/* context= */ NULL, &sz, /* param= */ NULL);
                 if (rc != TPM2_RC_SUCCESS)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                                "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
@@ -726,19 +726,37 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
 
         /* We require AES and CFB support for session encryption. */
         if (!tpm2_supports_alg(context, TPM2_ALG_AES))
-                return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES.");
+                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES.");
 
         if (!tpm2_supports_alg(context, TPM2_ALG_CFB))
-                return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support CFB.");
+                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support CFB.");
 
         if (!tpm2_supports_tpmt_sym_def(context, &SESSION_TEMPLATE_SYM_AES_128_CFB))
-                return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES-128-CFB.");
+                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES-128-CFB.");
 
         *ret_context = TAKE_PTR(context);
 
         return 0;
 }
 
+int tpm2_context_new_or_warn(const char *device, Tpm2Context **ret_context) {
+        int r;
+
+        assert(ret_context);
+
+        r = tpm2_context_new(device, ret_context);
+        if (r == -EOPNOTSUPP)
+                return log_error_errno(r, "TPM device not usable as it does not support the required functionality (AES-128-CFB missing?).");
+        if (r == -ENOPKG)
+                return log_error_errno(r, "TPM TCTI driver not available.");
+        if (r == -ENOENT)
+                return log_error_errno(r, "TPM device not found.");
+        if (r < 0)
+                return log_error_errno(r, "Failed to create TPM2 context: %m");
+
+        return 0;
+}
+
 static void tpm2_handle_cleanup(ESYS_CONTEXT *esys_context, ESYS_TR esys_handle, bool flush) {
         TSS2_RC rc;
 
index f09b71f84c5997efd8636597ce4fefb58c17e769..dc8aa88f09bb2aeabdc29b7cece7479cdcb27c08 100644 (file)
@@ -72,6 +72,7 @@ typedef struct {
 } Tpm2Context;
 
 int tpm2_context_new(const char *device, Tpm2Context **ret_context);
+int tpm2_context_new_or_warn(const char *device, Tpm2Context **ret_context);
 Tpm2Context *tpm2_context_ref(Tpm2Context *context);
 Tpm2Context *tpm2_context_unref(Tpm2Context *context);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Context*, tpm2_context_unref);
index 846d5b8ac8389005e5a62967983327712f604304..35628fc02a88bfaf2783f194f74b89ec90dff92a 100644 (file)
@@ -212,9 +212,9 @@ static int load_public_key_tpm2(struct public_key_data *ret) {
 
         assert(ret);
 
-        r = tpm2_context_new(arg_tpm2_device, &c);
+        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
         if (r < 0)
-                return log_error_errno(r, "Failed to create TPM2 context: %m");
+                return r;
 
         r = tpm2_get_or_create_srk(
                         c,