Coverage Report

Created: 2026-09-28 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfBoot/include/gpt.h
Line
Count
Source
1
/* gpt.h
2
 *
3
 * Generic GPT (GUID Partition Table) parsing support.
4
 *
5
 * Copyright (C) 2026 wolfSSL Inc.
6
 *
7
 * This file is part of wolfBoot.
8
 *
9
 * wolfBoot is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * wolfBoot is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
22
 */
23
24
#ifndef GPT_H
25
#define GPT_H
26
27
#include <stdint.h>
28
29
/* Every field in an MBR, a GPT structure, a FAT32 BPB and an ext4 superblock
30
 * is little-endian ON DISK. Casting a sector to a packed struct and
31
 * dereferencing it is therefore only correct on a little-endian host, so all
32
 * on-disk values are read through these instead. One definition, used by the
33
 * partition layer and by the filesystem parsers alike. */
34
static inline uint16_t gpt_le16(const uint8_t *p)
35
3.21k
{
36
3.21k
    return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8));
37
3.21k
}
Unexecuted instantiation: fuzz_gpt.c:gpt_le16
gpt.c:gpt_le16
Line
Count
Source
35
3.21k
{
36
3.21k
    return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8));
37
3.21k
}
38
39
static inline uint32_t gpt_le32(const uint8_t *p)
40
4.09k
{
41
4.09k
    return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) |
42
4.09k
           ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
43
4.09k
}
Unexecuted instantiation: fuzz_gpt.c:gpt_le32
gpt.c:gpt_le32
Line
Count
Source
40
4.09k
{
41
4.09k
    return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) |
42
4.09k
           ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
43
4.09k
}
44
45
static inline uint64_t gpt_le64(const uint8_t *p)
46
1.83k
{
47
1.83k
    return (uint64_t)gpt_le32(p) | ((uint64_t)gpt_le32(p + 4) << 32);
48
1.83k
}
Unexecuted instantiation: fuzz_gpt.c:gpt_le64
gpt.c:gpt_le64
Line
Count
Source
46
1.83k
{
47
1.83k
    return (uint64_t)gpt_le32(p) | ((uint64_t)gpt_le32(p + 4) << 32);
48
1.83k
}
49
50
51
/* GPT Constants */
52
705
#define GPT_SECTOR_SIZE        512 /* 0x200 */
53
574
#define GPT_SIGNATURE          0x5452415020494645ULL /* "EFI PART" */
54
40
#define GPT_PTYPE_PROTECTIVE   0xEE
55
3.21k
#define GPT_PART_NAME_SIZE     36
56
40
#define GPT_MBR_ENTRY_START    0x01BE
57
58
/* MBR partition entry field offsets, shared by src/gpt.c and src/disk.c. */
59
40
#define GPT_MBR_PTE_PTYPE      0x04
60
5
#define GPT_MBR_PTE_LBA_FIRST  0x08
61
#define GPT_MBR_PTE_LBA_SIZE   0x0C
62
40
#define GPT_MBR_PTE_SIZE       0x10
63
87
#define GPT_MBR_BOOTSIG_OFFSET 0x01FE
64
87
#define GPT_MBR_BOOTSIG_VALUE  0xAA55
65
#define GPT_PART_ENTRY_SIZE    256
66
/* UEFI reserves 128 partition entries by default; bound the partition-entry
67
 * array (n_part * array_sz) used by the CRC scan to this many entries so a
68
 * crafted header cannot force an unbounded number of disk reads. */
69
#define GPT_MAX_PART_ENTRIES   128
70
71
/**
72
 * @brief MBR partition table entry structure.
73
 *
74
 * This packed structure defines the layout of an MBR partition table entry
75
 * used to identify GPT partitions (protective MBR).
76
 */
77
struct __attribute__((packed)) gpt_mbr_part_entry {
78
    uint8_t stat;
79
    uint8_t chs_first[3];
80
    uint8_t ptype;
81
    uint8_t chs_last[3];
82
    uint32_t lba_first;
83
    uint32_t lba_size;
84
};
85
86
/**
87
 * @brief GPT (GUID Partition Table) header structure.
88
 */
89
struct __attribute__((packed)) guid_ptable {
90
    uint64_t signature;
91
    uint32_t revision;
92
    uint32_t hdr_size;
93
    uint32_t hdr_crc32;
94
    uint32_t res0;
95
    uint64_t main_lba;
96
    uint64_t backup_lba;
97
    uint64_t first_usable;
98
    uint64_t last_usable;
99
    uint64_t disk_guid[2];
100
    uint64_t start_array;
101
    uint32_t n_part;
102
    uint32_t array_sz;
103
    uint32_t part_crc;
104
    uint8_t  res1[GPT_SECTOR_SIZE - 0x5C];
105
};
106
107
/**
108
 * @brief GPT partition entry structure.
109
 *
110
 * This packed structure defines the layout of a GPT partition entry
111
 * used to describe individual partitions on the disk.
112
 */
