1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#include "main.h"
#include "gpt.h"
#include <zlib.h>
#include <cstring>
#include <arpa/inet.h>
#define UUID "\x5E\x86\x90\xEF\xD0\x30\x03\x46\x99\x3D\x54\x6E\xB0\xE7\x1B\x0D"
TEST_CASE("GPT") {
// First eight bytes must be "EFI PART"
SUBCASE("Signature") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 4194287, 34, nullptr));
CHECK(0 == memcmp(&head.signature, "EFI PART", sizeof(head.signature)));
}
// Bytes 0x8--0xb must be 00 00 01 00 (1.00 by UEFI logic)
SUBCASE("Revision") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 4194287, 34, nullptr));
auto revision = head.revision;
CHECK(0x00010000 == revision);
}
// Bytes 0xc--0xf must be >= 92, should be the logical block size
SUBCASE("HeaderSize") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 4194287, 34, nullptr));
auto headsize = head.headsize;
CHECK(92 == headsize);
}
// Bytes 0x18--0x1f are the sector of the GPT primary, usually 1
// Bytes 0x20--0x27 are the sector of the GPT alternate, provided as argument
SUBCASE("GPTLBAs") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 100000, 34, nullptr));
auto lba = head.lba;
CHECK(1 == lba);
auto backuplba = head.backuplba;
CHECK(100000 == backuplba);
}
// Verify the 16-byte UUID is as specified
SUBCASE("UUID") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 4194287, 34, UUID));
CHECK(0 == memcmp(head.disk_guid, UUID, sizeof(head.disk_guid)));
}
SUBCASE("CRC32Sanity") {
const unsigned char sample[] = "123456789";
uint32_t crc = crc32(0L, Z_NULL, 0);
crc = crc32(crc, sample, sizeof(sample) - 1);
CHECK(crc == 0xCBF43926);
crc = crc32(0L, Z_NULL, 0);
uint32_t db = htonl(0xdeadbeef);
crc = crc32(crc, (const unsigned char*)&db, 4);
CHECK(crc == 2090640218);
}
// Verify both CRCs, and the reserved area following HeaderCRC32
SUBCASE("CRC32") {
gpt_header head;
CHECK(0 == initialize_gpt(&head, 512, 4194287, 34, UUID));
// partition entry size must be a positive multiple of 128 (usually 128)
auto partsize = head.partsize;
CHECK(0 < partsize);
CHECK(0 == (partsize % 128));
// number of partition entries, usually 128 (MINIMUM_GPT_ENTRIES)
auto partcount = head.partcount;
CHECK(128 <= partcount);
auto entries = new gpt_entry[partcount];
memset(entries, 0, sizeof(*entries) * partcount);
CHECK(0 == update_crc(&head, entries));
auto crc = head.crc;
// FIXME fix on big-endian!
WARN(2006165414 == crc);
auto reserved = head.reserved;
CHECK(0 == reserved);
auto partcrc = head.partcrc;
CHECK(2874462854 == partcrc);
delete[] entries;
}
// Check that LBA of 512 sets header size and zeroes out remainder of sector.
// The Unified Extensible Firmware Interface Specification, Version 2.3.1,
// Errata C, June 27, 2012, states on page 104, in Table 16: "Size in bytes
// of the GPT Header. The HeaderSize must be greater than 92 and must be less
// than or equal to the logical block size." But everyone uses 92 :/.
SUBCASE("FullLBA") {
unsigned char sector[512];
memset(sector, 0xff, sizeof(sector));
gpt_header* head = reinterpret_cast<gpt_header*>(sector);
CHECK(0 == initialize_gpt(head, sizeof(sector), 4194287, 34, nullptr));
auto headsize = head->headsize;
CHECK(92 == headsize);
for(size_t idx = 92 ; idx < sizeof(sector) ; ++idx){
CHECK(0 == sector[idx]);
}
}
}
|