diff options
author | Dan Streetman <ddstreet@ieee.org> | 2023-07-12 23:35:54 +0200 |
---|---|---|
committer | Dan Streetman <ddstreet@ieee.org> | 2023-08-04 17:20:22 +0200 |
commit | 9e4379945b74ee7920fe375be0bcb04d8ef53873 (patch) | |
tree | 478508e67c611cefebd184e82f0262362d61bcc4 /src/shared/creds-util.c | |
parent | tpm2: add functions to convert TPM2B_PUBLIC to/from openssl pkey or PEM (diff) | |
download | systemd-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.c | 51 |
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); } |