From 62b9997afb850843f8fa52c66c3320f0f969d400 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2022 18:07:46 +0200 Subject: [PATCH] tpm2-util: split out code that derives "good" TPM2 banks into an strv from pcrphase and generalize it in tpm2-util.c That way we can reuse it later from different places. (cherry picked from commit e4481cc512f48d423115b10d4ae1c8e1381ff84b) Related: RHEL-16182 --- src/boot/pcrphase.c | 28 ++++++--------------------- src/shared/tpm2-util.c | 43 ++++++++++++++++++++++++++++++++++++++++++ src/shared/tpm2-util.h | 1 + 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/boot/pcrphase.c b/src/boot/pcrphase.c index 8e91e80e22..6e3a564f35 100644 --- a/src/boot/pcrphase.c +++ b/src/boot/pcrphase.c @@ -123,35 +123,19 @@ static int parse_argv(int argc, char *argv[]) { } static int determine_banks(struct tpm2_context *c) { - _cleanup_free_ TPMI_ALG_HASH *algs = NULL; - int n_algs, r; + _cleanup_strv_free_ char **l = NULL; + int r; assert(c); if (!strv_isempty(arg_banks)) /* Explicitly configured? Then use that */ return 0; - n_algs = tpm2_get_good_pcr_banks(c->esys_context, UINT32_C(1) << TPM_PCR_INDEX_KERNEL_IMAGE, &algs); - if (n_algs <= 0) - return n_algs; - - for (int i = 0; i < n_algs; i++) { - const EVP_MD *implementation; - const char *salg; - - salg = tpm2_pcr_bank_to_string(algs[i]); - if (!salg) - return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure."); - - implementation = EVP_get_digestbyname(salg); - if (!implementation) - return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure."); - - r = strv_extend(&arg_banks, EVP_MD_name(implementation)); - if (r < 0) - return log_oom(); - } + r = tpm2_get_good_pcr_banks_strv(c->esys_context, UINT32_C(1) << TPM_PCR_INDEX_KERNEL_IMAGE, &l); + if (r < 0) + return r; + strv_free_and_replace(arg_banks, l); return 0; } diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 8171b3e9e9..45ece9d1a6 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -730,6 +730,49 @@ int tpm2_get_good_pcr_banks( return 0; } +int tpm2_get_good_pcr_banks_strv( + ESYS_CONTEXT *c, + uint32_t pcr_mask, + char ***ret) { + + _cleanup_free_ TPMI_ALG_HASH *algs = NULL; + _cleanup_strv_free_ char **l = NULL; + int n_algs; + + assert(c); + assert(ret); + + n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs); + if (n_algs < 0) + return n_algs; + + for (int i = 0; i < n_algs; i++) { + _cleanup_free_ char *n = NULL; + const EVP_MD *implementation; + const char *salg; + + salg = tpm2_pcr_bank_to_string(algs[i]); + if (!salg) + return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure."); + + implementation = EVP_get_digestbyname(salg); + if (!implementation) + return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure."); + + n = strdup(ASSERT_PTR(EVP_MD_name(implementation))); + if (!n) + return log_oom(); + + ascii_strlower(n); /* OpenSSL uses uppercase digest names, we prefer them lower case. */ + + if (strv_consume(&l, TAKE_PTR(n)) < 0) + return log_oom(); + } + + *ret = TAKE_PTR(l); + return 0; +} + static void hash_pin(const char *pin, size_t len, TPM2B_AUTH *auth) { struct sha256_ctx hash; diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index c240335ae6..6d83281be0 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -68,6 +68,7 @@ static inline void Esys_Freep(void *p) { } int tpm2_get_good_pcr_banks(ESYS_CONTEXT *c, uint32_t pcr_mask, TPMI_ALG_HASH **ret_banks); +int tpm2_get_good_pcr_banks_strv(ESYS_CONTEXT *c, uint32_t pcr_mask, char ***ret); #else struct tpm2_context;