mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
tpm2: in tpm2_pcr_values_valid() use FOREACH_ARRAY()
This commit is contained in:
parent
064ac95d81
commit
193fd5730e
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user