mb/google/brya/var/omnigul: Modify NVMe and UFS Storage support
[coreboot.git] / payloads / libpayload / tests / libcbfs / cbfs-verification-test.c
blob25e402cca3ef2046552abece68ec253a33b11bd3
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cbfs.h>
4 #include <cbfs_glue.h>
5 #include <string.h>
6 #include <mocks/cbfs_util.h>
7 #include <tests/test.h>
9 #include "../libcbfs/cbfs.c"
11 /* Mocks */
13 unsigned long virtual_offset = 0;
14 struct sysinfo_t lib_sysinfo;
16 size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg)
18 if (hash_alg != VB2_HASH_SHA256) {
19 fail_msg("Unsupported hash algorithm: %d\n", hash_alg);
20 return 0;
23 return VB2_SHA256_DIGEST_SIZE;
26 vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
27 const struct vb2_hash *hash)
29 assert_true(allow_hwcrypto);
30 check_expected_ptr(buf);
31 check_expected(size);
33 assert_int_equal(hash->algo, VB2_HASH_SHA256);
35 if (!memcmp(hash->sha256, good_hash, sizeof(good_hash)))
36 return VB2_SUCCESS;
38 if (!memcmp(hash->sha256, bad_hash, sizeof(bad_hash)))
39 return VB2_ERROR_SHA_MISMATCH;
41 fail_msg("%s called with bad hash", __func__);
42 return VB2_ERROR_SHA_MISMATCH;
45 unsigned long ulzman(const unsigned char *src, unsigned long srcn, unsigned char *dst,
46 unsigned long dstn)
48 size_t copy_size = MIN(srcn, dstn);
49 function_called();
50 memcpy(dst, src, copy_size);
51 return copy_size;
54 size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn)
56 size_t copy_size = MIN(srcn, dstn);
57 function_called();
58 memcpy(dst, src, copy_size);
59 return copy_size;
62 enum cb_err cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
63 union cbfs_mdata *mdata_out, size_t *data_offset_out)
65 return CB_CBFS_CACHE_FULL;
68 enum cb_err cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out,
69 size_t *data_offset_out, struct vb2_hash *metadata_hash)
71 assert_non_null(dev);
72 check_expected(name);
74 enum cb_err ret = mock_type(enum cb_err);
75 if (ret != CB_SUCCESS)
76 return ret;
78 memcpy(mdata_out, mock_ptr_type(const union cbfs_mdata *), sizeof(union cbfs_mdata));
79 *data_offset_out = mock_type(size_t);
80 return CB_SUCCESS;
83 static void expect_cbfs_lookup(const char *name, enum cb_err err, const union cbfs_mdata *mdata,
84 size_t data_offset_out)
86 expect_string(cbfs_lookup, name, name);
87 will_return(cbfs_lookup, err);
89 if (err == CB_SUCCESS) {
90 will_return(cbfs_lookup, mdata);
91 will_return(cbfs_lookup, data_offset_out);
95 const void *cbfs_find_attr(const union cbfs_mdata *mdata, uint32_t attr_tag, size_t size_check)
97 return mock_ptr_type(void *);
100 enum cb_err fmap_locate_area(const char *name, size_t *offset, size_t *size)
102 *offset = 0;
103 *size = 0;
104 return CB_SUCCESS;
107 ssize_t boot_device_read(void *buf, size_t offset, size_t size)
109 /* Offset should be based on an address from lib_sysinfo.cbfs_offset */
110 memcpy(buf, (void *)offset, size);
112 return size;
115 const struct vb2_hash *cbfs_file_hash(const union cbfs_mdata *mdata)
117 return mock_ptr_type(const struct vb2_hash *);
120 /* Utils */
122 static void clear_cbfs_boot_devices(void)
124 lib_sysinfo.cbfs_ro_mcache_offset = 0;
125 lib_sysinfo.cbfs_ro_mcache_size = 0;
126 lib_sysinfo.cbfs_offset = 0;
127 lib_sysinfo.cbfs_size = 0;
128 lib_sysinfo.cbfs_rw_mcache_offset = 0;
129 lib_sysinfo.cbfs_rw_mcache_size = 0;
130 memset((void *)cbfs_get_boot_device(true), 0, sizeof(struct cbfs_boot_device));
131 memset((void *)cbfs_get_boot_device(false), 0, sizeof(struct cbfs_boot_device));
134 void set_cbfs(uint64_t offset, size_t size)
136 clear_cbfs_boot_devices();
137 lib_sysinfo.cbfs_offset = offset;
138 lib_sysinfo.cbfs_size = size;
141 /* Tests */
143 static int setup_test_cbfs(void **state)
145 clear_cbfs_boot_devices();
146 return 0;
149 static void test_cbfs_map_no_hash(void **state)
151 void *mapping = NULL;
152 size_t size = 0;
154 set_cbfs((uint64_t)&file_no_hash, sizeof(file_no_hash));
156 expect_cbfs_lookup(TEST_DATA_1_FILENAME, CB_SUCCESS,
157 (const union cbfs_mdata *)&file_no_hash,
158 be32toh(file_no_hash.header.offset));
159 will_return(cbfs_find_attr, NULL);
161 if (CONFIG(LP_CBFS_VERIFICATION)) {
162 /* File with no hash. No hash causes hash mismatch by default,
163 so mapping will not be completed successfully. */
164 will_return(cbfs_file_hash, NULL);
165 mapping = cbfs_map(TEST_DATA_1_FILENAME, NULL);
166 assert_null(mapping);
167 } else {
168 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size);
169 assert_non_null(mapping);
170 assert_int_equal(TEST_DATA_1_SIZE, size);
171 assert_memory_equal(test_data_1, mapping, size);
172 cbfs_unmap(mapping);
176 static void test_cbfs_map_valid_hash_impl(void **state, bool lz4_compressed)
178 void *mapping = NULL;
179 size_t size = 0;
180 struct vb2_hash hash = {
181 .algo = VB2_HASH_SHA256,
183 memcpy(&hash.sha256, good_hash, VB2_SHA256_DIGEST_SIZE);
185 set_cbfs((uint64_t)&file_valid_hash, sizeof(file_valid_hash));
187 expect_cbfs_lookup(TEST_DATA_1_FILENAME, CB_SUCCESS,
188 (const union cbfs_mdata *)&file_valid_hash,
189 be32toh(file_valid_hash.header.offset));
191 if (lz4_compressed) {
192 struct cbfs_file_attr_compression cattr = {
193 .compression = htobe32(CBFS_COMPRESS_LZ4),
194 .decompressed_size = htobe32(TEST_DATA_1_SIZE),
196 will_return(cbfs_find_attr, &cattr);
197 expect_function_call(ulz4fn);
198 } else {
199 will_return(cbfs_find_attr, NULL);
202 if (CONFIG(LP_CBFS_VERIFICATION)) {
203 will_return(cbfs_file_hash, &hash);
204 expect_memory(vb2_hash_verify, buf,
205 &file_valid_hash.attrs_and_data[HASH_ATTR_SIZE], HASH_ATTR_SIZE);
206 expect_value(vb2_hash_verify, size, TEST_DATA_1_SIZE);
207 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size);
208 assert_non_null(mapping);
209 assert_int_equal(TEST_DATA_1_SIZE, size);
210 assert_memory_equal(mapping, &file_valid_hash.attrs_and_data[HASH_ATTR_SIZE],
211 size);
212 } else {
213 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size);
214 assert_non_null(mapping);
215 assert_int_equal(TEST_DATA_1_SIZE, size);
216 assert_memory_equal(test_data_1, mapping, size);
217 cbfs_unmap(mapping);
221 static void test_cbfs_map_valid_hash(void **state)
223 test_cbfs_map_valid_hash_impl(state, false);
226 static void test_cbfs_map_valid_hash_with_lz4(void **state)
228 test_cbfs_map_valid_hash_impl(state, true);
231 static void test_cbfs_map_invalid_hash(void **state)
233 void *mapping = NULL;
234 size_t size = 0;
235 struct vb2_hash hash = {
236 .algo = VB2_HASH_SHA256,
238 memcpy(&hash.sha256, bad_hash, VB2_SHA256_DIGEST_SIZE);
240 set_cbfs((uint64_t)&file_broken_hash, sizeof(file_broken_hash));
242 expect_cbfs_lookup(TEST_DATA_1_FILENAME, CB_SUCCESS,
243 (const union cbfs_mdata *)&file_broken_hash,
244 be32toh(file_broken_hash.header.offset));
245 will_return(cbfs_find_attr, NULL);
247 if (CONFIG(LP_CBFS_VERIFICATION)) {
248 will_return(cbfs_file_hash, &hash);
249 expect_memory(vb2_hash_verify, buf,
250 &file_broken_hash.attrs_and_data[HASH_ATTR_SIZE], HASH_ATTR_SIZE);
251 expect_value(vb2_hash_verify, size, TEST_DATA_1_SIZE);
252 mapping = cbfs_map(TEST_DATA_1_FILENAME, NULL);
253 assert_null(mapping);
254 } else {
255 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size);
256 assert_non_null(mapping);
257 assert_int_equal(TEST_DATA_1_SIZE, size);
258 assert_memory_equal(test_data_1, mapping, size);
259 cbfs_unmap(mapping);
263 int main(void)
265 const struct CMUnitTest tests[] = {
266 cmocka_unit_test_setup(test_cbfs_map_no_hash, setup_test_cbfs),
267 cmocka_unit_test_setup(test_cbfs_map_valid_hash, setup_test_cbfs),
268 cmocka_unit_test_setup(test_cbfs_map_valid_hash_with_lz4, setup_test_cbfs),
269 cmocka_unit_test_setup(test_cbfs_map_invalid_hash, setup_test_cbfs),
272 return lp_run_group_tests(tests, NULL, NULL);