]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: For NV index errors report EREMOTE to be able to continue
authorKai Lüke <kai@amutable.com>
Mon, 20 Apr 2026 11:27:59 +0000 (20:27 +0900)
committerKai Lüke <pothos@users.noreply.github.com>
Fri, 10 Jul 2026 06:07:47 +0000 (08:07 +0200)
When we have many LUKS slots and not all are for our TPM, we can get an
NV index error when it's missing or has wrong content.
Instead of fully erroring out, map these encounters to EREMOTE like we
do for a foreign TPM key.

src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
src/shared/cryptsetup-tpm2.c
src/shared/tpm2-util.c

index b611aab83fe2fb0941713203f469b550e748ad7f..40bc2a8f6fded26763cd98edd9aab769ab03d130 100644 (file)
@@ -112,7 +112,7 @@ int acquire_luks2_key(
                         srk,
                         ret_decrypted_key);
         if (r == -EREMOTE)
-                return log_error_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM.");
+                return log_error_errno(r, "TPM key integrity check failed or NV index unusable. Key enrolled in superblock most likely does not belong to this TPM.");
         if (r == -EILSEQ)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOANO), "Bad PIN."); /* cryptsetup docs say we should return ENOANO on bad PIN */
         if (r == -ENOLCK)
index f536cb8113ad9f4cdb4ffedec3d9a8b070b4ef0d..c8c99cacba2a1474fc70742cca242e86de65e54e 100644 (file)
@@ -174,7 +174,7 @@ int acquire_tpm2_key(
                                 srk,
                                 ret_decrypted_key);
                 if (r == -EREMOTE)
-                        return log_error_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM.");
+                        return log_error_errno(r, "TPM key integrity check failed or NV index unusable. Key enrolled in superblock most likely does not belong to this TPM.");
                 if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r))
                         return log_error_errno(r, "TPM policy does not match current system state. Either system has been tempered with or policy out-of-date: %m");
                 if (r == -ENOSTR)
@@ -229,7 +229,7 @@ int acquire_tpm2_key(
                                 srk,
                                 ret_decrypted_key);
                 if (r == -EREMOTE)
-                        return log_error_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM.");
+                        return log_error_errno(r, "TPM key integrity check failed or NV index unusable. Key enrolled in superblock most likely does not belong to this TPM.");
                 if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r))
                         return log_error_errno(r, "TPM policy does not match current system state. Either system has been tempered with or policy out-of-date: %m");
                 if (r == -ENOSTR)
index 4010eaeffec4bf7e9f787c4f66219553a42e3140..75cd2aca3e34b6269cfb4e98031a40e45f9bc80b 100644 (file)
@@ -4751,6 +4751,10 @@ int tpm2_policy_authorize_nv(
                                                                   * just put together */
                 return log_debug_errno(SYNTHETIC_ERRNO(EREMCHG),
                                        "Submitted policy does not match policy stored in PolicyAuthorizeNV.");
+        if ((rc & ~(TPM2_RC_N_MASK|TPM2_RC_P)) == TPM2_RC_HANDLE ||
+            rc == TPM2_RC_NV_UNINITIALIZED) /* NV index is missing, unwritten, or otherwise unusable for this policy (or: wrong authHandle/policySession). */
+                return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
+                                       "NV index referenced by token is missing, unwritten, or unusable.");
         if (rc != TSS2_RC_SUCCESS)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                        "Failed to add AuthorizeNV policy to TPM: %s",
@@ -6663,7 +6667,7 @@ int tpm2_unseal(Tpm2Context *c,
 
         /* Returns the following errors:
          *
-         *   -EREMOTE         → blob is from a different TPM
+         *   -EREMOTE         → blob is from a different TPM, or NV index referenced by policy is unusable
          *   -ENOSTR          → signature JSON has no matching entry for the current PCR policy
          *   -EDEADLK         → couldn't create primary key because authorization failure
          *   -ENOLCK          → TPM is in dictionary lockout mode