1 /*
2 * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "gpt.h"
9
10 #include "flash_layout.h"
11 #include "Driver_Flash.h"
12
13 #include <string.h>
14
15 extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
16
17 /* GPT has UTF-16LE strings, but we don't want to support them. FIP partitions
18 * are always labelled using ANSI characters, so this function compares the
19 * digits of the UTF-16LE string to an ANSI string.
20 */
gpt_strncmp(uint16_t * gpt_str,size_t gpt_maxlen,uint8_t * str,size_t str_len)21 static int gpt_strncmp(uint16_t *gpt_str, size_t gpt_maxlen, uint8_t *str,
22 size_t str_len)
23 {
24 size_t idx;
25
26 if (str_len > gpt_maxlen) {
27 return 1;
28 }
29
30 for (idx = 0; idx < str_len; idx++) {
31 if (str[idx] != gpt_str[idx]) {
32 return 1;
33 }
34 }
35
36 return 0;
37 }
38
gpt_get_header(uint32_t table_base,size_t atu_slot_size,gpt_header_t * header)39 int gpt_get_header(uint32_t table_base, size_t atu_slot_size,
40 gpt_header_t *header)
41 {
42 ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
43 /* Valid entries for data item width */
44 uint32_t data_width_byte[] = {
45 sizeof(uint8_t),
46 sizeof(uint16_t),
47 sizeof(uint32_t),
48 };
49 size_t data_width = data_width_byte[DriverCapabilities.data_width];
50 int rc;
51
52 if (atu_slot_size < sizeof(gpt_header_t)) {
53 return 1;
54 }
55
56 rc = FLASH_DEV_NAME.ReadData(table_base - FLASH_BASE_ADDRESS, header,
57 sizeof(gpt_header_t) / data_width);
58 if (rc != sizeof(gpt_header_t) / data_width) {
59 return rc;
60 }
61
62 if (memcmp(header->signature, "EFI PART", sizeof(header->signature))) {
63 return 1;
64 }
65
66 return 0;
67 }
68
gpt_get_list_entry_by_name(uint32_t list_base,uint32_t list_num_entries,size_t list_entry_size,uint8_t * name,size_t name_size,size_t atu_slot_size,gpt_entry_t * entry)69 int gpt_get_list_entry_by_name(uint32_t list_base, uint32_t list_num_entries,
70 size_t list_entry_size, uint8_t *name,
71 size_t name_size, size_t atu_slot_size,
72 gpt_entry_t *entry)
73 {
74 ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
75 /* Valid entries for data item width */
76 uint32_t data_width_byte[] = {
77 sizeof(uint8_t),
78 sizeof(uint16_t),
79 sizeof(uint32_t),
80 };
81 size_t data_width = data_width_byte[DriverCapabilities.data_width];
82 int rc;
83 uint64_t idx;
84
85 /* List entry is using names larger than EFI_NAMELEN_MAX - this is either an
86 * RSE GPT config error or an out-of-spec GPT partition, either way we fail
87 * here.
88 */
89 if (list_entry_size > sizeof(gpt_entry_t)) {
90 return 1;
91 }
92
93 /* Check for overflow */
94 if (list_base + list_num_entries * list_entry_size < list_base ||
95 list_num_entries * list_entry_size > atu_slot_size) {
96 return 1;
97 }
98
99 for (idx = list_base;
100 idx < list_base + list_num_entries * list_entry_size;
101 idx += list_entry_size) {
102 rc = FLASH_DEV_NAME.ReadData(idx - FLASH_BASE_ADDRESS, entry,
103 sizeof(gpt_entry_t));
104 if (rc != sizeof(gpt_entry_t) / data_width) {
105 return rc;
106 }
107
108 if (gpt_strncmp(entry->name,
109 list_entry_size - offsetof(gpt_entry_t, name),
110 name, name_size)) {
111 return 0;
112 }
113 }
114
115 return 1;
116 }
117