blob: 29cf0dd4d89274fa8d1f027e637d6bcbeabb5fac [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>
Julian Hall4a658ac2022-10-20 10:44:49 +010014#include <media/volume/block_volume/block_volume.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
Julian Hall4a658ac2022-10-20 10:44:49 +010036 m_volume = NULL;
Julian Hall69a25f32022-09-26 14:55:57 +010037
Julian Hall4a658ac2022-10-20 10:44:49 +010038 int result = block_volume_init(&m_block_volume,
Julian Hall69a25f32022-09-26 14:55:57 +010039 m_block_store, &m_partition_guid,
Julian Hall4a658ac2022-10-20 10:44:49 +010040 &m_volume);
Julian Hall69a25f32022-09-26 14:55:57 +010041
42 LONGS_EQUAL(0, result);
Julian Hall4a658ac2022-10-20 10:44:49 +010043 CHECK_TRUE(m_volume);
Julian Hall69a25f32022-09-26 14:55:57 +010044
Julian Hall09a05822022-09-28 16:53:49 +010045 result = disk_formatter_clone(
Julian Hall4a658ac2022-10-20 10:44:49 +010046 m_volume->dev_handle, m_volume->io_spec,
Julian Hall09a05822022-09-28 16:53:49 +010047 ref_partition_data, ref_partition_data_length);
48
49 LONGS_EQUAL(0, result);
50
Julian Hall69a25f32022-09-26 14:55:57 +010051 volume_index_init();
Julian Hall4a658ac2022-10-20 10:44:49 +010052 volume_index_add(VOLUME_ID_SECURE_FLASH, m_volume);
Julian Hall69a25f32022-09-26 14:55:57 +010053 }
54
55 void teardown()
56 {
Julian Hall4a658ac2022-10-20 10:44:49 +010057 block_volume_deinit(&m_block_volume);
Julian Hall69a25f32022-09-26 14:55:57 +010058 ram_block_store_deinit(&m_ram_block_store);
59 volume_index_clear();
60 }
61
62 void uuid_from_canonical(uuid_t *uuid, const char *canonical)
63 {
Julian Hall31d4fdd2022-12-01 16:52:01 +000064 uuid_parse_to_guid_octets(canonical, (uint8_t*)uuid, sizeof(uuid_t));
Julian Hall69a25f32022-09-26 14:55:57 +010065 }
66
67 void corrupt_mbr()
68 {
69 /* Scribble over the protective MBR signature */
70 static const char scribble[] = "scribble";
71 psa_status_t status = ram_block_store_modify(
72 &m_ram_block_store, 510,
73 (const uint8_t*)scribble, sizeof(scribble));
74 LONGS_EQUAL(PSA_SUCCESS, status);
75 }
76
77 void corrupt_primary_gpt_header()
78 {
79 /* Scribble over the primary GPT header in block 1 */
80 static const char scribble[] = "scribble";
81 psa_status_t status = ram_block_store_modify(
82 &m_ram_block_store, PLAT_PARTITION_BLOCK_SIZE * 1,
83 (const uint8_t*)scribble, sizeof(scribble));
84 LONGS_EQUAL(PSA_SUCCESS, status);
85 }
86
Julian Hall69a25f32022-09-26 14:55:57 +010087 static const uint32_t CLIENT_ID = 0;
88 static const size_t FIRST_USABLE_LBA = 34;
89
90 struct uuid_octets m_partition_guid;
91 struct block_store *m_block_store;
92 struct ram_block_store m_ram_block_store;
Julian Hall4a658ac2022-10-20 10:44:49 +010093 struct block_volume m_block_volume;
94 struct volume *m_volume;
Julian Hall69a25f32022-09-26 14:55:57 +010095};
96
97TEST(PartitionTableTests, loadRefPartitionTable)
98{
Julian Hall94970102022-09-28 11:02:48 +010099 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100100 LONGS_EQUAL(0, result);
101
102 /* Check for expected partition entries */
103 const partition_entry_t *partition_entry = NULL;
104 uuid_t partition_guid;
105
106 uuid_from_canonical(&partition_guid, REF_PARTITION_1_GUID);
107 partition_entry = get_partition_entry_by_uuid(&partition_guid);
108 CHECK_TRUE(partition_entry);
109 UNSIGNED_LONGS_EQUAL(
110 FIRST_USABLE_LBA + REF_PARTITION_1_STARTING_LBA,
111 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
112 UNSIGNED_LONGS_EQUAL(
113 (REF_PARTITION_1_ENDING_LBA - REF_PARTITION_1_STARTING_LBA + 1),
114 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
115
116 uuid_from_canonical(&partition_guid, REF_PARTITION_2_GUID);
117 partition_entry = get_partition_entry_by_uuid(&partition_guid);
118 CHECK_TRUE(partition_entry);
119 UNSIGNED_LONGS_EQUAL(
120 FIRST_USABLE_LBA + REF_PARTITION_2_STARTING_LBA,
121 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
122 UNSIGNED_LONGS_EQUAL(
123 (REF_PARTITION_2_ENDING_LBA - REF_PARTITION_2_STARTING_LBA + 1),
124 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
125
126 uuid_from_canonical(&partition_guid, REF_PARTITION_3_GUID);
127 partition_entry = get_partition_entry_by_uuid(&partition_guid);
128 CHECK_TRUE(partition_entry);
129 UNSIGNED_LONGS_EQUAL(
130 FIRST_USABLE_LBA + REF_PARTITION_3_STARTING_LBA,
131 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
132 UNSIGNED_LONGS_EQUAL(
133 (REF_PARTITION_3_ENDING_LBA - REF_PARTITION_3_STARTING_LBA + 1),
134 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
135
136 uuid_from_canonical(&partition_guid, REF_PARTITION_4_GUID);
137 partition_entry = get_partition_entry_by_uuid(&partition_guid);
138 CHECK_TRUE(partition_entry);
139 UNSIGNED_LONGS_EQUAL(
140 FIRST_USABLE_LBA + REF_PARTITION_4_STARTING_LBA,
141 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
142 UNSIGNED_LONGS_EQUAL(
143 (REF_PARTITION_4_ENDING_LBA - REF_PARTITION_4_STARTING_LBA + 1),
144 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
145}
146
147TEST(PartitionTableTests, detectCorruptedMbr)
148{
149 corrupt_mbr();
Julian Hall94970102022-09-28 11:02:48 +0100150 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100151 LONGS_EQUAL(-ENOENT, result);
152}
153
154// Shows up defect in TF-A where failed GPT header CRC results in an assert.
155IGNORE_TEST(PartitionTableTests, detectCorruptedGptHeader)
156{
157 /* Load should be successful with a corrupted primary GPT header as
158 * backup is still available.
159 */
160 corrupt_primary_gpt_header();
Julian Hall94970102022-09-28 11:02:48 +0100161 int result = load_partition_table(VOLUME_ID_SECURE_FLASH);
Julian Hall69a25f32022-09-26 14:55:57 +0100162 LONGS_EQUAL(0, result);
163}