#include <linux/unaligned/generic.h>
#include <hexdump.h>
+/**
+ * struct event_log_buffer - internal eventlog management structure
+ *
+ * @buffer: eventlog buffer
+ * @final_buffer: finalevent config table buffer
+ * @pos: current position of 'buffer'
+ * @final_pos: current position of 'final_buffer'
+ * @get_event_called: true if GetEventLog has been invoked at least once
+ * @ebs_called: true if ExitBootServices has been invoked
+ * @truncated: true if the 'buffer' is truncated
+ */
struct event_log_buffer {
void *buffer;
void *final_buffer;
size_t final_pos; /* final events config table position */
size_t last_event_size;
bool get_event_called;
+ bool ebs_called;
bool truncated;
};
return EFI_SUCCESS;
}
-/* tcg2_agile_log_append - Append an agile event to out eventlog
+/* put_event - Append an agile event to an eventlog
*
* @pcr_index: PCR index
* @event_type: type of event added
* @digest_list: list of digest algorithms to add
* @size: size of event
* @event: event to add
+ * @log: log buffer to append the event
*
- * @Return: status code
*/
-static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
- struct tpml_digest_values *digest_list,
- u32 size, u8 event[])
+static void put_event(u32 pcr_index, u32 event_type,
+ struct tpml_digest_values *digest_list, u32 size,
+ u8 event[], void *log)
{
- void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
size_t pos;
size_t i;
u32 event_size;
- if (event_log.get_event_called)
- log = (void *)((uintptr_t)event_log.final_buffer +
- event_log.final_pos);
-
/*
* size refers to the length of event[] only, we need to check against
* the final tcg_pcr_event2 size
*/
event_size = size + tcg_event_final_size(digest_list);
- if (event_log.pos + event_size > TPM2_EVENT_LOG_SIZE ||
- event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) {
- event_log.truncated = true;
- return EFI_VOLUME_FULL;
- }
put_unaligned_le32(pcr_index, log);
pos = offsetof(struct tcg_pcr_event2, event_type);
memcpy((void *)((uintptr_t)log + pos), event, size);
pos += size;
- /* make sure the calculated buffer is what we checked against */
+ /*
+ * make sure the calculated buffer is what we checked against
+ * This check should never fail. It checks the code above is
+ * calculating the right length for the event we are adding
+ */
if (pos != event_size)
- return EFI_INVALID_PARAMETER;
+ log_err("Appending to the EventLog failed\n");
+}
- /* if GetEventLog hasn't been called update the normal log */
- if (!event_log.get_event_called) {
- event_log.pos += pos;
- event_log.last_event_size = pos;
- } else {
- /* if GetEventLog has been called update config table log */
- struct efi_tcg2_final_events_table *final_event;
+/* tcg2_agile_log_append - Append an agile event to an eventlog
+ *
+ * @pcr_index: PCR index
+ * @event_type: type of event added
+ * @digest_list: list of digest algorithms to add
+ * @size: size of event
+ * @event: event to add
+ * @log: log buffer to append the event
+ *
+ * @Return: status code
+ */
+static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
+ struct tpml_digest_values *digest_list,
+ u32 size, u8 event[])
+{
+ void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
+ u32 event_size = size + tcg_event_final_size(digest_list);
+ struct efi_tcg2_final_events_table *final_event;
+ efi_status_t ret = EFI_SUCCESS;
- final_event =
- (struct efi_tcg2_final_events_table *)(event_log.final_buffer);
- final_event->number_of_events++;
- event_log.final_pos += pos;
+ /* if ExitBootServices hasn't been called update the normal log */
+ if (!event_log.ebs_called) {
+ if (event_log.truncated ||
+ event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) {
+ event_log.truncated = true;
+ return EFI_VOLUME_FULL;
+ }
+ put_event(pcr_index, event_type, digest_list, size, event, log);
+ event_log.pos += event_size;
+ event_log.last_event_size = event_size;
}
- return EFI_SUCCESS;
+ if (!event_log.get_event_called)
+ return ret;
+
+ /* if GetEventLog has been called update FinalEventLog as well */
+ if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE)
+ return EFI_VOLUME_FULL;
+
+ log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos);
+ put_event(pcr_index, event_type, digest_list, size, event, log);
+
+ final_event = event_log.final_buffer;
+ final_event->number_of_events++;
+ event_log.final_pos += event_size;
+
+ return ret;
}
/**
event_log.pos = 0;
event_log.last_event_size = 0;
event_log.get_event_called = false;
+ event_log.ebs_called = false;
event_log.truncated = false;
/*
EFI_ENTRY("%p, %p", event, context);
+ event_log.ebs_called = true;
ret = platform_get_tpm2_device(&dev);
if (ret != EFI_SUCCESS)
goto out;