blob: 9a38a99932acd52c3c19b8fc4855e5d0793ca1a2 [file] [log] [blame]
Julian Hall69a25f32022-09-26 14:55:57 +01001/*
2 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8#include <string>
9#include <cstring>
10#include <common/uuid/uuid.h>
11#include <service/block_storage/block_store/device/ram/ram_block_store.h>
12#include <service/block_storage/config/ref/ref_partition_configurator.h>
13#include <media/volume/index/volume_index.h>
14#include <media/volume/block_io_dev/block_io_dev.h>
Julian Hall69a25f32022-09-26 14:55:57 +010015#include <media/disk/disk_images/ref_partition.h>
Julian Hall09a05822022-09-28 16:53:49 +010016#include <media/disk/formatter/disk_formatter.h>
Julian Hall69a25f32022-09-26 14:55:57 +010017#include <media/disk/partition_table.h>
18#include <CppUTest/TestHarness.h>
19
20TEST_GROUP(PartitionTableTests)
21{
22 void setup()
23 {
24 /* Load reference GPT image into ram block store */
25 size_t block_size = PLAT_PARTITION_BLOCK_SIZE;
26 size_t num_blocks = ref_partition_data_length / block_size;
27
28 m_block_store = ram_block_store_init(&m_ram_block_store,
29 NULL,
Julian Hall09a05822022-09-28 16:53:49 +010030 num_blocks, block_size);
Julian Hall69a25f32022-09-26 14:55:57 +010031
32 CHECK_TRUE(m_block_store);
33
34 memset(m_partition_guid.octets, 0, sizeof(m_partition_guid.octets));
35
36 m_dev_handle = 0;
37 m_volume_spec = 0;
38
39 int result = block_io_dev_init(&m_block_io_dev,
40 m_block_store, &m_partition_guid,
41 &m_dev_handle, &m_volume_spec);
42
43 LONGS_EQUAL(0, result);
44 CHECK_TRUE(m_dev_handle);
45 CHECK_TRUE(m_volume_spec);
46
Julian Hall09a05822022-09-28 16:53:49 +010047 result = disk_formatter_clone(
48 m_dev_handle, m_volume_spec,
49 ref_partition_data, ref_partition_data_length);
50
51 LONGS_EQUAL(0, result);
52
Julian Hall69a25f32022-09-26 14:55:57 +010053 volume_index_init();
Julian Hall94970102022-09-28 11:02:48 +010054 volume_index_add(VOLUME_ID_SECURE_FLASH, m_dev_handle, m_volume_spec);
Julian Hall69a25f32022-09-26 14:55:57 +010055 }
56
57 void teardown()
58 {
59 block_io_dev_deinit(&m_block_io_dev);
60 ram_block_store_deinit(&m_ram_block_store);
61 volume_index_clear();
62 }
63
64 void uuid_from_canonical(uuid_t *uuid, const char *canonical)
65 {
Julian Hall31d4fdd2022-12-01 16:52:01 +000066 uuid_parse_to_guid_octets(canonical, (uint8_t*)uuid, sizeof(uuid_t));
Julian Hall69a25f32022-09-26 14:55:57 +010067 }
68
69 void corrupt_mbr()
70 {
71 /* Scribble over the protective MBR signature */
72 static const char scribble[] = "scribble";
73 psa_status_t status = ram_block_store_modify(
74 &m_ram_block_store, 510,
75 (const uint8_t*)scribble, sizeof(scribble));
76 LONGS_EQUAL(PSA_SUCCESS, status);
77 }
78
79 void corrupt_primary_gpt_header()
80 {
81 /* Scribble over the primary GPT header in block 1 */
82 static const char scribble[] = "scribble";
83 psa_status_t status = ram_block_store_modify(
84 &m_ram_block_store, PLAT_PARTITION_BLOCK_SIZE * 1,
85 (const uint8_t*)scribble, sizeof(scribble));
86 LONGS_EQUAL(PSA_SUCCESS, status);
87 }
88
Julian Hall69a25f32022-09-26 14:55:57 +010089 static const uint32_t CLIENT_ID = 0;
90 static const size_t FIRST_USABLE_LBA = 34;
91
92 struct uuid_octets m_partition_guid;
93 struct block_store *m_block_store;
94 struct ram_block_store m_ram_block_store;
95 struct block_io_dev m_block_io_dev;
96 uintptr_t m_dev_handle;
97 uintptr_t m_volume_spec;
98};
99
100TEST(PartitionTableTests, loadRefPartitionTable)
101{
Julian Hall94970102022-09-28 11:02:48 +0100102 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100103 LONGS_EQUAL(0, result);
104
105 /* Check for expected partition entries */
106 const partition_entry_t *partition_entry = NULL;
107 uuid_t partition_guid;
108
109 uuid_from_canonical(&partition_guid, REF_PARTITION_1_GUID);
110 partition_entry = get_partition_entry_by_uuid(&partition_guid);
111 CHECK_TRUE(partition_entry);
112 UNSIGNED_LONGS_EQUAL(
113 FIRST_USABLE_LBA + REF_PARTITION_1_STARTING_LBA,
114 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
115 UNSIGNED_LONGS_EQUAL(
116 (REF_PARTITION_1_ENDING_LBA - REF_PARTITION_1_STARTING_LBA + 1),
117 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
118
119 uuid_from_canonical(&partition_guid, REF_PARTITION_2_GUID);
120 partition_entry = get_partition_entry_by_uuid(&partition_guid);
121 CHECK_TRUE(partition_entry);
122 UNSIGNED_LONGS_EQUAL(
123 FIRST_USABLE_LBA + REF_PARTITION_2_STARTING_LBA,
124 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
125 UNSIGNED_LONGS_EQUAL(
126 (REF_PARTITION_2_ENDING_LBA - REF_PARTITION_2_STARTING_LBA + 1),
127 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
128
129 uuid_from_canonical(&partition_guid, REF_PARTITION_3_GUID);
130 partition_entry = get_partition_entry_by_uuid(&partition_guid);
131 CHECK_TRUE(partition_entry);
132 UNSIGNED_LONGS_EQUAL(
133 FIRST_USABLE_LBA + REF_PARTITION_3_STARTING_LBA,
134 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
135 UNSIGNED_LONGS_EQUAL(
136 (REF_PARTITION_3_ENDING_LBA - REF_PARTITION_3_STARTING_LBA + 1),
137 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
138
139 uuid_from_canonical(&partition_guid, REF_PARTITION_4_GUID);
140 partition_entry = get_partition_entry_by_uuid(&partition_guid);
141 CHECK_TRUE(partition_entry);
142 UNSIGNED_LONGS_EQUAL(
143 FIRST_USABLE_LBA + REF_PARTITION_4_STARTING_LBA,
144 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
145 UNSIGNED_LONGS_EQUAL(
146 (REF_PARTITION_4_ENDING_LBA - REF_PARTITION_4_STARTING_LBA + 1),
147 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
148}
149
150TEST(PartitionTableTests, detectCorruptedMbr)
151{
152 corrupt_mbr();
Julian Hall94970102022-09-28 11:02:48 +0100153 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100154 LONGS_EQUAL(-ENOENT, result);
155}
156
157// Shows up defect in TF-A where failed GPT header CRC results in an assert.
158IGNORE_TEST(PartitionTableTests, detectCorruptedGptHeader)
159{
160 /* Load should be successful with a corrupted primary GPT header as
161 * backup is still available.
162 */
163 corrupt_primary_gpt_header();
Julian Hall94970102022-09-28 11:02:48 +0100164 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100165 LONGS_EQUAL(0, result);
166}