]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptenroll: explicitly pick PCR bank if literal PCR binding is off, but signed PCR...
authorLennart Poettering <lennart@poettering.net>
Thu, 23 May 2024 11:53:22 +0000 (13:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 23 May 2024 11:53:22 +0000 (13:53 +0200)
We so far derived the PCR bank to use from the PCR values specified fr
literal PCR binding. However, when that's not used then we left the bank
uninitialized – which will break if signed PCR binds are used (where we
need to pick a bank too after all).

Hence, let's explicitly pick a bank to use if literal PCR values are not
used, to make things just work.

Fixes: #32946
src/cryptenroll/cryptenroll-tpm2.c

index 1423f3b2ac3b071141b465364c42c6963aec5383..4e5d02a97e769ecceee528592ec354952fab7133 100644 (file)
@@ -371,8 +371,10 @@ int enroll_tpm2(struct crypt_device *cd,
 
         uint16_t hash_pcr_bank = 0;
         uint32_t hash_pcr_mask = 0;
+
         if (n_hash_pcr_values > 0) {
                 size_t hash_count;
+
                 r = tpm2_pcr_values_hash_count(hash_pcr_values, n_hash_pcr_values, &hash_count);
                 if (r < 0)
                         return log_error_errno(r, "Could not get hash count: %m");
@@ -380,10 +382,21 @@ int enroll_tpm2(struct crypt_device *cd,
                 if (hash_count > 1)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Multiple PCR banks selected.");
 
+                /* If we use a literal PCR value policy, derive the bank to use from the algorithm specified on the hash values */
                 hash_pcr_bank = hash_pcr_values[0].hash;
                 r = tpm2_pcr_values_to_mask(hash_pcr_values, n_hash_pcr_values, hash_pcr_bank, &hash_pcr_mask);
                 if (r < 0)
                         return log_error_errno(r, "Could not get hash mask: %m");
+        } else if (pubkey_pcr_mask != 0) {
+
+                /* If no literal PCR value policy is used, then let's determine the mask to use automatically
+                 * from the measurements of the TPM. */
+                r = tpm2_get_best_pcr_bank(
+                                tpm2_context,
+                                pubkey_pcr_mask,
+                                &hash_pcr_bank);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to determine best PCR bank: %m");
         }
 
         TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE);