From 8de8ec88da2a0008752a08bc6886fa1c1d885776 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Aug 2022 16:16:03 +0200 Subject: [PATCH] tpm2-util: also add helper for parsing PCR arrays --- src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c | 21 +++++---------- src/cryptsetup/cryptsetup-tpm2.c | 22 ++++------------ src/shared/tpm2-util.c | 26 +++++++++++++++++++ src/shared/tpm2-util.h | 2 ++ 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c index f0286ec1bf4..9f5dd46734f 100644 --- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c @@ -66,8 +66,8 @@ int parse_luks2_tpm2_data( TPM2Flags *ret_flags) { int r; - JsonVariant *w, *e; - uint32_t pcr_mask = 0; + JsonVariant *w; + uint32_t pcr_mask; uint16_t pcr_bank = UINT16_MAX, primary_alg = TPM2_ALG_ECC; _cleanup_free_ char *base64_blob = NULL, *hex_policy_hash = NULL; _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; @@ -85,21 +85,12 @@ int parse_luks2_tpm2_data( return -EINVAL; w = json_variant_by_key(v, "tpm2-pcrs"); - if (!w || !json_variant_is_array(w)) + if (!w) return -EINVAL; - JSON_VARIANT_ARRAY_FOREACH(e, w) { - uint64_t u; - - if (!json_variant_is_number(e)) - return -EINVAL; - - u = json_variant_unsigned(e); - if (u >= TPM2_PCRS_MAX) - return -EINVAL; - - pcr_mask |= UINT32_C(1) << u; - } + r = tpm2_parse_pcr_json_array(w, &pcr_mask); + if (r < 0) + return r; if (search_pcr_mask != UINT32_MAX && search_pcr_mask != pcr_mask) diff --git a/src/cryptsetup/cryptsetup-tpm2.c b/src/cryptsetup/cryptsetup-tpm2.c index b84d64def85..c715c8f232e 100644 --- a/src/cryptsetup/cryptsetup-tpm2.c +++ b/src/cryptsetup/cryptsetup-tpm2.c @@ -185,7 +185,7 @@ int find_tpm2_auto_data( for (token = start_token; token < sym_crypt_token_max(CRYPT_LUKS2); token++) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; - JsonVariant *w, *e; + JsonVariant *w; int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-tpm2", &v); @@ -203,25 +203,13 @@ int find_tpm2_auto_data( } w = json_variant_by_key(v, "tpm2-pcrs"); - if (!w || !json_variant_is_array(w)) + if (!w) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-pcrs' field."); - assert(pcr_mask == 0); - JSON_VARIANT_ARRAY_FOREACH(e, w) { - uint64_t u; - - if (!json_variant_is_number(e)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "TPM2 PCR is not a number."); - - u = json_variant_unsigned(e); - if (u >= TPM2_PCRS_MAX) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "TPM2 PCR number out of range."); - - pcr_mask |= UINT32_C(1) << u; - } + r = tpm2_parse_pcr_json_array(w, &pcr_mask); + if (r < 0) + return log_error_errno(r, "Failed to parse TPM2 PCR mask: %m"); if (search_pcr_mask != UINT32_MAX && search_pcr_mask != pcr_mask) /* PCR mask doesn't match what is configured, ignore this entry */ diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index dde6ce84225..36999437f6f 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1410,6 +1410,32 @@ finish: return r; } +int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret) { + JsonVariant *e; + uint32_t mask = 0; + + if (!json_variant_is_array(v)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR array is not a JSON array."); + + JSON_VARIANT_ARRAY_FOREACH(e, v) { + uint64_t u; + + if (!json_variant_is_unsigned(e)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR is not an unsigned integer."); + + u = json_variant_unsigned(e); + if (u >= TPM2_PCRS_MAX) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR number out of range: %" PRIu64, u); + + mask |= UINT32_C(1) << u; + } + + if (ret) + *ret = mask; + + return 0; +} + int tpm2_make_luks2_json( int keyslot, uint32_t pcr_mask, diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 440d92e3790..3e9464ea674 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -55,6 +55,8 @@ int tpm2_find_device_auto(int log_level, char **ret); int tpm2_parse_pcrs(const char *s, uint32_t *ret); int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret); +int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret); + int tpm2_make_luks2_json(int keyslot, uint32_t pcr_mask, uint16_t pcr_bank, uint16_t primary_alg, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, TPM2Flags flags, JsonVariant **ret); #define TPM2_PCRS_MAX 24 -- 2.47.3