cryptsetup: fix 'tpm2-primary-alg' information in 'cryptsetup luksDump' (#40872)

It was noticed that cryptsetup luksDump outputs

  tpm2-primary-alg: ecc

regardless of the actual primary key type. Namely, in the situation when
RSA SRK is passed to 'systemd-cryptenroll', the output is incorrect and
misleading. Turns out 'tpm2-primary-alg' is not currently used for
unsealing as 'tpm2_srk' object has it in its properties but the
misleading information problem stays.

Fix the issue with a two-fold fix:
- Put the SRK primary alg type to the JSON token so 'cryptsetup
luksDump' has a chance to actually print the right information without
the need to inspect SRK.
- Avoid printing 'tpm2-primary-alg' when it is unset in the JSON as the
default 'ECC' may not match the reality.

No real functional change for the sealing/unsealing expected.
This commit is contained in:
Yu Watanabe
2026-03-02 12:40:40 +09:00
committed by GitHub
3 changed files with 11 additions and 6 deletions
+6 -3
View File
@@ -313,6 +313,7 @@ int enroll_tpm2(struct crypt_device *cd,
ssize_t base64_encoded_size;
int r, keyslot, slot_to_wipe = -1;
TPM2Flags flags = 0;
uint16_t primary_alg = 0;
uint8_t binary_salt[SHA256_DIGEST_SIZE] = {};
/*
* erase the salt, we'd rather attempt to not have this in a coredump
@@ -402,6 +403,8 @@ int enroll_tpm2(struct crypt_device *cd,
if (!tpm2_pcr_values_has_all_values(hash_pcr_values, n_hash_pcr_values))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Must provide all PCR values when using TPM2 device key.");
primary_alg = device_key_public.publicArea.type;
} else {
r = tpm2_context_new_or_warn(device, &tpm2_context);
if (r < 0)
@@ -515,7 +518,7 @@ int enroll_tpm2(struct crypt_device *cd,
&secret,
&blobs,
&n_blobs,
/* ret_primary_alg= */ NULL,
&primary_alg,
&srk);
if (r < 0)
return log_error_errno(r, "Failed to seal to TPM2: %m");
@@ -553,7 +556,7 @@ int enroll_tpm2(struct crypt_device *cd,
signature_json,
pin_str,
pcrlock_path ? &pcrlock_policy : NULL,
/* primary_alg= */ 0,
primary_alg,
blobs,
n_blobs,
policy_hash_as_iovec,
@@ -592,7 +595,7 @@ int enroll_tpm2(struct crypt_device *cd,
hash_pcr_bank,
&pubkey,
pubkey_pcr_mask,
/* primary_alg= */ 0,
primary_alg,
blobs,
n_blobs,
policy_hash_as_iovec,
@@ -230,7 +230,8 @@ _public_ void cryptsetup_token_dump(
crypt_log(cd, "\ttpm2-pcr-bank: %s\n", strna(tpm2_hash_alg_to_string(pcr_bank)));
crypt_log(cd, "\ttpm2-pubkey:" CRYPT_DUMP_LINE_SEP "%s\n", pubkey_str);
crypt_log(cd, "\ttpm2-pubkey-pcrs: %s\n", strna(pubkey_pcrs_str));
crypt_log(cd, "\ttpm2-primary-alg: %s\n", strna(tpm2_asym_alg_to_string(primary_alg)));
if (primary_alg != 0)
crypt_log(cd, "\ttpm2-primary-alg: %s\n", strna(tpm2_asym_alg_to_string(primary_alg)));
crypt_log(cd, "\ttpm2-pin: %s\n", true_false(flags & TPM2_FLAGS_USE_PIN));
crypt_log(cd, "\ttpm2-pcrlock: %s\n", true_false(flags & TPM2_FLAGS_USE_PCRLOCK));
crypt_log(cd, "\ttpm2-salt: %s\n", true_false(iovec_is_set(&salt)));
+3 -2
View File
@@ -5625,8 +5625,9 @@ int tpm2_unseal(Tpm2Context *c,
if (r < 0)
return r;
if (r == 0) {
/* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
if (primary_alg == 0)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "No SRK or primary algorithm provided.");
primary_alg = TPM2_ALG_ECC;
TPM2B_PUBLIC template = {
.size = sizeof(TPMT_PUBLIC),
@@ -8592,7 +8593,7 @@ int tpm2_parse_luks2_json(
_cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
uint32_t hash_pcr_mask = 0, pubkey_pcr_mask = 0;
uint16_t primary_alg = TPM2_ALG_ECC; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
uint16_t primary_alg = 0;
uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
int r, keyslot = -1;
TPM2Flags flags = 0;