diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c index 708d8a7645..ab7d01f137 100644 --- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c @@ -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) diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c index b62b0f8b33..bd27d3e6d6 100644 --- a/src/shared/cryptsetup-tpm2.c +++ b/src/shared/cryptsetup-tpm2.c @@ -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; } diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 1c1ce441a2..d5106dbb54 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3134,6 +3134,12 @@ int tpm2_make_policy_session( &SESSION_TEMPLATE_SYM_AES_128_CFB, TPM2_ALG_SHA256, &session->esys_handle); + if ((rc & ~TPM2_RC_N_MASK) == TPM2_RC_AUTH_FAIL) + return log_debug_errno(SYNTHETIC_ERRNO(EILSEQ), + "Authorization failure from TPM: %s", sym_Tss2_RC_Decode(rc)); + if (rc == TPM2_RC_LOCKOUT) + return log_debug_errno(SYNTHETIC_ERRNO(ENOLCK), + "TPM2 device is in dictionary attack lockout mode."); if (rc != TSS2_RC_SUCCESS) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc)); @@ -5518,6 +5524,7 @@ int tpm2_unseal(Tpm2Context *c, * -EUCLEAN → PCR state doesn't match expectations * -EPERM → stored policy does not match TPM state * -ENOTRECOVERABLE → all other kinds of TPM errors + * -EILSEQ → bad PIN * * Of these all four of EREMCHG, ENOANO, EUCLEAN, EPERM can all mean that PCR state is not matching * expectations. */ @@ -5657,7 +5664,7 @@ int tpm2_unseal(Tpm2Context *c, encryption_session, &policy_session); if (r < 0) - return r; + return r; /* Will return EILSEQ on auth failure (i.e. bad PIN) */ /* If both public PCR key and pcrlock policies are requested, then generate the * public PCR policy for the first shared, and the pcrlock policy for the 2nd */