diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index f9a805964a..29d9dbbe2e 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -8090,14 +8090,15 @@ int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **pcr_values, s #endif } -/* Same as tpm2_parse_pcr_argument() but converts the pcr values to a pcr mask. If more than one hash - * algorithm is included in the pcr values array this results in error. This retains the previous behavior of - * tpm2_parse_pcr_argument() of clearing the mask if 'arg' is empty, replacing the mask if it is set to - * UINT32_MAX, and or-ing the mask otherwise. */ int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *mask) { #if HAVE_TPM2 int r; + /* Same as tpm2_parse_pcr_argument() but converts the pcr values to a pcr mask. If a hash algorithm or + * hash value is specified an error is generated (after all we only return the mask here, nothing + * else). This retains the previous behavior of tpm2_parse_pcr_argument() of clearing the mask if + * 'arg' is empty, replacing the mask if it is set to UINT32_MAX, and or-ing the mask otherwise. */ + assert(arg); assert(mask); @@ -8113,6 +8114,15 @@ int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *mask) { return 0; } + FOREACH_ARRAY(v, pcr_values, n_pcr_values) { + if (v->hash != 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Not expecting hash algorithm specification in PCR mask value, refusing: %s", arg); + if (v->value.size != 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Not expecting hash value specification in PCR mask value, refusing: %s", arg); + } + uint32_t new_mask; r = tpm2_pcr_values_to_mask(pcr_values, n_pcr_values, /* algorithm= */ 0, &new_mask); if (r < 0) diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c index e4f1f861b4..31ef6192b2 100644 --- a/src/test/test-tpm2.c +++ b/src/test/test-tpm2.c @@ -556,8 +556,13 @@ static void check_parse_pcr_argument( assert_se(tpm2_pcr_values_to_mask(expected_values, n_expected_values, expected_values[0].hash, &expected_mask) == 0); - assert_se(tpm2_parse_pcr_argument_to_mask(arg, &mask) == 0); - assert_se(mask == expected_mask); + _cleanup_free_ Tpm2PCRValue *arg_pcr_values = NULL; + size_t n_arg_pcr_values = 0; + assert_se(tpm2_parse_pcr_argument(arg, &arg_pcr_values, &n_arg_pcr_values) >= 0); + uint32_t mask2 = UINT32_MAX; + assert_se(tpm2_pcr_values_to_mask(arg_pcr_values, n_arg_pcr_values, /* algorithm= */ 0, &mask2) >= 0); + + assert_se((mask == UINT32_MAX ? mask2 : (mask|mask2)) == expected_mask); } size_t old_n_values = n_values; @@ -701,6 +706,10 @@ TEST(parse_pcr_argument) { check_parse_pcr_argument_to_mask("sysexts+17+23", 0x822000); check_parse_pcr_argument_to_mask("6+boot-loader-code,44", -EINVAL); check_parse_pcr_argument_to_mask("debug+24", -EINVAL); + check_parse_pcr_argument_to_mask("5:sha1=f013d66c7f6817d08b7eb2a93e6d0440c1f3e7f8", -EINVAL); + check_parse_pcr_argument_to_mask("0:sha256=f013d66c7f6817d08b7eb2a93e6d0440c1f3e7f8", -EINVAL); + check_parse_pcr_argument_to_mask("5:sha1=f013d66c7f6817d08b7eb2a93e6d0440c1f3e7f8,3", -EINVAL); + check_parse_pcr_argument_to_mask("3,0:sha256=f013d66c7f6817d08b7eb2a93e6d0440c1f3e7f8", -EINVAL); } static const TPMT_PUBLIC test_rsa_template = {