1 /* 2 * Copyright (c) 2020, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <common/debug.h> 11 #include <drivers/measured_boot/event_log/event_log.h> 12 13 #if LOG_LEVEL >= EVENT_LOG_LEVEL 14 15 /* 16 * Print TCG_EfiSpecIDEventStruct 17 * 18 * @param[in/out] log_addr Pointer to Event Log 19 * @param[in/out] log_size Pointer to Event Log size 20 */ 21 static void id_event_print(uint8_t **log_addr, size_t *log_size) 22 { 23 unsigned int i; 24 uint8_t info_size, *info_size_ptr; 25 void *ptr = *log_addr; 26 id_event_headers_t *event = (id_event_headers_t *)ptr; 27 id_event_algorithm_size_t *alg_ptr; 28 uint32_t event_size, number_of_algorithms; 29 size_t digest_len; 30 #if ENABLE_ASSERTIONS 31 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); 32 bool valid = true; 33 #endif 34 35 assert(*log_size >= sizeof(id_event_headers_t)); 36 37 /* The fields of the event log header are defined to be PCRIndex of 0, 38 * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and 39 * Event content defined as TCG_EfiSpecIDEventStruct. 40 */ 41 LOG_EVENT("TCG_EfiSpecIDEvent:\n"); 42 LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index); 43 assert(event->header.pcr_index == (uint32_t)PCR_0); 44 45 LOG_EVENT(" EventType : %u\n", event->header.event_type); 46 assert(event->header.event_type == EV_NO_ACTION); 47 48 LOG_EVENT(" Digest :"); 49 for (i = 0U; i < sizeof(event->header.digest); ++i) { 50 uint8_t val = event->header.digest[i]; 51 52 (void)printf(" %02x", val); 53 if ((i & U(0xF)) == 0U) { 54 (void)printf("\n"); 55 LOG_EVENT("\t\t :"); 56 } 57 #if ENABLE_ASSERTIONS 58 if (val != 0U) { 59 valid = false; 60 } 61 #endif 62 } 63 if ((i & U(0xF)) != 0U) { 64 (void)printf("\n"); 65 } 66 67 assert(valid); 68 69 /* EventSize */ 70 event_size = event->header.event_size; 71 LOG_EVENT(" EventSize : %u\n", event_size); 72 73 LOG_EVENT(" Signature : %s\n", 74 event->struct_header.signature); 75 LOG_EVENT(" PlatformClass : %u\n", 76 event->struct_header.platform_class); 77 LOG_EVENT(" SpecVersion : %u.%u.%u\n", 78 event->struct_header.spec_version_major, 79 event->struct_header.spec_version_minor, 80 event->struct_header.spec_errata); 81 LOG_EVENT(" UintnSize : %u\n", 82 event->struct_header.uintn_size); 83 84 /* NumberOfAlgorithms */ 85 number_of_algorithms = event->struct_header.number_of_algorithms; 86 LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms); 87 88 /* Address of DigestSizes[] */ 89 alg_ptr = event->struct_header.digest_size; 90 91 /* Size of DigestSizes[] */ 92 digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); 93 assert(((uintptr_t)alg_ptr + digest_len) <= (uintptr_t)end_ptr); 94 95 LOG_EVENT(" DigestSizes :\n"); 96 for (i = 0U; i < number_of_algorithms; ++i) { 97 LOG_EVENT(" #%u AlgorithmId : SHA", i); 98 uint16_t algorithm_id = alg_ptr[i].algorithm_id; 99 100 switch (algorithm_id) { 101 case TPM_ALG_SHA256: 102 (void)printf("256\n"); 103 break; 104 case TPM_ALG_SHA384: 105 (void)printf("384\n"); 106 break; 107 case TPM_ALG_SHA512: 108 (void)printf("512\n"); 109 break; 110 default: 111 (void)printf("?\n"); 112 ERROR("Algorithm 0x%x not found\n", algorithm_id); 113 assert(false); 114 } 115 116 LOG_EVENT(" DigestSize : %u\n", 117 alg_ptr[i].digest_size); 118 } 119 120 /* Address of VendorInfoSize */ 121 info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len); 122 assert((uintptr_t)info_size_ptr <= (uintptr_t)end_ptr); 123 124 info_size = *info_size_ptr++; 125 LOG_EVENT(" VendorInfoSize : %u\n", info_size); 126 127 /* Check VendorInfo end address */ 128 assert(((uintptr_t)info_size_ptr + info_size) <= (uintptr_t)end_ptr); 129 130 /* Check EventSize */ 131 assert(event_size == (sizeof(id_event_struct_t) + 132 digest_len + info_size)); 133 if (info_size != 0U) { 134 LOG_EVENT(" VendorInfo :"); 135 for (i = 0U; i < info_size; ++i) { 136 (void)printf(" %02x", *info_size_ptr++); 137 } 138 (void)printf("\n"); 139 } 140 141 *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr; 142 *log_addr = info_size_ptr; 143 } 144 145 /* 146 * Print TCG_PCR_EVENT2 147 * 148 * @param[in/out] log_addr Pointer to Event Log 149 * @param[in/out] log_size Pointer to Event Log size 150 */ 151 static void event2_print(uint8_t **log_addr, size_t *log_size) 152 { 153 uint32_t event_size, count; 154 size_t sha_size, digests_size = 0U; 155 void *ptr = *log_addr; 156 #if ENABLE_ASSERTIONS 157 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); 158 #endif 159 160 assert(*log_size >= sizeof(event2_header_t)); 161 162 LOG_EVENT("PCR_Event2:\n"); 163 LOG_EVENT(" PCRIndex : %u\n", 164 ((event2_header_t *)ptr)->pcr_index); 165 LOG_EVENT(" EventType : %u\n", 166 ((event2_header_t *)ptr)->event_type); 167 168 count = ((event2_header_t *)ptr)->digests.count; 169 LOG_EVENT(" Digests Count : %u\n", count); 170 171 /* Address of TCG_PCR_EVENT2.Digests[] */ 172 ptr = (uint8_t *)ptr + sizeof(event2_header_t); 173 assert(((uintptr_t)ptr <= (uintptr_t)end_ptr) && (count != 0U)); 174 175 for (unsigned int i = 0U; i < count; ++i) { 176 /* Check AlgorithmId address */ 177 assert(((uintptr_t)ptr + 178 offsetof(tpmt_ha, digest)) <= (uintptr_t)end_ptr); 179 180 LOG_EVENT(" #%u AlgorithmId : SHA", i); 181 switch (((tpmt_ha *)ptr)->algorithm_id) { 182 case TPM_ALG_SHA256: 183 sha_size = SHA256_DIGEST_SIZE; 184 (void)printf("256\n"); 185 break; 186 case TPM_ALG_SHA384: 187 sha_size = SHA384_DIGEST_SIZE; 188 (void)printf("384\n"); 189 break; 190 case TPM_ALG_SHA512: 191 sha_size = SHA512_DIGEST_SIZE; 192 (void)printf("512\n"); 193 break; 194 default: 195 (void)printf("?\n"); 196 ERROR("Algorithm 0x%x not found\n", 197 ((tpmt_ha *)ptr)->algorithm_id); 198 panic(); 199 } 200 201 /* End of Digest[] */ 202 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); 203 assert(((uintptr_t)ptr + sha_size) <= (uintptr_t)end_ptr); 204 205 /* Total size of all digests */ 206 digests_size += sha_size; 207 208 LOG_EVENT(" Digest :"); 209 for (unsigned int j = 0U; j < sha_size; ++j) { 210 (void)printf(" %02x", *(uint8_t *)ptr++); 211 if ((j & U(0xF)) == U(0xF)) { 212 (void)printf("\n"); 213 if (j < (sha_size - 1U)) { 214 LOG_EVENT("\t\t :"); 215 } 216 } 217 } 218 } 219 220 /* TCG_PCR_EVENT2.EventSize */ 221 assert(((uintptr_t)ptr + offsetof(event2_data_t, event)) <= (uintptr_t)end_ptr); 222 223 event_size = ((event2_data_t *)ptr)->event_size; 224 LOG_EVENT(" EventSize : %u\n", event_size); 225 226 /* Address of TCG_PCR_EVENT2.Event[EventSize] */ 227 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); 228 229 /* End of TCG_PCR_EVENT2.Event[EventSize] */ 230 assert(((uintptr_t)ptr + event_size) <= (uintptr_t)end_ptr); 231 232 if ((event_size == sizeof(startup_locality_event_t)) && 233 (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) { 234 LOG_EVENT(" Signature : %s\n", 235 ((startup_locality_event_t *)ptr)->signature); 236 LOG_EVENT(" StartupLocality : %u\n", 237 ((startup_locality_event_t *)ptr)->startup_locality); 238 } else { 239 LOG_EVENT(" Event : %s\n", (uint8_t *)ptr); 240 } 241 242 *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr; 243 *log_addr = (uint8_t *)ptr + event_size; 244 } 245 #endif /* LOG_LEVEL >= EVENT_LOG_LEVEL */ 246 247 /* 248 * Print Event Log 249 * 250 * @param[in] log_addr Pointer to Event Log 251 * @param[in] log_size Event Log size 252 */ 253 void dump_event_log(uint8_t *log_addr, size_t log_size) 254 { 255 #if LOG_LEVEL >= EVENT_LOG_LEVEL 256 assert(log_addr != NULL); 257 258 /* Print TCG_EfiSpecIDEvent */ 259 id_event_print(&log_addr, &log_size); 260 261 while (log_size != 0U) { 262 event2_print(&log_addr, &log_size); 263 } 264 #endif 265 } 266