tpm2: add Tpm2PCRValue struct and associated functions

Add a new struct that can represent a PCR index, hash, and value all
together. This replaces code (e.g. the tpm2_pcr_read() parameters) that
required using both a TPML_PCR_SELECTION as well as array of TPM2B_DIGEST
entries, which was difficult to correlate the selection hash/index to each
digest.
This commit is contained in:
Dan Streetman
2023-07-11 21:23:36 -04:00
parent 13b551744b
commit 323eb4803a
4 changed files with 400 additions and 50 deletions

View File

@@ -278,7 +278,7 @@ _public_ int cryptsetup_token_validate(
}
u = json_variant_unsigned(e);
if (!TPM2_PCR_VALID(u)) {
if (!TPM2_PCR_INDEX_VALID(u)) {
crypt_log_debug(cd, "TPM2 PCR number out of range.");
return 1;
}

View File

@@ -435,7 +435,7 @@ static int parse_one_option(const char *option) {
}
pcr = r ? TPM_PCR_INDEX_VOLUME_KEY : UINT_MAX;
} else if (!TPM2_PCR_VALID(pcr)) {
} else if (!TPM2_PCR_INDEX_VALID(pcr)) {
log_warning("Selected TPM index for measurement %u outside of allowed range 0…%u, ignoring.", pcr, TPM2_PCRS_MAX-1);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,7 @@ typedef enum TPM2Flags {
* TPM2 on a Client PC must have at least 24 PCRs. This hardcodes our expectation of 24. */
#define TPM2_PCRS_MAX 24U
#define TPM2_PCRS_MASK ((UINT32_C(1) << TPM2_PCRS_MAX) - 1)
static inline bool TPM2_PCR_VALID(unsigned pcr) {
static inline bool TPM2_PCR_INDEX_VALID(unsigned pcr) {
return pcr < TPM2_PCRS_MAX;
}
static inline bool TPM2_PCR_MASK_VALID(uint32_t pcr_mask) {
@@ -88,6 +88,26 @@ int tpm2_handle_new(Tpm2Context *context, Tpm2Handle **ret_handle);
Tpm2Handle *tpm2_handle_free(Tpm2Handle *handle);
DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Handle*, tpm2_handle_free);
typedef struct {
unsigned index;
TPMI_ALG_HASH hash;
TPM2B_DIGEST value;
} 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);
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);
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);
int tpm2_pcr_values_from_string(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
char *tpm2_pcr_values_to_string(const Tpm2PCRValue *pcr_values, size_t n_pcr_values);
int tpm2_pcr_values_hash_count(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, size_t *ret_count);
int tpm2_tpml_pcr_selection_from_pcr_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, TPML_PCR_SELECTION *ret_selection, TPM2B_DIGEST **ret_values, size_t *ret_n_values);
int tpm2_create_primary(Tpm2Context *c, const Tpm2Handle *session, const TPM2B_PUBLIC *template, const TPM2B_SENSITIVE_CREATE *sensitive, TPM2B_PUBLIC **ret_public, Tpm2Handle **ret_handle);
int tpm2_create(Tpm2Context *c, const Tpm2Handle *parent, const Tpm2Handle *session, const TPMT_PUBLIC *template, const TPMS_SENSITIVE_CREATE *sensitive, TPM2B_PUBLIC **ret_public, TPM2B_PRIVATE **ret_private);
int tpm2_create_loaded(Tpm2Context *c, const Tpm2Handle *parent, const Tpm2Handle *session, const TPMT_PUBLIC *template, const TPMS_SENSITIVE_CREATE *sensitive, TPM2B_PUBLIC **ret_public, TPM2B_PRIVATE **ret_private, Tpm2Handle **ret_handle);
@@ -130,6 +150,9 @@ size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l);
#else /* HAVE_TPM2 */
typedef struct {} Tpm2Context;
typedef struct {} Tpm2Handle;
typedef struct {} Tpm2PCRValue;
#define TPM2_PCR_VALUE_MAKE(i, h, v) (Tpm2PCRValue) {}
#endif /* HAVE_TPM2 */
int tpm2_list_devices(void);