113
struct __attribute__((packed)) gpt_part_entry {
114
    uint64_t type[2];
115
    uint64_t uuid[2];
116
    uint64_t first;
117
    uint64_t last;
118
    uint64_t flags;
119
    uint16_t name[GPT_PART_NAME_SIZE];
120
};
121
122
/**
123
 * @brief Parsed partition information.
124
 *
125
 * This structure holds parsed information about a partition extracted
126
 * from a GPT partition entry.
127
 */
128
struct gpt_part_info {
129
    uint64_t start;  /* Start offset in bytes */
130
    uint64_t end;    /* End offset in bytes */
131
    uint16_t name[GPT_PART_NAME_SIZE];
132
};
133
134
/**
135
 * @brief CRC32 context for GPT header and partition-array validation.
136
 */
137
struct gpt_crc32_ctx {
138
    uint32_t value;
139
};
140
141
/**
142
 * @brief Check MBR for protective GPT partition entry.
143
 *
144
 * Scans the MBR sector for a protective GPT partition entry (type 0xEE)
145
 * and validates the boot signature.
146
 *
147
 * @param[in] mbr_sector Pointer to 512-byte MBR sector data.
148
 * @param[out] gpt_lba If not NULL, receives the LBA of the GPT header.
149
 *
150
 * @return 0 on success (valid protective MBR found), -1 on error.
151
 */
152
int gpt_check_mbr_protective(const uint8_t *mbr_sector, uint32_t *gpt_lba);
153
154
/**
155
 * @brief Parse and validate a GPT header.
156
 *
157
 * Validates the GPT signature and copies header data to the output structure.
158
 *
159
 * @param[in] sector Pointer to 512-byte GPT header sector data.
160
 * @param[out] hdr Pointer to structure to receive parsed header.
161
 *
162
 * @return 0 on success (valid GPT header), -1 on error.
163
 */
164
int gpt_parse_header(const uint8_t *sector, struct guid_ptable *hdr);
165
166
/**
167
 * @brief Parse a GPT partition entry.
168
 *
169
 * Parses a single partition entry and extracts partition information.
170
 * Returns success only if the partition entry is valid (non-zero type GUID).
171
 *
172
 * @param[in] entry_data Pointer to partition entry data.
173
 * @param[in] entry_size Size of the partition entry in bytes.
174
 * @param[out] part Pointer to structure to receive parsed partition info.
175
 *
176
 * @return 0 on success (valid partition entry), -1 if entry is empty/invalid.
177
 */
178
int gpt_parse_partition(const uint8_t *entry_data, uint32_t entry_size,
179
                        struct gpt_part_info *part);
180
181
/**
182
 * @brief Initialize a GPT CRC32 calculation.
183
 *
184
 * @param[out] ctx Pointer to CRC32 context.
185
 */
186
void gpt_crc32_init(struct gpt_crc32_ctx *ctx);
187
188
/**
189
 * @brief Accumulate bytes into a GPT CRC32 calculation.
190
 *
191
 * @param[in,out] ctx Pointer to CRC32 context.
192
 * @param[in] data Pointer to input bytes.
193
 * @param[in] len Number of bytes to process.
194
 */
195
void gpt_crc32_update(struct gpt_crc32_ctx *ctx, const uint8_t *data,
196
                      uint32_t len);
197
198
/**
199
 * @brief Finalize a GPT CRC32 calculation.
200
 *
201
 * @param[in] ctx Pointer to CRC32 context.
202
 *
203
 * @return Final CRC32 value.
204
 */
205
uint32_t gpt_crc32_final(const struct gpt_crc32_ctx *ctx);
206
207
/**
208
 * @brief Compare UTF-16 partition name with ASCII string.
209
 *
210
 * Compares a GPT partition name (UTF-16LE) with an ASCII string label.
211
 *
212
 * @param[in] utf16_name UTF-16LE partition name from GPT entry.
213
 * @param[in] ascii_label ASCII string to compare against.
214
 *
215
 * @return 1 if names match, 0 if they don't match.
216
 */
217
int gpt_part_name_eq(const uint16_t *utf16_name, const char *ascii_label);
218
219
#endif /* GPT_H */