From 941db14b8e3bf1b517f83975a2b948304871e79d Mon Sep 17 00:00:00 2001 From: Alberto Planas Date: Mon, 14 Sep 2026 10:41:05 +0200 Subject: [PATCH] cryptsetup,cryptenroll: report continuously changing PCRs explicitly tpm2_unseal() returns -EUCLEAN specifically when a PCR kept being extended while unsealing, but the unseal callers no longer catch it via ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR() and would fall back to the generic "Failed to unseal secret using TPM2" message. Give it a message of its own instead, so that the log points at the actual cause instead of suggesting the system was tampered with. Signed-off-by: Alberto Planas --- src/cryptenroll/cryptenroll-tpm2.c | 2 ++ src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c | 2 ++ src/shared/cryptsetup-tpm2.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 6165a31642..21b77bd9c0 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -589,6 +589,8 @@ int enroll_tpm2(const EnrollContext *c, n_policy_hash, &srk, &secret2); + if (r == -EUCLEAN) + return log_error_errno(r, "PCR values kept changing while unsealing the TPM2 secret, giving up. Something on this system extends a PCR continuously."); if (r < 0) return log_error_errno(r, "Failed to unseal secret using TPM2: %m"); diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c index bb26193153..40a9ed1ffd 100644 --- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c @@ -135,6 +135,8 @@ int acquire_luks2_key( return log_error_errno(SYNTHETIC_ERRNO(ENOANO), "Bad %s.", argon2id ? "password" : "PIN"); if (r == -ENOLCK) return log_error_errno(r, "TPM is in dictionary attack lock-out mode."); + if (r == -EUCLEAN) + return log_error_errno(r, "PCR values kept changing while unsealing the TPM2 secret, giving up. Something on this system extends a PCR continuously."); if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r)) { log_warning_errno(r, "TPM policy does not match current system state. Either system has been tampered with or policy out-of-date: %m"); /* Normalize to -EPERM so callers don't confuse it with -ENOANO's "needs PIN" meaning. */ diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c index ecb312a960..e989c3c5fd 100644 --- a/src/shared/cryptsetup-tpm2.c +++ b/src/shared/cryptsetup-tpm2.c @@ -177,6 +177,8 @@ int acquire_tpm2_key( return log_warning_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM."); if (r == -EADDRNOTAVAIL) return log_warning_errno(r, "NV index referenced by token is missing, unwritten, or unusable, it could be for another system."); + if (r == -EUCLEAN) + return log_error_errno(r, "PCR values kept changing while unsealing the TPM2 secret, giving up. Something on this system extends a PCR continuously."); if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r)) { log_warning_errno(r, "TPM policy does not match current system state. Either system has been tampered with or policy out-of-date: %m"); /* Normalize to -EPERM so callers don't confuse it with -ENOANO's "needs PIN" meaning. */ @@ -257,6 +259,8 @@ int acquire_tpm2_key( return log_warning_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM."); if (r == -EADDRNOTAVAIL) return log_warning_errno(r, "NV index referenced by token is missing, unwritten, or unusable, it could be for another system."); + if (r == -EUCLEAN) + return log_error_errno(r, "PCR values kept changing while unsealing the TPM2 secret, giving up. Something on this system extends a PCR continuously."); if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r)) { log_warning_errno(r, "TPM policy does not match current system state. Either system has been tampered with or policy out-of-date: %m"); /* Normalize to -EPERM so callers don't confuse it with -ENOANO's "needs PIN" meaning. */