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.
This commit is contained in:
Kai Lüke
2026-07-10 08:07:47 +02:00
committed by Kai Lüke
parent 924552cfba
commit 58d38f6360
4 changed files with 10 additions and 3 deletions
@@ -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.");
@@ -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");
+4
View File
@@ -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) {
+3 -2
View File
@@ -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)