]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: also add helper for parsing PCR arrays 24368/head
authorLennart Poettering <lennart@poettering.net>
Fri, 19 Aug 2022 14:16:03 +0000 (16:16 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Aug 2022 14:30:37 +0000 (16:30 +0200)
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
src/cryptsetup/cryptsetup-tpm2.c
src/shared/tpm2-util.c
src/shared/tpm2-util.h

index f0286ec1bf4f76864962a93e6fed17859c9b4c5b..9f5dd46734f48ef04025b83f9fd7831b96e21c41 100644 (file)
@@ -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)
index b84d64def85c613207c62982bc8b29091f08131d..c715c8f232e7fccc44c47a17f78b20ea9153445d 100644 (file)
@@ -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 */
index dde6ce8422521d103c825353190f3b95b693e7da..36999437f6fc23d85317077b88a26ff7e5611fe8 100644 (file)
@@ -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,
index 440d92e37906ca462f71c4c7769760af013eaca6..3e9464ea6746c350c19288283440ac42a1d200f1 100644 (file)
@@ -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