summaryrefslogtreecommitdiffstats
path: root/src/shared/creds-util.c
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2023-07-12 23:35:54 +0200
committerDan Streetman <ddstreet@ieee.org>2023-08-04 17:20:22 +0200
commit9e4379945b74ee7920fe375be0bcb04d8ef53873 (patch)
tree478508e67c611cefebd184e82f0262362d61bcc4 /src/shared/creds-util.c
parenttpm2: add functions to convert TPM2B_PUBLIC to/from openssl pkey or PEM (diff)
downloadsystemd-9e4379945b74ee7920fe375be0bcb04d8ef53873.tar.xz
systemd-9e4379945b74ee7920fe375be0bcb04d8ef53873.zip
tpm2: move policy calculation out of tpm2_seal()
Move the calculation of the sealed object policy hash out of the tpm2_seal() function. Instead, callers of tpm2_seal() can directly call tpm2_calculate_sealing_policy() and then provide the policy hash to tpm2_seal().
Diffstat (limited to 'src/shared/creds-util.c')
-rw-r--r--src/shared/creds-util.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c
index 16df01b9ca..8a5240e5f1 100644
--- a/src/shared/creds-util.c
+++ b/src/shared/creds-util.c
@@ -825,18 +825,49 @@ int encrypt_credential_and_warn(
if (!pubkey)
tpm2_pubkey_pcr_mask = 0;
- r = tpm2_seal(tpm2_device,
- tpm2_hash_pcr_mask,
- pubkey, pubkey_size,
- tpm2_pubkey_pcr_mask,
+ _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
+ r = tpm2_context_new(tpm2_device, &tpm2_context);
+ if (r < 0)
+ return r;
+
+ r = tpm2_get_best_pcr_bank(tpm2_context, tpm2_hash_pcr_mask | tpm2_pubkey_pcr_mask, &tpm2_pcr_bank);
+ if (r < 0)
+ return r;
+
+ TPML_PCR_SELECTION tpm2_hash_pcr_selection;
+ tpm2_tpml_pcr_selection_from_mask(tpm2_hash_pcr_mask, tpm2_pcr_bank, &tpm2_hash_pcr_selection);
+
+ _cleanup_free_ Tpm2PCRValue *tpm2_hash_pcr_values = NULL;
+ size_t tpm2_n_hash_pcr_values;
+ r = tpm2_pcr_read(tpm2_context, &tpm2_hash_pcr_selection, &tpm2_hash_pcr_values, &tpm2_n_hash_pcr_values);
+ if (r < 0)
+ return r;
+
+ TPM2B_PUBLIC public;
+ if (pubkey) {
+ r = tpm2_tpm2b_public_from_pem(pubkey, pubkey_size, &public);
+ if (r < 0)
+ return log_error_errno(r, "Could not convert public key to TPM2B_PUBLIC: %m");
+ }
+
+ TPM2B_DIGEST tpm2_policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE);
+ r = tpm2_calculate_sealing_policy(
+ tpm2_hash_pcr_values,
+ tpm2_n_hash_pcr_values,
+ pubkey ? &public : NULL,
+ /* use_pin= */ false,
+ &tpm2_policy);
+ if (r < 0)
+ return r;
+
+ r = tpm2_seal(tpm2_context,
+ &tpm2_policy,
/* pin= */ NULL,
&tpm2_key, &tpm2_key_size,
&tpm2_blob, &tpm2_blob_size,
- &tpm2_policy_hash, &tpm2_policy_hash_size,
- &tpm2_pcr_bank,
&tpm2_primary_alg,
/* ret_srk_buf= */ NULL,
- /* ret_srk_buf_size= */ 0);
+ /* ret_srk_buf_size= */ NULL);
if (r < 0) {
if (sd_id128_equal(with_key, _CRED_AUTO_INITRD))
log_warning("TPM2 present and used, but we didn't manage to talk to it. Credential will be refused if SecureBoot is enabled.");
@@ -846,6 +877,12 @@ int encrypt_credential_and_warn(
log_notice_errno(r, "TPM2 sealing didn't work, continuing without TPM2: %m");
}
+ tpm2_policy_hash_size = tpm2_policy.size;
+ tpm2_policy_hash = malloc(tpm2_policy_hash_size);
+ if (!tpm2_policy_hash)
+ return log_oom();
+ memcpy(tpm2_policy_hash, tpm2_policy.buffer, tpm2_policy_hash_size);
+
assert(tpm2_blob_size <= CREDENTIAL_FIELD_SIZE_MAX);
assert(tpm2_policy_hash_size <= CREDENTIAL_FIELD_SIZE_MAX);
}