You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
9.1 KiB
200 lines
9.1 KiB
8 months ago
|
From be19ca580bf23d3b6e31c7a030cd3e19c2498f16 Mon Sep 17 00:00:00 2001
|
||
|
From: Dan Streetman <ddstreet@ieee.org>
|
||
|
Date: Tue, 1 Aug 2023 12:55:17 -0400
|
||
|
Subject: [PATCH] tpm2: change tpm2_tpm*_pcr_selection_to_mask() to return mask
|
||
|
|
||
|
This simplifies use of the functions, as well as avoiding the use of -ENOENT
|
||
|
from tpm2_tpml_pcr_selection_to_mask().
|
||
|
|
||
|
(cherry picked from commit dbaae766c7eaacdfb19ee23600f0f382a16ae33b)
|
||
|
|
||
|
Related: RHEL-16182
|
||
|
---
|
||
|
src/shared/tpm2-util.c | 52 ++++++++++++++++--------------------------
|
||
|
src/shared/tpm2-util.h | 4 ++--
|
||
|
src/test/test-tpm2.c | 8 ++-----
|
||
|
3 files changed, 24 insertions(+), 40 deletions(-)
|
||
|
|
||
|
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
||
|
index 509dab60f8..b0a2f715ef 100644
|
||
|
--- a/src/shared/tpm2-util.c
|
||
|
+++ b/src/shared/tpm2-util.c
|
||
|
@@ -1200,15 +1200,14 @@ static int tpm2_get_or_create_srk(
|
||
|
/* Utility functions for TPMS_PCR_SELECTION. */
|
||
|
|
||
|
/* Convert a TPMS_PCR_SELECTION object to a mask. */
|
||
|
-void tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s, uint32_t *ret) {
|
||
|
+uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s) {
|
||
|
assert(s);
|
||
|
assert(s->sizeofSelect <= sizeof(s->pcrSelect));
|
||
|
- assert(ret);
|
||
|
|
||
|
uint32_t mask = 0;
|
||
|
for (unsigned i = 0; i < s->sizeofSelect; i++)
|
||
|
SET_FLAG(mask, (uint32_t)s->pcrSelect[i] << (i * 8), true);
|
||
|
- *ret = mask;
|
||
|
+ return mask;
|
||
|
}
|
||
|
|
||
|
/* Convert a mask and hash alg to a TPMS_PCR_SELECTION object. */
|
||
|
@@ -1231,25 +1230,27 @@ void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TP
|
||
|
|
||
|
/* Add all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
|
||
|
void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
|
||
|
+ uint32_t maska, maskb;
|
||
|
+
|
||
|
assert(a);
|
||
|
assert(b);
|
||
|
assert(a->hash == b->hash);
|
||
|
|
||
|
- uint32_t maska, maskb;
|
||
|
- tpm2_tpms_pcr_selection_to_mask(a, &maska);
|
||
|
- tpm2_tpms_pcr_selection_to_mask(b, &maskb);
|
||
|
+ maska = tpm2_tpms_pcr_selection_to_mask(a);
|
||
|
+ maskb = tpm2_tpms_pcr_selection_to_mask(b);
|
||
|
tpm2_tpms_pcr_selection_from_mask(maska | maskb, a->hash, a);
|
||
|
}
|
||
|
|
||
|
/* Remove all PCR selections in 'b' from 'a'. Both must have the same hash alg. */
|
||
|
void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
|
||
|
+ uint32_t maska, maskb;
|
||
|
+
|
||
|
assert(a);
|
||
|
assert(b);
|
||
|
assert(a->hash == b->hash);
|
||
|
|
||
|
- uint32_t maska, maskb;
|
||
|
- tpm2_tpms_pcr_selection_to_mask(a, &maska);
|
||
|
- tpm2_tpms_pcr_selection_to_mask(b, &maskb);
|
||
|
+ maska = tpm2_tpms_pcr_selection_to_mask(a);
|
||
|
+ maskb = tpm2_tpms_pcr_selection_to_mask(b);
|
||
|
tpm2_tpms_pcr_selection_from_mask(maska & ~maskb, a->hash, a);
|
||
|
}
|
||
|
|
||
|
@@ -1265,11 +1266,7 @@ void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *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, \
|
||
|
- ({ uint32_t UNIQ_T(_mask, uniq); \
|
||
|
- tpm2_tpms_pcr_selection_to_mask(tpms, &UNIQ_T(_mask, uniq)); \
|
||
|
- UNIQ_T(_mask, 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)
|
||
|
@@ -1291,21 +1288,17 @@ char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION *s) {
|
||
|
|
||
|
const char *algstr = strna(tpm2_hash_alg_to_string(s->hash));
|
||
|
|
||
|
- uint32_t mask;
|
||
|
- tpm2_tpms_pcr_selection_to_mask(s, &mask);
|
||
|
- _cleanup_free_ char *maskstr = tpm2_pcr_mask_to_string(mask);
|
||
|
- if (!maskstr)
|
||
|
+ _cleanup_free_ char *mask = tpm2_pcr_mask_to_string(tpm2_tpms_pcr_selection_to_mask(s));
|
||
|
+ if (!mask)
|
||
|
return NULL;
|
||
|
|
||
|
- return strjoin(algstr, "(", maskstr, ")");
|
||
|
+ return strjoin(algstr, "(", mask, ")");
|
||
|
}
|
||
|
|
||
|
size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s) {
|
||
|
assert(s);
|
||
|
|
||
|
- uint32_t mask;
|
||
|
- tpm2_tpms_pcr_selection_to_mask(s, &mask);
|
||
|
- return (size_t)__builtin_popcount(mask);
|
||
|
+ return (size_t)__builtin_popcount(tpm2_tpms_pcr_selection_to_mask(s));
|
||
|
}
|
||
|
|
||
|
/* Utility functions for TPML_PCR_SELECTION. */
|
||
|
@@ -1356,10 +1349,9 @@ static TPMS_PCR_SELECTION *tpm2_tpml_pcr_selection_get_tpms_pcr_selection(
|
||
|
return selection;
|
||
|
}
|
||
|
|
||
|
-/* Convert a TPML_PCR_SELECTION object to a mask. Returns -ENOENT if 'hash_alg' is not in the object. */
|
||
|
-int tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash_alg, uint32_t *ret) {
|
||
|
+/* 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);
|
||
|
- assert(ret);
|
||
|
|
||
|
/* Make a copy, as tpm2_tpml_pcr_selection_get_tpms_pcr_selection() will modify the object if there
|
||
|
* are multiple entries with the requested hash alg. */
|
||
|
@@ -1368,10 +1360,9 @@ int tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH h
|
||
|
TPMS_PCR_SELECTION *s;
|
||
|
s = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(&lcopy, hash_alg);
|
||
|
if (!s)
|
||
|
- return SYNTHETIC_ERRNO(ENOENT);
|
||
|
+ return 0;
|
||
|
|
||
|
- tpm2_tpms_pcr_selection_to_mask(s, ret);
|
||
|
- return 0;
|
||
|
+ return tpm2_tpms_pcr_selection_to_mask(s);
|
||
|
}
|
||
|
|
||
|
/* Convert a mask and hash alg to a TPML_PCR_SELECTION object. */
|
||
|
@@ -2574,10 +2565,7 @@ static int find_signature(
|
||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
|
||
|
|
||
|
uint16_t pcr_bank = pcr_selection->pcrSelections[0].hash;
|
||
|
- uint32_t pcr_mask;
|
||
|
- r = tpm2_tpml_pcr_selection_to_mask(pcr_selection, pcr_bank, &pcr_mask);
|
||
|
- if (r < 0)
|
||
|
- return r;
|
||
|
+ uint32_t pcr_mask = tpm2_tpml_pcr_selection_to_mask(pcr_selection, pcr_bank);
|
||
|
|
||
|
k = tpm2_hash_alg_to_string(pcr_bank);
|
||
|
if (!k)
|
||
|
diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h
|
||
|
index affcbea3a1..2f1eb8a012 100644
|
||
|
--- a/src/shared/tpm2-util.h
|
||
|
+++ b/src/shared/tpm2-util.h
|
||
|
@@ -102,7 +102,7 @@ int tpm2_get_good_pcr_banks_strv(Tpm2Context *c, uint32_t pcr_mask, char ***ret)
|
||
|
|
||
|
int tpm2_extend_bytes(Tpm2Context *c, char **banks, unsigned pcr_index, const void *data, size_t data_size, const void *secret, size_t secret_size);
|
||
|
|
||
|
-void tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s, uint32_t *ret);
|
||
|
+uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s);
|
||
|
void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash, TPMS_PCR_SELECTION *ret);
|
||
|
void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b);
|
||
|
void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b);
|
||
|
@@ -111,7 +111,7 @@ char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION *s);
|
||
|
size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s);
|
||
|
#define tpm2_tpms_pcr_selection_is_empty(s) (tpm2_tpms_pcr_selection_weight(s) == 0)
|
||
|
|
||
|
-int tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t *ret);
|
||
|
+uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash);
|
||
|
void tpm2_tpml_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash, TPML_PCR_SELECTION *ret);
|
||
|
void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s);
|
||
|
void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s);
|
||
|
diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c
|
||
|
index 87c8f6f421..c61bbf6d94 100644
|
||
|
--- a/src/test/test-tpm2.c
|
||
|
+++ b/src/test/test-tpm2.c
|
||
|
@@ -157,9 +157,7 @@ static void verify_tpms_pcr_selection(TPMS_PCR_SELECTION *s, uint32_t mask, TPMI
|
||
|
assert_se(s->pcrSelect[2] == ((mask >> 16) & 0xff));
|
||
|
assert_se(s->pcrSelect[3] == 0);
|
||
|
|
||
|
- uint32_t m = POISON_U32;
|
||
|
- tpm2_tpms_pcr_selection_to_mask(s, &m);
|
||
|
- assert_se(m == mask);
|
||
|
+ assert_se(tpm2_tpms_pcr_selection_to_mask(s) == mask);
|
||
|
}
|
||
|
|
||
|
static void verify_tpml_pcr_selection(TPML_PCR_SELECTION *l, TPMS_PCR_SELECTION s[], size_t count) {
|
||
|
@@ -167,10 +165,8 @@ static void verify_tpml_pcr_selection(TPML_PCR_SELECTION *l, TPMS_PCR_SELECTION
|
||
|
for (size_t i = 0; i < count; i++) {
|
||
|
assert_tpms_pcr_selection_eq(&s[i], &l->pcrSelections[i]);
|
||
|
|
||
|
- uint32_t mask = POISON_U32;
|
||
|
TPMI_ALG_HASH hash = l->pcrSelections[i].hash;
|
||
|
- assert_se(tpm2_tpml_pcr_selection_to_mask(l, hash, &mask) == 0);
|
||
|
- verify_tpms_pcr_selection(&l->pcrSelections[i], mask, hash);
|
||
|
+ verify_tpms_pcr_selection(&l->pcrSelections[i], tpm2_tpml_pcr_selection_to_mask(l, hash), hash);
|
||
|
}
|
||
|
}
|
||
|
|