]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptsetup: handle DA lockout/bad PIN properly 37894/head
authorLennart Poettering <lennart@poettering.net>
Thu, 19 Jun 2025 10:28:32 +0000 (12:28 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 19 Jun 2025 10:33:52 +0000 (12:33 +0200)
Now that we have recognizable errors, let's print clear error messages
when we try to unlock a TPM slot. And in case of the token plugin
propagate this as ENOANO so that libcryptsetup recognizes this as bad
PIN. (ENOANO is documented as the error to return in that case)

Fixes: #32260
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
src/shared/cryptsetup-tpm2.c

index 708d8a7645946bb0f06af510a463edb4b39ff349..ab7d01f137507a4bbc41becb0bb6741fc5ce34ee 100644 (file)
@@ -111,6 +111,10 @@ int acquire_luks2_key(
                         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.");
+        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)
+                return log_error_errno(r, "TPM is in dictionary attack lock-out mode.");
         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 < 0)
index b62b0f8b33274d15729b5dd59dee76a409eb957b..bd27d3e6d6be7ac9b918dc9134079167236f8301 100644 (file)
@@ -227,14 +227,14 @@ int acquire_tpm2_key(
                         return log_error_errno(r, "TPM key integrity check failed. 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 < 0) {
-                        log_error_errno(r, "Failed to unseal secret using TPM2: %m");
-
-                        /* We get this error in case there is an authentication policy mismatch. This should
-                         * not happen, but this avoids confusing behavior, just in case. */
-                        if (r != -ENOLCK)
-                                continue;
+                if (r == -ENOLCK)
+                        return log_error_errno(r, "TPM is in dictionary attack lock-out mode.");
+                if (r == -EILSEQ) {
+                        log_warning_errno(r, "Bad PIN.");
+                        continue;
                 }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to unseal secret using TPM2: %m");
 
                 return r;
         }