From 2748f56bf147d5212cada67cba838877f3ce3f5c Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 19 Jul 2023 08:50:06 -0400 Subject: [PATCH] tpm2: add more helper functions for managing TPML_PCR_SELECTION and TPMS_PCR_SELECTION Add more functions to help manage these objects. (cherry picked from commit 13b551744b9df9ea08d7e06dee57a8cea7b48d1b) Related: RHEL-16182 --- src/shared/tpm2-util.c | 62 +++++++++++++++++++++++++++++++++++------- src/shared/tpm2-util.h | 6 ++++ 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index b0a2f715ef..9c0cad47c6 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1228,30 +1228,45 @@ void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TP }; } +/* Test if all bits in the mask are set in the TPMS_PCR_SELECTION. */ +bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION *s, uint32_t mask) { + assert(s); + + return FLAGS_SET(tpm2_tpms_pcr_selection_to_mask(s), mask); +} + +static void tpm2_tpms_pcr_selection_update_mask(TPMS_PCR_SELECTION *s, uint32_t mask, bool b) { + assert(s); + + tpm2_tpms_pcr_selection_from_mask(UPDATE_FLAG(tpm2_tpms_pcr_selection_to_mask(s), mask, b), s->hash, s); +} + +/* Add all PCR selections in the mask. */ +void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION *s, uint32_t mask) { + tpm2_tpms_pcr_selection_update_mask(s, mask, 1); +} + +/* Remove all PCR selections in the mask. */ +void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION *s, uint32_t mask) { + tpm2_tpms_pcr_selection_update_mask(s, mask, 0); +} + /* 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); - 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); + tpm2_tpms_pcr_selection_add_mask(a, tpm2_tpms_pcr_selection_to_mask(b)); } /* 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); - 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); + tpm2_tpms_pcr_selection_sub_mask(a, tpm2_tpms_pcr_selection_to_mask(b)); } /* Move all PCR selections in 'b' to 'a'. Both must have the same hash alg. */ @@ -1426,6 +1441,33 @@ void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION *l, const tpm2_tpms_pcr_selection_sub(selection, s); } +/* Test if all bits in the mask for the hash are set in the TPML_PCR_SELECTION. */ +bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) { + assert(l); + + return FLAGS_SET(tpm2_tpml_pcr_selection_to_mask(l, hash), mask); +} + +/* Add the PCR selections in the mask, with the provided hash. */ +void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) { + TPMS_PCR_SELECTION tpms; + + assert(l); + + tpm2_tpms_pcr_selection_from_mask(mask, hash, &tpms); + tpm2_tpml_pcr_selection_add_tpms_pcr_selection(l, &tpms); +} + +/* Remove the PCR selections in the mask, with the provided hash. */ +void tpm2_tpml_pcr_selection_sub_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) { + TPMS_PCR_SELECTION tpms; + + assert(l); + + tpm2_tpms_pcr_selection_from_mask(mask, hash, &tpms); + tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(l, &tpms); +} + /* Add all PCR selections in 'b' to 'a'. */ void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b) { assert(a); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 2f1eb8a012..c024245915 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -104,6 +104,9 @@ int tpm2_extend_bytes(Tpm2Context *c, char **banks, unsigned pcr_index, const vo 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); +bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION *s, uint32_t mask); +void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION *s, uint32_t mask); +void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION *s, uint32_t mask); 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); void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b); @@ -113,6 +116,9 @@ size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s); 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); +bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask); +void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask); +void tpm2_tpml_pcr_selection_sub_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask); 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); void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b);