From 7354a7ccd4aa27bc8c94280c82d0ae54fd947c2a Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 10:34:57 -0400 Subject: [PATCH 01/21] tpm2: change *alg_to_* functions to use switch() --- src/shared/tpm2-util.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 3b83dafa6f..ad885e8c4f 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4654,28 +4654,34 @@ int tpm2_parse_luks2_json( } int tpm2_hash_alg_to_size(uint16_t alg) { - if (alg == TPM2_ALG_SHA1) + switch (alg) { + case TPM2_ALG_SHA1: return 20; - if (alg == TPM2_ALG_SHA256) + case TPM2_ALG_SHA256: return 32; - if (alg == TPM2_ALG_SHA384) + case TPM2_ALG_SHA384: return 48; - if (alg == TPM2_ALG_SHA512) + case TPM2_ALG_SHA512: return 64; - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm id 0x%" PRIx16, alg); + default: + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm id 0x%" PRIx16, alg); + } } const char *tpm2_hash_alg_to_string(uint16_t alg) { - if (alg == TPM2_ALG_SHA1) + switch (alg) { + case TPM2_ALG_SHA1: return "sha1"; - if (alg == TPM2_ALG_SHA256) + case TPM2_ALG_SHA256: return "sha256"; - if (alg == TPM2_ALG_SHA384) + case TPM2_ALG_SHA384: return "sha384"; - if (alg == TPM2_ALG_SHA512) + case TPM2_ALG_SHA512: return "sha512"; - log_debug("Unknown hash algorithm id 0x%" PRIx16, alg); - return NULL; + default: + log_debug("Unknown hash algorithm id 0x%" PRIx16, alg); + return NULL; + } } int tpm2_hash_alg_from_string(const char *alg) { @@ -4691,12 +4697,15 @@ int tpm2_hash_alg_from_string(const char *alg) { } const char *tpm2_asym_alg_to_string(uint16_t alg) { - if (alg == TPM2_ALG_ECC) + switch (alg) { + case TPM2_ALG_ECC: return "ecc"; - if (alg == TPM2_ALG_RSA) + case TPM2_ALG_RSA: return "rsa"; - log_debug("Unknown asymmetric algorithm id 0x%" PRIx16, alg); - return NULL; + default: + log_debug("Unknown asymmetric algorithm id 0x%" PRIx16, alg); + return NULL; + } } int tpm2_asym_alg_from_string(const char *alg) { From cc1a78d5c48a0100169a847da0e252f2b01b05e6 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 10:38:48 -0400 Subject: [PATCH 02/21] tpm2: lowercase TPM2_PCR_VALUE[S]_VALID functions As these are not macros, they should be lowercase. --- src/cryptenroll/cryptenroll-tpm2.c | 2 +- src/shared/tpm2-util.c | 16 ++++++++-------- src/shared/tpm2-util.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 86aed31838..d7f81ede3f 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -163,7 +163,7 @@ int enroll_tpm2(struct crypt_device *cd, assert(cd); assert(volume_key); assert(volume_key_size > 0); - assert(TPM2_PCR_VALUES_VALID(hash_pcr_values, n_hash_pcr_values)); + assert(tpm2_pcr_values_valid(hash_pcr_values, n_hash_pcr_values)); assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask)); assert_se(node = crypt_get_device_name(cd)); diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index ad885e8c4f..cc90a379f8 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1521,7 +1521,7 @@ size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l) { return weight; } -bool TPM2_PCR_VALUE_VALID(const Tpm2PCRValue *pcr_value) { +bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) { int r; assert(pcr_value); @@ -1552,13 +1552,13 @@ bool TPM2_PCR_VALUE_VALID(const Tpm2PCRValue *pcr_value) { * 1) all entries must be sorted in ascending order (e.g. using tpm2_sort_pcr_values()) * 2) all entries must be unique, i.e. there cannot be 2 entries with the same hash and index */ -bool TPM2_PCR_VALUES_VALID(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { +bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { assert(pcr_values || n_pcr_values == 0); for (size_t i = 0; i < n_pcr_values; i++) { const Tpm2PCRValue *v = &pcr_values[i]; - if (!TPM2_PCR_VALUE_VALID(v)) + if (!tpm2_pcr_value_valid(v)) return false; if (i == 0) @@ -1633,7 +1633,7 @@ int tpm2_pcr_values_to_mask(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, assert(pcr_values || n_pcr_values == 0); assert(ret_mask); - if (!TPM2_PCR_VALUES_VALID(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid PCR values."); for (size_t i = 0; i < n_pcr_values; i++) @@ -1658,7 +1658,7 @@ int tpm2_tpml_pcr_selection_from_pcr_values( assert(pcr_values || n_pcr_values == 0); - if (!TPM2_PCR_VALUES_VALID(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "PCR values are not valid."); for (size_t i = 0; i < n_pcr_values; i++) { @@ -2315,7 +2315,7 @@ int tpm2_pcr_read( tpm2_sort_pcr_values(pcr_values, n_pcr_values); - if (!TPM2_PCR_VALUES_VALID(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PCR values read from TPM are not valid."); *ret_pcr_values = TAKE_PTR(pcr_values); @@ -4793,7 +4793,7 @@ int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size tpm2_sort_pcr_values(pcr_values, n_pcr_values); - if (!TPM2_PCR_VALUES_VALID(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid."); *ret_pcr_values = TAKE_PTR(pcr_values); @@ -4835,7 +4835,7 @@ int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **ret_pcr_value tpm2_sort_pcr_values(pcr_values, n_pcr_values); - if (!TPM2_PCR_VALUES_VALID(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid."); SWAP_TWO(*ret_pcr_values, pcr_values); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 23a97f15ff..9045934563 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -76,11 +76,11 @@ typedef struct { } Tpm2PCRValue; #define TPM2_PCR_VALUE_MAKE(i, h, v) (Tpm2PCRValue) { .index = (i), .hash = (h), .value = ((TPM2B_DIGEST) v), } -bool TPM2_PCR_VALUE_VALID(const Tpm2PCRValue *pcr_value); +bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value); int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value); char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value); -bool TPM2_PCR_VALUES_VALID(const Tpm2PCRValue *pcr_values, size_t n_pcr_values); +bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values); void tpm2_sort_pcr_values(Tpm2PCRValue *pcr_values, size_t n_pcr_values); int tpm2_pcr_values_from_mask(uint32_t mask, TPMI_ALG_HASH hash, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values); int tpm2_pcr_values_to_mask(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, TPMI_ALG_HASH hash, uint32_t *ret_mask); From 3cd4145f347461018fe79263534f59df6d3cde7a Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 10:42:35 -0400 Subject: [PATCH 03/21] tpm2: move cast from lhs to rhs in uint16_t/int comparison --- src/shared/tpm2-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index cc90a379f8..51cb1beeb9 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1537,7 +1537,7 @@ bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) { if (r < 0) return false; - if ((int) pcr_value->value.size != r) { + if (pcr_value->value.size != (size_t) r) { log_debug("PCR hash 0x%" PRIx16 " expected size %d does not match actual size %" PRIu16 ".", pcr_value->hash, r, pcr_value->value.size); return false; From 064ac95d81b9ab6a6eb8849cacce928015d44e5b Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 10:48:20 -0400 Subject: [PATCH 04/21] tpm2: in validator functions, return false instead of assert failure --- src/shared/tpm2-util.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 51cb1beeb9..35433371be 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1524,7 +1524,8 @@ size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l) { bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) { int r; - assert(pcr_value); + if (!pcr_value) + return false; if (!TPM2_PCR_INDEX_VALID(pcr_value->index)) { log_debug("PCR index %u invalid.", pcr_value->index); @@ -1551,9 +1552,12 @@ bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) { * * 1) all entries must be sorted in ascending order (e.g. using tpm2_sort_pcr_values()) * 2) all entries must be unique, i.e. there cannot be 2 entries with the same hash and index + * + * Returns true if all entries are valid (or if no entries are provided), false otherwise. */ bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { - assert(pcr_values || n_pcr_values == 0); + if (!pcr_values && n_pcr_values > 0) + return false; for (size_t i = 0; i < n_pcr_values; i++) { const Tpm2PCRValue *v = &pcr_values[i]; From 193fd5730e980db57cb092bd90cbc1966d9b404e Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 11:02:55 -0400 Subject: [PATCH 05/21] tpm2: in tpm2_pcr_values_valid() use FOREACH_ARRAY() --- src/shared/tpm2-util.c | 119 ++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 66 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 35433371be..f4b9f4ff33 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1282,21 +1282,14 @@ void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b) tpm2_tpms_pcr_selection_from_mask(0, b->hash, b); } -#define FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms) \ - _FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms, UNIQ) -#define _FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms, uniq) \ - FOREACH_PCR_IN_MASK(pcr, tpm2_tpms_pcr_selection_to_mask(tpms)) - #define FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \ - UNIQ_FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, UNIQ) -#define UNIQ_FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, uniq) \ - for (TPML_PCR_SELECTION *UNIQ_T(_tpml, uniq) = (TPML_PCR_SELECTION*)(tpml); \ - UNIQ_T(_tpml, uniq); UNIQ_T(_tpml, uniq) = NULL) \ - _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, UNIQ_T(_tpml, uniq)) -#define _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \ - for (TPMS_PCR_SELECTION *tpms = tpml->pcrSelections; \ - (uint32_t)(tpms - tpml->pcrSelections) < tpml->count; \ - tpms++) + _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, UNIQ_T(l, UNIQ)) +#define _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, l) \ + for (typeof(tpml) (l) = (tpml); (l); (l) = NULL) \ + FOREACH_ARRAY(tpms, (l)->pcrSelections, (l)->count) + +#define FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms) \ + FOREACH_PCR_IN_MASK(pcr, tpm2_tpms_pcr_selection_to_mask(tpms)) #define FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr, tpms, tpml) \ FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \ @@ -1369,6 +1362,14 @@ static TPMS_PCR_SELECTION *tpm2_tpml_pcr_selection_get_tpms_pcr_selection( return selection; } +/* Combine all duplicate (same hash alg) TPMS_PCR_SELECTION entries in 'l'. */ +static void tpm2_tpml_pcr_selection_cleanup(TPML_PCR_SELECTION *l) { + /* Can't use FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION() because we might modify l->count */ + for (uint32_t i = 0; i < l->count; i++) + /* This removes all duplicate TPMS_PCR_SELECTION entries for this hash. */ + (void) tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, l->pcrSelections[i].hash); +} + /* Convert a TPML_PCR_SELECTION object to a mask. Returns empty mask (i.e. 0) if 'hash_alg' is not in the object. */ uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash_alg) { assert(l); @@ -1398,13 +1399,6 @@ void tpm2_tpml_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TP }; } -/* Combine all duplicate (same hash alg) TPMS_PCR_SELECTION entries in 'l'. */ -static void tpm2_tpml_pcr_selection_cleanup(TPML_PCR_SELECTION *l) { - FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) - /* This removes all duplicates for s->hash. */ - (void) tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, s->hash); -} - /* Add the PCR selections in 's' to the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. Adds a new * TPMS_PCR_SELECTION entry for the hash alg if needed. This may modify the TPML_PCR_SELECTION by combining * entries with the same hash alg. */ @@ -1478,7 +1472,7 @@ void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION assert(a); assert(b); - FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, (TPML_PCR_SELECTION*) b) + FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b) tpm2_tpml_pcr_selection_add_tpms_pcr_selection(a, selection_b); } @@ -1487,7 +1481,7 @@ void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION assert(a); assert(b); - FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, (TPML_PCR_SELECTION*) b) + FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b) tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(a, selection_b); } @@ -1495,7 +1489,7 @@ char *tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION *l) { assert(l); _cleanup_free_ char *banks = NULL; - FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, (TPML_PCR_SELECTION*) l) { + FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) { if (tpm2_tpms_pcr_selection_is_empty(s)) continue; @@ -1559,36 +1553,35 @@ bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) if (!pcr_values && n_pcr_values > 0) return false; - for (size_t i = 0; i < n_pcr_values; i++) { - const Tpm2PCRValue *v = &pcr_values[i]; - - if (!tpm2_pcr_value_valid(v)) + const Tpm2PCRValue *previous = NULL; + FOREACH_ARRAY(current, pcr_values, n_pcr_values) { + if (!tpm2_pcr_value_valid(current)) return false; - if (i == 0) + if (!previous) { + previous = current; continue; - - const Tpm2PCRValue *l = &pcr_values[i - 1]; + } /* Hashes must be sorted in ascending order */ - if (v->hash < l->hash) { + if (current->hash < previous->hash) { log_debug("PCR values not in ascending order, hash %" PRIu16 " is after %" PRIu16 ".", - v->hash, l->hash); + current->hash, previous->hash); return false; } - if (v->hash == l->hash) { + if (current->hash == previous->hash) { /* Indexes (for the same hash) must be sorted in ascending order */ - if (v->index < l->index) { + if (current->index < previous->index) { log_debug("PCR values not in ascending order, hash %" PRIu16 " index %u is after %u.", - v->hash, v->index, l->index); + current->hash, current->index, previous->index); return false; } /* Indexes (for the same hash) must not be duplicates */ - if (v->index == l->index) { + if (current->index == previous->index) { log_debug("PCR values contain duplicates for hash %" PRIu16 " index %u.", - v->hash, v->index); + current->hash, previous->index); return false; } } @@ -1640,9 +1633,9 @@ int tpm2_pcr_values_to_mask(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid PCR values."); - for (size_t i = 0; i < n_pcr_values; i++) - if (pcr_values[i].hash == hash) - SET_BIT(mask, pcr_values[i].index); + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (v->hash == hash) + SET_BIT(mask, v->index); *ret_mask = mask; @@ -1665,14 +1658,10 @@ int tpm2_tpml_pcr_selection_from_pcr_values( if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "PCR values are not valid."); - for (size_t i = 0; i < n_pcr_values; i++) { - unsigned index = pcr_values[i].index; - TPMI_ALG_HASH hash = pcr_values[i].hash; - const TPM2B_DIGEST *digest = &pcr_values[i].value; + FOREACH_ARRAY(v, pcr_values, n_pcr_values) { + tpm2_tpml_pcr_selection_add_mask(&selection, v->hash, INDEX_TO_MASK(uint32_t, v->index)); - tpm2_tpml_pcr_selection_add_mask(&selection, hash, INDEX_TO_MASK(uint32_t, index)); - - if (!GREEDY_REALLOC_APPEND(values, n_values, digest, 1)) + if (!GREEDY_REALLOC_APPEND(values, n_values, &v->value, 1)) return log_oom_debug(); } @@ -1830,8 +1819,8 @@ int tpm2_pcr_values_from_string(const char *arg, Tpm2PCRValue **ret_pcr_values, char *tpm2_pcr_values_to_string(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { _cleanup_free_ char *s = NULL; - for (size_t i = 0; i < n_pcr_values; i++) { - _cleanup_free_ char *pcrstr = tpm2_pcr_value_to_string(&pcr_values[i]); + FOREACH_ARRAY(v, pcr_values, n_pcr_values) { + _cleanup_free_ char *pcrstr = tpm2_pcr_value_to_string(v); if (!pcrstr || !strextend_with_separator(&s, "+", pcrstr)) return NULL; } @@ -2357,9 +2346,7 @@ int tpm2_pcr_read_missing_values(Tpm2Context *c, Tpm2PCRValue *pcr_values, size_ } } - for (size_t i = 0; i < n_pcr_values; i++) { - Tpm2PCRValue *v = &pcr_values[i]; - + FOREACH_ARRAY(v, pcr_values, n_pcr_values) { if (v->hash == 0) v->hash = pcr_bank; @@ -2415,9 +2402,9 @@ static int tpm2_pcr_mask_good( return r; /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */ - for (unsigned i = 0; i < n_pcr_values; i++) - if (!memeqbyte(0x00, pcr_values[i].value.buffer, pcr_values[i].value.size) && - !memeqbyte(0xFF, pcr_values[i].value.buffer, pcr_values[i].value.size)) + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (!memeqbyte(0x00, v->value.buffer, v->value.size) && + !memeqbyte(0xFF, v->value.buffer, v->value.size)) return true; return false; @@ -2611,12 +2598,12 @@ int tpm2_get_good_pcr_banks_strv( if (n_algs < 0) return n_algs; - for (int i = 0; i < n_algs; i++) { + FOREACH_ARRAY(a, algs, n_algs) { _cleanup_free_ char *n = NULL; const EVP_MD *implementation; const char *salg; - salg = tpm2_hash_alg_to_string(algs[i]); + salg = tpm2_hash_alg_to_string(*a); if (!salg) return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure."); @@ -2688,8 +2675,8 @@ int tpm2_digest_many( return 0; } - for (size_t i = 0; i < n_data; i++) - sha256_process_bytes(data[i].iov_base, data[i].iov_len, &ctx); + FOREACH_ARRAY(d, data, n_data) + sha256_process_bytes(d->iov_base, d->iov_len, &ctx); sha256_finish_ctx(&ctx, digest->buffer); @@ -4758,16 +4745,16 @@ Tpm2Support tpm2_support(void) { #if HAVE_TPM2 static void tpm2_pcr_values_apply_default_hash_alg(Tpm2PCRValue *pcr_values, size_t n_pcr_values) { TPMI_ALG_HASH default_hash = 0; - for (size_t i = 0; i < n_pcr_values; i++) - if (pcr_values[i].hash != 0) { - default_hash = pcr_values[i].hash; + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (v->hash != 0) { + default_hash = v->hash; break; } if (default_hash != 0) - for (size_t i = 0; i < n_pcr_values; i++) - if (pcr_values[i].hash == 0) - pcr_values[i].hash = default_hash; + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (v->hash == 0) + v->hash = default_hash; } #endif From 7001a7daf7b2cf67991acc8383a58ff71432188c Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 16:29:44 -0400 Subject: [PATCH 06/21] tpm2: use SIZE_MAX instead of strlen() for unhexmem() --- src/shared/tpm2-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index f4b9f4ff33..794474776b 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1738,7 +1738,7 @@ int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value) { _cleanup_free_ void *buf = NULL; size_t buf_size = 0; - r = unhexmem(p, strlen(p), &buf, &buf_size); + r = unhexmem(p, SIZE_MAX, &buf, &buf_size); if (r < 0) return log_error_errno(r, "Invalid pcr hash value '%s': %m", p); From 2b2ee3f265957e4dda9f82b1b6e8138117a90502 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 17:29:28 -0400 Subject: [PATCH 07/21] tpm2: put !isempty() check inside previous !isempty() check --- src/shared/tpm2-util.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 794474776b..4b36872864 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1730,23 +1730,23 @@ int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value) { if (r < 0) return log_error_errno(r, "Invalid pcr hash algorithm '%s': %m", hash); pcr_value.hash = (TPMI_ALG_HASH) r; - } - if (!isempty(p)) { - /* Remove leading 0x if present */ - p = startswith_no_case(p, "0x") ?: p; + if (!isempty(p)) { + /* Remove leading 0x if present */ + p = startswith_no_case(p, "0x") ?: p; - _cleanup_free_ void *buf = NULL; - size_t buf_size = 0; - r = unhexmem(p, SIZE_MAX, &buf, &buf_size); - if (r < 0) - return log_error_errno(r, "Invalid pcr hash value '%s': %m", p); + _cleanup_free_ void *buf = NULL; + size_t buf_size = 0; + r = unhexmem(p, SIZE_MAX, &buf, &buf_size); + if (r < 0) + return log_error_errno(r, "Invalid pcr hash value '%s': %m", p); - r = TPM2B_DIGEST_CHECK_SIZE(buf_size); - if (r < 0) - return log_error_errno(r, "PCR hash value size %zu too large.", buf_size); + r = TPM2B_DIGEST_CHECK_SIZE(buf_size); + if (r < 0) + return log_error_errno(r, "PCR hash value size %zu too large.", buf_size); - pcr_value.value = TPM2B_DIGEST_MAKE(buf, buf_size); + pcr_value.value = TPM2B_DIGEST_MAKE(buf, buf_size); + } } *ret_pcr_value = pcr_value; From 495f2bf57ccd74c5e63040f05430e1148942b2c7 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 17:31:56 -0400 Subject: [PATCH 08/21] tpm2: simplify call to asprintf() --- src/shared/tpm2-util.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 4b36872864..db51d46bd4 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1759,10 +1759,8 @@ int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value) { * string. This does not check for validity. */ char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value) { _cleanup_free_ char *index = NULL, *value = NULL; - int r; - r = asprintf(&index, "%u", pcr_value->index); - if (r < 0) + if (asprintf(&index, "%u", pcr_value->index) < 0) return NULL; const char *hash = tpm2_hash_alg_to_string(pcr_value->hash); From 8e757259c3f491841a6c5aa853f2cfce41e95b2e Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 17:37:40 -0400 Subject: [PATCH 09/21] tpm2: check pcr value hash != 0 before looking up hash algorithm name --- src/shared/tpm2-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index db51d46bd4..8ba363fdcc 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1763,7 +1763,7 @@ char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value) { if (asprintf(&index, "%u", pcr_value->index) < 0) return NULL; - const char *hash = tpm2_hash_alg_to_string(pcr_value->hash); + const char *hash = pcr_value->hash > 0 ? tpm2_hash_alg_to_string(pcr_value->hash) : NULL; if (hash && pcr_value->value.size > 0) { value = hexmem(pcr_value->value.buffer, pcr_value->value.size); From 85b6f299b2ae11ea589d373559d43cfe88c8d30f Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 17:39:20 -0400 Subject: [PATCH 10/21] tpm2: use strempty() --- src/shared/tpm2-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 8ba363fdcc..2b9bdb1da4 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1771,7 +1771,7 @@ char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value) { return NULL; } - return strjoin(index, hash ? ":" : "", hash ?: "", value ? "=" : "", value ?: ""); + return strjoin(index, hash ? ":" : "", strempty(hash), value ? "=" : "", strempty(value)); } /* Parse a string argument into an array of Tpm2PCRValue objects. From c6e5178220237fb10187c573a8ac4384993c0206 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 17:42:39 -0400 Subject: [PATCH 11/21] tpm2: split TPM2_PCR_VALUE_MAKE() over multiple lines --- src/shared/tpm2-util.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 9045934563..6883975174 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -75,7 +75,13 @@ typedef struct { TPM2B_DIGEST value; } Tpm2PCRValue; -#define TPM2_PCR_VALUE_MAKE(i, h, v) (Tpm2PCRValue) { .index = (i), .hash = (h), .value = ((TPM2B_DIGEST) v), } +#define TPM2_PCR_VALUE_MAKE(i, h, v) \ + (Tpm2PCRValue) { \ + .index = (i), \ + .hash = (h), \ + .value = ((TPM2B_DIGEST) v), \ + } + bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value); int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value); char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value); From ae2b38e4630b76103367869b5ace87ae0dd34f99 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 18:09:52 -0400 Subject: [PATCH 12/21] tpm2: remove ret_ prefix from input/output params --- src/shared/tpm2-util.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 2b9bdb1da4..d53f4cd5a2 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4802,33 +4802,33 @@ int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size * including application of the default hash algorithm. Then the two arrays are combined, the default hash * algorithm check applied again (in case either the previous or current array had no default hash * algorithm), and then the resulting array is sorted and rechecked for validity. */ -int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) { +int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **pcr_values, size_t *n_pcr_values) { #if HAVE_TPM2 int r; assert(arg); - assert(ret_pcr_values); - assert(ret_n_pcr_values); + assert(pcr_values); + assert(n_pcr_values); - _cleanup_free_ Tpm2PCRValue *pcr_values = NULL; - size_t n_pcr_values; - r = tpm2_parse_pcr_argument(arg, &pcr_values, &n_pcr_values); + _cleanup_free_ Tpm2PCRValue *more_pcr_values = NULL; + size_t n_more_pcr_values; + r = tpm2_parse_pcr_argument(arg, &more_pcr_values, &n_more_pcr_values); if (r < 0) return r; /* If we got previous values, append them. */ - if (*ret_pcr_values && !GREEDY_REALLOC_APPEND(pcr_values, n_pcr_values, *ret_pcr_values, *ret_n_pcr_values)) + if (*pcr_values && !GREEDY_REALLOC_APPEND(more_pcr_values, n_more_pcr_values, *pcr_values, *n_pcr_values)) return log_oom(); - tpm2_pcr_values_apply_default_hash_alg(pcr_values, n_pcr_values); + tpm2_pcr_values_apply_default_hash_alg(more_pcr_values, n_more_pcr_values); - tpm2_sort_pcr_values(pcr_values, n_pcr_values); + tpm2_sort_pcr_values(more_pcr_values, n_more_pcr_values); - if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values)) + if (!tpm2_pcr_values_valid(more_pcr_values, n_more_pcr_values)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid."); - SWAP_TWO(*ret_pcr_values, pcr_values); - *ret_n_pcr_values = n_pcr_values; + SWAP_TWO(*pcr_values, more_pcr_values); + *n_pcr_values = n_more_pcr_values; return 0; #else From 65fd657e0a13c0fdd4221cf6f22d51462a0bbc10 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 18:10:56 -0400 Subject: [PATCH 13/21] tpm2: use memcpy_safe() instead of memcpy() --- src/shared/tpm2-util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 6883975174..e62a3c30e1 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -199,7 +199,7 @@ int tpm2_tpm2b_public_to_fingerprint(const TPM2B_PUBLIC *public, void **ret_fing struct_type UNIQ_T(STRUCT, uniq) = { .size_field = UNIQ_T(SIZE, uniq), }; \ assert(sizeof(UNIQ_T(STRUCT, uniq).buffer_field) >= (size_t) UNIQ_T(SIZE, uniq)); \ if (UNIQ_T(BUF, uniq)) \ - memcpy(UNIQ_T(STRUCT, uniq).buffer_field, UNIQ_T(BUF, uniq), UNIQ_T(SIZE, uniq)); \ + memcpy_safe(UNIQ_T(STRUCT, uniq).buffer_field, UNIQ_T(BUF, uniq), UNIQ_T(SIZE, uniq)); \ UNIQ_T(STRUCT, uniq); \ }) From b0307102951f57becf733f740710bc826e1609ba Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 18:14:07 -0400 Subject: [PATCH 14/21] openssl: use new(char, size) instead of malloc(size) --- src/shared/openssl-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/openssl-util.c b/src/shared/openssl-util.c index db45b23aaf..3d3d8090f8 100644 --- a/src/shared/openssl-util.c +++ b/src/shared/openssl-util.c @@ -403,7 +403,7 @@ int ecc_pkey_to_curve_x_y( if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, &name_size)) return log_openssl_errors("Failed to get ECC group name size"); - _cleanup_free_ char *name = malloc(name_size + 1); + _cleanup_free_ char *name = new(char, name_size + 1); if (!name) return log_oom_debug(); From 6761e1355edae6aa133f49325c8a03100694ba81 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 18:40:13 -0400 Subject: [PATCH 15/21] tpm2: use table for openssl<->tpm2 ecc curve id mappings --- src/shared/tpm2-util.c | 46 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index d53f4cd5a2..4705b6f69f 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3507,36 +3507,42 @@ static int tpm2_build_sealing_policy( } #if HAVE_OPENSSL -static int tpm2_ecc_curve_from_openssl_curve_id(int curve_id, TPM2_ECC_CURVE *ret) { +static const struct { + TPM2_ECC_CURVE tpm2_ecc_curve_id; + int openssl_ecc_curve_id; +} tpm2_openssl_ecc_curve_table[] = { + { TPM2_ECC_NIST_P192, NID_X9_62_prime192v1, }, + { TPM2_ECC_NIST_P224, NID_secp224r1, }, + { TPM2_ECC_NIST_P256, NID_X9_62_prime256v1, }, + { TPM2_ECC_NIST_P384, NID_secp384r1, }, + { TPM2_ECC_NIST_P521, NID_secp521r1, }, + { TPM2_ECC_SM2_P256, NID_sm2, }, +}; + +static int tpm2_ecc_curve_from_openssl_curve_id(int openssl_ecc_curve_id, TPM2_ECC_CURVE *ret) { assert(ret); - switch (curve_id) { - case NID_X9_62_prime192v1: *ret = TPM2_ECC_NIST_P192; return 0; - case NID_secp224r1: *ret = TPM2_ECC_NIST_P192; return 0; - case NID_X9_62_prime256v1: *ret = TPM2_ECC_NIST_P256; return 0; - case NID_secp384r1: *ret = TPM2_ECC_NIST_P384; return 0; - case NID_secp521r1: *ret = TPM2_ECC_NIST_P521; return 0; - case NID_sm2: *ret = TPM2_ECC_SM2_P256; return 0; - } + FOREACH_ARRAY(t, tpm2_openssl_ecc_curve_table, ELEMENTSOF(tpm2_openssl_ecc_curve_table)) + if (t->openssl_ecc_curve_id == openssl_ecc_curve_id) { + *ret = t->tpm2_ecc_curve_id; + return 0; + } return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Openssl ECC curve id %d not supported.", curve_id); + "Openssl ECC curve id %d not supported.", openssl_ecc_curve_id); } -static int tpm2_ecc_curve_to_openssl_curve_id(TPM2_ECC_CURVE curve, int *ret) { +static int tpm2_ecc_curve_to_openssl_curve_id(TPM2_ECC_CURVE tpm2_ecc_curve_id, int *ret) { assert(ret); - switch (curve) { - case TPM2_ECC_NIST_P192: *ret = NID_X9_62_prime192v1; return 0; - case TPM2_ECC_NIST_P224: *ret = NID_secp224r1; return 0; - case TPM2_ECC_NIST_P256: *ret = NID_X9_62_prime256v1; return 0; - case TPM2_ECC_NIST_P384: *ret = NID_secp384r1; return 0; - case TPM2_ECC_NIST_P521: *ret = NID_secp521r1; return 0; - case TPM2_ECC_SM2_P256: *ret = NID_sm2; return 0; - } + FOREACH_ARRAY(t, tpm2_openssl_ecc_curve_table, ELEMENTSOF(tpm2_openssl_ecc_curve_table)) + if (t->tpm2_ecc_curve_id == tpm2_ecc_curve_id) { + *ret = t->openssl_ecc_curve_id; + return 0; + } return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "TPM2 ECC curve %u not supported.", curve); + "TPM2 ECC curve %u not supported.", tpm2_ecc_curve_id); } #define TPM2_RSA_DEFAULT_EXPONENT UINT32_C(0x10001) From 3f4d5dfd651864adf94e43ffdc6303a41f96fcd4 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:02:18 -0400 Subject: [PATCH 16/21] tpm2: use switch() instead of if-else --- src/shared/tpm2-util.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 4705b6f69f..ee6a4b42da 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3554,7 +3554,8 @@ int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret assert(ret); const TPMT_PUBLIC *p = &public->publicArea; - if (p->type == TPM2_ALG_ECC) { + switch (p->type) { + case TPM2_ALG_ECC: { int curve_id; r = tpm2_ecc_curve_to_openssl_curve_id(p->parameters.eccDetail.curveID, &curve_id); if (r < 0) @@ -3569,8 +3570,7 @@ int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret point->y.size, ret); } - - if (p->type == TPM2_ALG_RSA) { + case TPM2_ALG_RSA: { /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of * zero indicates that the exponent is the default of 2^16 + 1". */ uint32_t exponent = htobe32(p->parameters.rsaDetail.exponent ?: TPM2_RSA_DEFAULT_EXPONENT); @@ -3581,9 +3581,10 @@ int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret sizeof(exponent), ret); } - - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "TPM2 asymmetric algorithm 0x%" PRIx16 " not supported.", p->type); + default: + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "TPM2 asymmetric algorithm 0x%" PRIx16 " not supported.", p->type); + } } int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) { @@ -3607,7 +3608,8 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) key_id = EVP_PKEY_id(pkey); #endif - if (key_id == EVP_PKEY_EC) { + switch (key_id) { + case EVP_PKEY_EC: { public.type = TPM2_ALG_ECC; int curve_id; @@ -3637,7 +3639,10 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) return log_error_errno(r, "ECC key y size %zu too large.", y_size); public.unique.ecc.y = TPM2B_ECC_PARAMETER_MAKE(y, y_size); - } else if (key_id == EVP_PKEY_RSA) { + + break; + } + case EVP_PKEY_RSA: { public.type = TPM2_ALG_RSA; _cleanup_free_ void *n = NULL, *e = NULL; @@ -3663,9 +3668,13 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) if (exponent == TPM2_RSA_DEFAULT_EXPONENT) exponent = 0; public.parameters.rsaDetail.exponent = exponent; - } else + + break; + } + default: return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "EVP_PKEY type %d not supported.", key_id); + } *ret = (TPM2B_PUBLIC) { .size = sizeof(public), From ed35ac31557722530e174e474b0be1b21bac53a4 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:06:38 -0400 Subject: [PATCH 17/21] tpm2: make logging level consistent at debug for some functions --- src/shared/tpm2-util.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index ee6a4b42da..efe93095a7 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3617,7 +3617,7 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) size_t x_size, y_size; r = ecc_pkey_to_curve_x_y(pkey, &curve_id, &x, &x_size, &y, &y_size); if (r < 0) - return log_error_errno(r, "Could not get ECC key curve/x/y: %m"); + return log_debug_errno(r, "Could not get ECC key curve/x/y: %m"); TPM2_ECC_CURVE curve; r = tpm2_ecc_curve_from_openssl_curve_id(curve_id, &curve); @@ -3630,13 +3630,13 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) r = TPM2B_ECC_PARAMETER_CHECK_SIZE(x_size); if (r < 0) - return log_error_errno(r, "ECC key x size %zu too large.", x_size); + return log_debug_errno(r, "ECC key x size %zu too large.", x_size); public.unique.ecc.x = TPM2B_ECC_PARAMETER_MAKE(x, x_size); r = TPM2B_ECC_PARAMETER_CHECK_SIZE(y_size); if (r < 0) - return log_error_errno(r, "ECC key y size %zu too large.", y_size); + return log_debug_errno(r, "ECC key y size %zu too large.", y_size); public.unique.ecc.y = TPM2B_ECC_PARAMETER_MAKE(y, y_size); @@ -3649,17 +3649,17 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) size_t n_size, e_size; r = rsa_pkey_to_n_e(pkey, &n, &n_size, &e, &e_size); if (r < 0) - return log_error_errno(r, "Could not get RSA key n/e: %m"); + return log_debug_errno(r, "Could not get RSA key n/e: %m"); r = TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(n_size); if (r < 0) - return log_error_errno(r, "RSA key n size %zu too large.", n_size); + return log_debug_errno(r, "RSA key n size %zu too large.", n_size); public.unique.rsa = TPM2B_PUBLIC_KEY_RSA_MAKE(n, n_size); public.parameters.rsaDetail.keyBits = n_size * 8; if (sizeof(uint32_t) < e_size) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "RSA key e size %zu too large.", e_size); uint32_t exponent = 0; From 70cb382d368518d69e99b5e384e2456eb2d9916e Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:07:38 -0400 Subject: [PATCH 18/21] tpm2: remove unnecessary void* cast --- src/shared/tpm2-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index efe93095a7..0da85b3ff2 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3663,7 +3663,7 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) "RSA key e size %zu too large.", e_size); uint32_t exponent = 0; - memcpy((void*) &exponent, e, e_size); + memcpy(&exponent, e, e_size); exponent = be32toh(exponent) >> (32 - e_size * 8); if (exponent == TPM2_RSA_DEFAULT_EXPONENT) exponent = 0; From 26d8d71fa5fc9d620899e3940ad246485991e632 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:18:40 -0400 Subject: [PATCH 19/21] tpm2: add tpm2_pcr_values_has_(any|all)_values() functions --- src/cryptenroll/cryptenroll-tpm2.c | 7 +------ src/shared/tpm2-util.c | 22 ++++++++++++++++++++++ src/shared/tpm2-util.h | 2 ++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index d7f81ede3f..38920fb94e 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -211,12 +211,7 @@ int enroll_tpm2(struct crypt_device *cd, if (r < 0) return r; - bool pcr_value_specified = false; - for (size_t i = 0; i < n_hash_pcr_values; i++) - if (hash_pcr_values[i].value.size > 0) { - pcr_value_specified = true; - break; - } + bool pcr_value_specified = tpm2_pcr_values_has_any_values(hash_pcr_values, n_hash_pcr_values); r = tpm2_pcr_read_missing_values(tpm2_context, hash_pcr_values, n_hash_pcr_values); if (r < 0) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 0da85b3ff2..83070ab824 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1590,6 +1590,28 @@ bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) return true; } +/* Returns true if any of the provided PCR values has an actual hash value included, false otherwise. */ +bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { + assert(pcr_values || n_pcr_values == 0); + + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (v->value.size > 0) + return true; + + return false; +} + +/* Returns true if all of the provided PCR values has an actual hash value included, false otherwise. */ +bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) { + assert(pcr_values || n_pcr_values == 0); + + FOREACH_ARRAY(v, pcr_values, n_pcr_values) + if (v->value.size == 0) + return false; + + return true; +} + static int cmp_pcr_values(const Tpm2PCRValue *a, const Tpm2PCRValue *b) { assert(a); assert(b); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index e62a3c30e1..0fd376a2e6 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -83,6 +83,8 @@ typedef struct { } bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value); +bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values); +bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values); int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value); char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value); From 81e3d37211362a4a0549f57abb56ba030337a135 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:21:21 -0400 Subject: [PATCH 20/21] tpm2: wrap (7) in UINT32_C() --- src/shared/tpm2-util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 0fd376a2e6..1db28bf034 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -249,7 +249,7 @@ int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, int tpm2_parse_luks2_json(JsonVariant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, void **ret_pubkey, size_t *ret_pubkey_size, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, void **ret_blob, size_t *ret_blob_size, void **ret_policy_hash, size_t *ret_policy_hash_size, void **ret_salt, size_t *ret_salt_size, void **ret_srk_buf, size_t *ret_srk_buf_size, TPM2Flags *ret_flags); /* Default to PCR 7 only */ -#define TPM2_PCR_INDEX_DEFAULT (7) +#define TPM2_PCR_INDEX_DEFAULT UINT32_C(7) #define TPM2_PCR_MASK_DEFAULT INDEX_TO_MASK(uint32_t, TPM2_PCR_INDEX_DEFAULT) /* We want the helpers below to work also if TPM2 libs are not available, hence define these four defines if From a11a2e059cd8e7d488985c23ceee0d6a2d5c8fb0 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Mon, 21 Aug 2023 19:25:49 -0400 Subject: [PATCH 21/21] cryptenroll: change man page example to remove leading 0x and lowercase hex --- man/systemd-cryptenroll.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml index cea2072c47..a959217ebb 100644 --- a/man/systemd-cryptenroll.xml +++ b/man/systemd-cryptenroll.xml @@ -403,9 +403,9 @@ specifies that PCR registers 4, 1, and 5 should be used. Example: specifies that PCR register 7 from the SHA256 bank should be used. - Example: + Example: specifies that PCR register 4 from the SHA1 bank should be used, and a hash digest value of - 0x3A3F780F11A4B49969FCAA80CD6E3957C33B2275 will be used instead of reading the current PCR + 3a3f780f11a4b49969fcaa80cd6e3957c33b2275 will be used instead of reading the current PCR value.