From: Kai Lüke Date: Mon, 20 Apr 2026 06:47:45 +0000 (+0900) Subject: cryptsetup: Report mismatching TPM token error separately X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=58d38f6360e24b2ae974077c5610a84a80c32da3;p=thirdparty%2Fsystemd.git cryptsetup: Report mismatching TPM token error separately When we enroll two UKIs with different PCR pub keys into one LUKS slot/ token each, then we can encounter the wrong one and should report it with a clearer error than the generic "Failed to unseal secret using TPM2". So when we don't have the right signature, report this as separate error. --- diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c index 450399ec129..d8d233fabb6 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c @@ -26,7 +26,7 @@ _public_ const char *cryptsetup_token_version(void) { static int log_debug_open_error(struct crypt_device *cd, int r) { if (r == -EAGAIN) return crypt_log_debug_errno(cd, r, "TPM2 device not found."); - if (r == -ENXIO) + if (r == -ENOSTR) return crypt_log_debug_errno(cd, r, "No matching TPM2 token data found."); return crypt_log_debug_errno(cd, r, TOKEN_NAME " open failed: %m."); diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c index edc0e7de5bc..b611aab83fe 100644 --- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c @@ -119,6 +119,8 @@ int acquire_luks2_key( 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 == -ENOSTR) + return log_error_errno(r, "No signature for current PCR policy in TPM2 signature JSON, token does not apply to current boot state: %m"); if (r < 0) return log_error_errno(r, "Failed to unseal secret using TPM2: %m"); diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c index 5d68f9bba46..f536cb8113a 100644 --- a/src/shared/cryptsetup-tpm2.c +++ b/src/shared/cryptsetup-tpm2.c @@ -177,6 +177,8 @@ 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 == -ENOSTR) + return log_error_errno(r, "No signature for current PCR policy in TPM2 signature JSON, token does not apply to current boot state: %m"); if (r < 0) return log_error_errno(r, "Failed to unseal secret using TPM2: %m"); @@ -230,6 +232,8 @@ 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 == -ENOSTR) + return log_error_errno(r, "No signature for current PCR policy in TPM2 signature JSON, token does not apply to current boot state: %m"); if (r == -ENOLCK) return log_error_errno(r, "TPM is in dictionary attack lock-out mode."); if (r == -EILSEQ) { diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 27606ab73d0..a60eca51acb 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4241,7 +4241,7 @@ static int find_signature( /* First, find field by bank */ b = sd_json_variant_by_key(v, k); if (!b) - return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Signature lacks data for PCR bank '%s'.", k); + return log_debug_errno(SYNTHETIC_ERRNO(ENOSTR), "Signature lacks data for PCR bank '%s'.", k); if (!sd_json_variant_is_array(b)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data is not a JSON array."); @@ -4311,7 +4311,7 @@ static int find_signature( return sd_json_variant_unbase64(sigj, ret_signature, ret_signature_size); } - return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key."); + return log_debug_errno(SYNTHETIC_ERRNO(ENOSTR), "Couldn't find signature for this PCR bank, PCR index and public key."); #else /* HAVE_OPENSSL */ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled."); #endif @@ -6661,6 +6661,7 @@ int tpm2_unseal(Tpm2Context *c, /* Returns the following errors: * * -EREMOTE → blob is from a different TPM + * -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 * -EREMCHG → submitted policy doesn't match NV index stored policy (in case of PolicyAuthorizeNV)