From 295affa3f7b74fb8bc680db2d7539e110e6d9130 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 27 Feb 2026 13:46:07 +0100 Subject: [PATCH 1/2] cryptenroll: Save primary algorithm type to the LUKS token 'tpm2-primary-alg' field is currently unset in LUKS JSON token both for the case when SRK was used for enrolling (--tpm2-device-key=) and for the case when SRK was obtained/generated (--tpm2-device=). While this information is not really needed for unsealing (the sealed object itself has key type in it), it may be convenient to see key type in e.g. 'cryptsetup luksDump' in the situations where key type matters. Since 'tpm2-primary-alg' is already defined, just set it properly in all cases. --- src/cryptenroll/cryptenroll-tpm2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 48f08e15d2..50abca4363 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -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, From 4883ef8aae80b0c1e69047c83b3830b9675db8e3 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 27 Feb 2026 14:20:20 +0100 Subject: [PATCH 2/2] cryptsetup-tokens: Print tpm2-primary-alg: only when it is known When 'tpm2-primary-alg' is missing in LUKS JSON token, the output of 'cryptsetup luksDump' is always: tpm2-primary-alg: ecc because tpm2_parse_luks2_json() returns the default (TPM2_ALG_ECC). This can be misleading and wrong. Make tpm2_parse_luks2_json() return the reality and move the default to tpm2_unseal(). --- .../cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c | 3 ++- src/shared/tpm2-util.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c index 4b9fe11199..933d18e2fd 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c @@ -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))); diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 3b559bf84c..f947e2fc48 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -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), @@ -8589,7 +8590,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;