blob: 238ea274c2fb0735ddec01b73e33172e6b33009f [file] [log] [blame]
Harrison Mutaib6748092025-04-25 16:03:03 +00001/*
2 * Copyright (c) 2025, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8
9#include <common/debug.h>
10#include <drivers/measured_boot/event_log/event_handoff.h>
11
12#include <platform_def.h>
13
14static uint8_t *get_log_ptr(struct transfer_list_entry *te, size_t offset)
15{
16 uint8_t *base_ptr = transfer_list_entry_data(te);
17
18 if (base_ptr == NULL) {
19 return NULL;
20 }
21
22 return base_ptr + offset;
23}
24
25uint8_t *transfer_list_event_log_extend(struct transfer_list_header *tl,
26 size_t req_size, size_t *free)
27{
28 struct transfer_list_entry *existing_entry;
29 struct transfer_list_entry *new_entry;
30 uint8_t *old_data;
31 size_t existing_offset;
32 size_t old_size;
33
34 if (tl == NULL || free == NULL || req_size == 0) {
35 ERROR("Invalid arguments to event log extend.\n");
36 return NULL;
37 }
38
39 existing_entry = transfer_list_find(tl, TL_TAG_TPM_EVLOG);
40 existing_offset = EVENT_LOG_RESERVED_BYTES;
41
42 if (existing_entry != NULL) {
43 existing_offset = existing_entry->data_size;
44
45 if (transfer_list_set_data_size(tl, existing_entry,
46 req_size + existing_offset)) {
47 VERBOSE("TPM event log entry resized: new space %zu bytes at offset %zu\n",
48 req_size, existing_offset);
49
50 *free = existing_entry->data_size - existing_offset;
51
52 return get_log_ptr(existing_entry, existing_offset);
53 }
54 }
55
56 /* Add new entry (resize failed or no existing entry) */
57 new_entry = transfer_list_add(tl, TL_TAG_TPM_EVLOG,
58 req_size + existing_offset, NULL);
59
60 if (new_entry == NULL) {
61 ERROR("Failed to add TPM event log entry to transfer list.\n");
62 return NULL;
63 }
64
65 VERBOSE("New TPM event log entry added at %p\n",
66 transfer_list_entry_data(new_entry));
67
68 if (existing_entry != NULL) {
69 old_data = transfer_list_entry_data(existing_entry);
70 old_size = existing_offset;
71
72 VERBOSE("Copying existing event log (%zu bytes) to new entry at %p\n",
73 old_size, transfer_list_entry_data(new_entry));
74
75 memmove(transfer_list_entry_data(new_entry), old_data,
76 old_size);
77
78 transfer_list_rem(tl, existing_entry);
79 }
80
81 *free = new_entry->data_size - existing_offset;
82
83 return get_log_ptr(new_entry, existing_offset);
84}
85
86uint8_t *transfer_list_event_log_finish(struct transfer_list_header *tl,
87 uintptr_t cursor)
88{
89 uintptr_t entry_data_base;
90 size_t final_log_size;
91 struct transfer_list_entry *entry;
92
93 entry = transfer_list_find(tl, TL_TAG_TPM_EVLOG);
94 entry_data_base = (uintptr_t)transfer_list_entry_data(entry);
95
96 if (cursor < entry_data_base ||
97 cursor >= entry_data_base + entry->data_size) {
98 ERROR("Invalid cursor: outside event log bounds.\n");
99 return NULL;
100 }
101
102 final_log_size = cursor - entry_data_base;
103
104 if (!transfer_list_set_data_size(tl, entry, final_log_size)) {
105 ERROR("Unable to resize event log TE.\n");
106 return NULL;
107 }
108
109 transfer_list_update_checksum(tl);
110
111 VERBOSE("TPM event log finalized: trimmed to %zu bytes",
112 final_log_size - EVENT_LOG_RESERVED_BYTES);
113
114 /* Ensure changes are visible to the next stage. */
115 flush_dcache_range((uintptr_t)tl, tl->size);
116
117 return get_log_ptr(entry, EVENT_LOG_RESERVED_BYTES);
118}