Commit 44038bc5 authored by Matthew Garrett's avatar Matthew Garrett Committed by Jarkko Sakkinen

tpm: Abstract crypto agile event size calculations

We need to calculate the size of crypto agile events in multiple
locations, including in the EFI boot stub. The easiest way to do this is
to put it in a header file as an inline and leave a wrapper to ensure we
don't end up with multiple copies of it embedded in the existing code.
Signed-off-by: default avatarMatthew Garrett <mjg59@google.com>
Reviewed-by: default avatarBartosz Szczepanek <bsz@semihalf.com>
Tested-by: default avatarBartosz Szczepanek <bsz@semihalf.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
parent 782779b6
...@@ -36,52 +36,7 @@ ...@@ -36,52 +36,7 @@
static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event, static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
struct tcg_pcr_event *event_header) struct tcg_pcr_event *event_header)
{ {
struct tcg_efi_specid_event_head *efispecid; return __calc_tpm2_event_size(event, event_header);
struct tcg_event_field *event_field;
void *marker;
void *marker_start;
u32 halg_size;
size_t size;
u16 halg;
int i;
int j;
marker = event;
marker_start = marker;
marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type)
+ sizeof(event->count);
efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
/* Check if event is malformed. */
if (event->count > efispecid->num_algs)
return 0;
for (i = 0; i < event->count; i++) {
halg_size = sizeof(event->digests[i].alg_id);
memcpy(&halg, marker, halg_size);
marker = marker + halg_size;
for (j = 0; j < efispecid->num_algs; j++) {
if (halg == efispecid->digest_sizes[j].alg_id) {
marker +=
efispecid->digest_sizes[j].digest_size;
break;
}
}
/* Algorithm without known length. Such event is unparseable. */
if (j == efispecid->num_algs)
return 0;
}
event_field = (struct tcg_event_field *)marker;
marker = marker + sizeof(event_field->event_size)
+ event_field->event_size;
size = marker - marker_start;
if ((event->event_type == 0) && (event_field->event_size == 0))
return 0;
return size;
} }
static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos) static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)
......
...@@ -112,4 +112,72 @@ struct tcg_pcr_event2_head { ...@@ -112,4 +112,72 @@ struct tcg_pcr_event2_head {
struct tpm_digest digests[]; struct tpm_digest digests[];
} __packed; } __packed;
/**
* __calc_tpm2_event_size - calculate the size of a TPM2 event log entry
* @event: Pointer to the event whose size should be calculated
* @event_header: Pointer to the initial event containing the digest lengths
*
* The TPM2 event log format can contain multiple digests corresponding to
* separate PCR banks, and also contains a variable length of the data that
* was measured. This requires knowledge of how long each digest type is,
* and this information is contained within the first event in the log.
*
* We calculate the length by examining the number of events, and then looking
* at each event in turn to determine how much space is used for events in
* total. Once we've done this we know the offset of the data length field,
* and can calculate the total size of the event.
*
* Return: size of the event on success, <0 on failure
*/
static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
struct tcg_pcr_event *event_header)
{
struct tcg_efi_specid_event_head *efispecid;
struct tcg_event_field *event_field;
void *marker;
void *marker_start;
u32 halg_size;
size_t size;
u16 halg;
int i;
int j;
marker = event;
marker_start = marker;
marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type)
+ sizeof(event->count);
efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
/* Check if event is malformed. */
if (event->count > efispecid->num_algs)
return 0;
for (i = 0; i < event->count; i++) {
halg_size = sizeof(event->digests[i].alg_id);
memcpy(&halg, marker, halg_size);
marker = marker + halg_size;
for (j = 0; j < efispecid->num_algs; j++) {
if (halg == efispecid->digest_sizes[j].alg_id) {
marker +=
efispecid->digest_sizes[j].digest_size;
break;
}
}
/* Algorithm without known length. Such event is unparseable. */
if (j == efispecid->num_algs)
return 0;
}
event_field = (struct tcg_event_field *)marker;
marker = marker + sizeof(event_field->event_size)
+ event_field->event_size;
size = marker - marker_start;
if ((event->event_type == 0) && (event_field->event_size == 0))
return 0;
return size;
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment