1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstdlib>
17 #include <gtest/gtest.h>
18 #include "fs_hvb.h"
19 #include "init_utils.h"
20 #include "fs_manager/ext4_super_block.h"
21 #include "fs_manager/erofs_super_block.h"
22 #include "securec.h"
23
24 using namespace std;
25 using namespace testing::ext;
26
27 namespace init_ut {
28 class FsHvbUnitTest : public testing::Test {
29 public:
SetUpTestCase(void)30 static void SetUpTestCase(void) {};
TearDownTestCase(void)31 static void TearDownTestCase(void) {};
32 };
33
CreateTestFile(const char * fileName,const char * data)34 void CreateTestFile(const char *fileName, const char *data)
35 {
36 CheckAndCreateDir(fileName);
37 printf("PrepareParamTestData for %s\n", fileName);
38 FILE *tmpFile = fopen(fileName, "a+");
39 if (tmpFile != nullptr) {
40 fprintf(tmpFile, "%s", data);
41 (void)fflush(tmpFile);
42 fclose(tmpFile);
43 }
44 }
45
46 HWTEST_F(FsHvbUnitTest, Init_FsHvbInit_001, TestSize.Level0)
47 {
48 const char *cmdLine;
49 int ret = FsHvbInit(MAIN_HVB);
50 EXPECT_EQ(ret, HVB_ERROR_INVALID_ARGUMENT);
51
52 setenv("VERIFY_VALUE", "PartFail", 1);
53 ret = FsHvbInit(MAIN_HVB);
54 EXPECT_EQ(ret, HVB_ERROR_UNSUPPORTED_VERSION);
55
56 setenv("VERIFY_VALUE", "Succeed", 1);
57 ret = FsHvbInit(MAIN_HVB);
58 EXPECT_EQ(ret, -1);
59
60 cmdLine = "ohos.boot.hvb.hash_algo=test "; // HVB_CMDLINE_HASH_ALG
61 CreateTestFile(BOOT_CMD_LINE, cmdLine);
62 ret = FsHvbInit(MAIN_HVB);
63 EXPECT_EQ(ret, -1);
64
65 cmdLine = "ohos.boot.hvb.digest=1 "; // HVB_CMDLINE_CERT_DIGEST
66 CreateTestFile(BOOT_CMD_LINE, cmdLine);
67 ret = FsHvbInit(MAIN_HVB);
68 EXPECT_EQ(ret, -1);
69 remove(BOOT_CMD_LINE);
70
71 cmdLine = "ohos.boot.hvb.hash_algo=test ";
72 CreateTestFile(BOOT_CMD_LINE, cmdLine);
73 cmdLine = "ohos.boot.hvb.digest=1234 ";
74 CreateTestFile(BOOT_CMD_LINE, cmdLine);
75 ret = FsHvbInit(MAIN_HVB);
76 EXPECT_EQ(ret, -1);
77 remove(BOOT_CMD_LINE);
78
79 setenv("HASH_VALUE", "InitFail", 1); // sha256
80 cmdLine = "ohos.boot.hvb.hash_algo=sha256 ";
81 CreateTestFile(BOOT_CMD_LINE, cmdLine);
82 cmdLine = "ohos.boot.hvb.digest=01 ";
83 CreateTestFile(BOOT_CMD_LINE, cmdLine);
84 ret = FsHvbInit(MAIN_HVB);
85 EXPECT_EQ(ret, -1);
86
87 setenv("HASH_VALUE", "UpdateFail", 1);
88 ret = FsHvbInit(MAIN_HVB);
89 EXPECT_EQ(ret, -1);
90
91 setenv("HASH_VALUE", "FinalFail", 1);
92 ret = FsHvbInit(MAIN_HVB);
93 EXPECT_EQ(ret, -1);
94
95 setenv("HASH_VALUE", "AllSucceed", 1);
96 ret = FsHvbInit(MAIN_HVB);
97 EXPECT_EQ(ret, 0);
98 remove(BOOT_CMD_LINE);
99 ret = FsHvbFinal(MAIN_HVB); //clear vd
100 EXPECT_EQ(ret, 0);
101 }
102
103 HWTEST_F(FsHvbUnitTest, Init_FsHvbInit_002, TestSize.Level0)
104 {
105 const char *cmdLine;
106 setenv("VERIFY_VALUE", "Succeed", 1);
107 setenv("HASH_VALUE", "InitFail", 1); // sm3
108 cmdLine = "ohos.boot.hvb.hash_algo=sm3 ";
109 CreateTestFile(BOOT_CMD_LINE, cmdLine);
110 cmdLine = "ohos.boot.hvb.digest=01 ";
111 CreateTestFile(BOOT_CMD_LINE, cmdLine);
112 int ret = FsHvbInit(MAIN_HVB);
113 EXPECT_EQ(ret, -1);
114
115 setenv("HASH_VALUE", "UpdateFail", 1);
116 ret = FsHvbInit(MAIN_HVB);
117 EXPECT_EQ(ret, -1);
118
119 setenv("HASH_VALUE", "FinalFail", 1);
120 ret = FsHvbInit(MAIN_HVB);
121 EXPECT_EQ(ret, -1);
122
123 setenv("HASH_VALUE", "AllSucceed", 1);
124 ret = FsHvbInit(MAIN_HVB);
125 EXPECT_EQ(ret, 0);
126
127 remove(BOOT_CMD_LINE);
128 unsetenv("VERIFY_VALUE");
129 unsetenv("HASH_VALUE");
130 }
131
132 HWTEST_F(FsHvbUnitTest, Init_FsHvbSetupHashtree_001, TestSize.Level0)
133 {
134 FstabItem fsItem;
135 char testStr[10] = "testStr";
136 char testDev[] = "/dev/block/platform/xxx/by-name/boot";
137 fsItem.deviceName = (char *)malloc(sizeof(testDev) + 1);
138 memcpy_s(fsItem.deviceName, sizeof(testDev) + 1, &testDev[0], sizeof(testDev));
139 fsItem.mountPoint = &testStr[0];
140 fsItem.fsType = &testStr[0];
141 fsItem.mountOptions = &testStr[0];
142 fsItem.fsManagerFlags = 1;
143 fsItem.next = nullptr;
144
145 int ret = FsHvbSetupHashtree(nullptr);
146 EXPECT_EQ(ret, -1);
147
148 setenv("FSDM_VALUE", "InitFail", 1);
149 ret = FsHvbSetupHashtree(&fsItem);
150 EXPECT_EQ(ret, -1);
151
152 setenv("FSDM_VALUE", "CreateFail", 1);
153 ret = FsHvbSetupHashtree(&fsItem);
154 EXPECT_EQ(ret, -1);
155
156 setenv("FSDM_VALUE", "AllSucceed", 1);
157 ret = FsHvbSetupHashtree(&fsItem);
158 EXPECT_EQ(ret, 0);
159
160 unsetenv("FSDM_VALUE");
161 }
162
163 HWTEST_F(FsHvbUnitTest, Init_FsHvbFinal_001, TestSize.Level0)
164 {
165 int ret = FsHvbFinal(MAIN_HVB);
166 EXPECT_EQ(ret, 0);
167 }
168
169 HWTEST_F(FsHvbUnitTest, Init_FsHvbGetOps_001, TestSize.Level0)
170 {
171 struct hvb_ops *ops = FsHvbGetOps();
172 EXPECT_NE(ops, nullptr);
173 }
174
175 HWTEST_F(FsHvbUnitTest, Init_FsHvbGetValueFromCmdLine_001, TestSize.Level0)
176 {
177 const char *cmdLine;
178 char hashAlg[32] = { 0 };
179
180 int ret = FsHvbGetValueFromCmdLine(nullptr, sizeof(hashAlg), "ohos.boot.hvb.hash_algo");
181 EXPECT_EQ(ret, -1);
182 ret = FsHvbGetValueFromCmdLine(&hashAlg[0], sizeof(hashAlg), nullptr);
183 EXPECT_EQ(ret, -1);
184
185 cmdLine = "ohos.boot.hvb.hash_algo=sha256 ";
186 CreateTestFile(BOOT_CMD_LINE, cmdLine);
187 ret = FsHvbGetValueFromCmdLine(&hashAlg[0], sizeof(hashAlg), "ohos.boot.hvb.hash_algo");
188 EXPECT_EQ(ret, 0);
189 EXPECT_EQ(strcmp(hashAlg, "sha256"), 0);
190
191 remove(BOOT_CMD_LINE);
192 }
193
194 HWTEST_F(FsHvbUnitTest, Init_FsHvbConstructVerityTarget_001, TestSize.Level0)
195 {
196 DmVerityTarget target;
197 const char *devName = "test";
198 struct hvb_cert cert;
199 uint8_t digest = 53;
200 uint8_t salt = 55;
201
202 int ret = FsHvbConstructVerityTarget(nullptr, devName, &cert);
203 EXPECT_EQ(ret, -1);
204 ret = FsHvbConstructVerityTarget(&target, nullptr, &cert);
205 EXPECT_EQ(ret, -1);
206 ret = FsHvbConstructVerityTarget(&target, devName, nullptr);
207 EXPECT_EQ(ret, -1);
208
209 cert.image_len = 512;
210 cert.data_block_size = 0;
211 ret = FsHvbConstructVerityTarget(&target, devName, &cert);
212 EXPECT_EQ(ret, -1);
213 cert.data_block_size = 8;
214 cert.hash_block_size = 0;
215 ret = FsHvbConstructVerityTarget(&target, devName, &cert);
216 EXPECT_EQ(ret, -1);
217
218 cert.hash_block_size = 8;
219 cert.hashtree_offset = 16;
220 cert.hash_algo = 4;
221 ret = FsHvbConstructVerityTarget(&target, devName, &cert);
222 EXPECT_EQ(ret, -1);
223
224 cert.hash_algo = 0;
225 cert.hash_payload.digest = &digest;
226 cert.digest_size = 1;
227 cert.hash_payload.salt = &salt;
228 cert.salt_size = 1;
229 cert.fec_size = 1;
230 cert.fec_num_roots = 1;
231 cert.fec_offset = 8;
232 ret = FsHvbConstructVerityTarget(&target, devName, &cert);
233 EXPECT_EQ(ret, 0);
234
235 cert.hash_algo = 2;
236 ret = FsHvbConstructVerityTarget(&target, devName, &cert);
237 EXPECT_EQ(ret, 0);
238 }
239
240 HWTEST_F(FsHvbUnitTest, Init_FsHvbDestoryVerityTarget_001, TestSize.Level0)
241 {
242 DmVerityTarget target;
243
244 target.paras = static_cast<char *>(calloc(1, 10));
245 EXPECT_NE(target.paras, nullptr);
246 FsHvbDestoryVerityTarget(&target);
247 }
248
249 HWTEST_F(FsHvbUnitTest, Init_VerifyExtHvbImage_001, TestSize.Level0)
250 {
251 const char *cmdLine;
252 const char *devPath = "/dev/block/loop0";
253 char *outPath = nullptr;
254 int ret = VerifyExtHvbImage(devPath, "boot", &outPath);
255 EXPECT_FALSE(ret == 0);
256
257 setenv("VERIFY_VALUE", "Succeed", 1);
258 setenv("HASH_VALUE", "AllSucceed", 1);
259 setenv("FSDM_VALUE", "AllSucceed", 1);
260 cmdLine = "ohos.boot.hvb.ext_rvt=01 "; // HVB_CMDLINE_EXT_CERT_DIGEST
261 CreateTestFile(BOOT_CMD_LINE, cmdLine);
262 ret = VerifyExtHvbImage(devPath, "module_update", &outPath);
263 EXPECT_EQ(ret, -1);
264
265 ret = VerifyExtHvbImage(devPath, "boot", &outPath);
266 EXPECT_EQ(ret, 0);
267
268 remove(BOOT_CMD_LINE);
269 unsetenv("VERIFY_VALUE");
270 unsetenv("HASH_VALUE");
271 unsetenv("FSDM_VALUE");
272 }
273
274 HWTEST_F(FsHvbUnitTest, Init_CheckAndGetExt4Size_001, TestSize.Level0)
275 {
276 ext4_super_block superBlock = {0};
277 uint64_t imageSize;
278
279 bool ret = CheckAndGetExt4Size(nullptr, &imageSize, "boot");
280 EXPECT_FALSE(ret);
281
282 ret = CheckAndGetExt4Size((const char*)&superBlock, &imageSize, "boot");
283 EXPECT_FALSE(ret);
284
285 superBlock.s_magic = EXT4_SUPER_MAGIC;
286 ret = CheckAndGetExt4Size((const char*)&superBlock, &imageSize, "boot");
287 EXPECT_TRUE(ret);
288 }
289
290 HWTEST_F(FsHvbUnitTest, Init_CheckAndGetErofsSize_001, TestSize.Level0)
291 {
292 struct erofs_super_block superBlock = {0};
293 uint64_t imageSize;
294
295 bool ret = CheckAndGetErofsSize(nullptr, &imageSize, "boot");
296 EXPECT_FALSE(ret);
297
298 ret = CheckAndGetErofsSize((const char*)&superBlock, &imageSize, "boot");
299 EXPECT_FALSE(ret);
300
301 superBlock.magic = EROFS_SUPER_MAGIC;
302 ret = CheckAndGetErofsSize((const char*)&superBlock, &imageSize, "boot");
303 EXPECT_TRUE(ret);
304 }
305
306 HWTEST_F(FsHvbUnitTest, Init_CheckAndGetExtheaderSize_001, TestSize.Level0)
307 {
308 uint64_t imageSize;
309 bool ret = CheckAndGetExtheaderSize(-1, 0, &imageSize, "boot");
310 EXPECT_FALSE(ret);
311 }
312
313 HWTEST_F(FsHvbUnitTest, Init_HvbReadFromPartition_001, TestSize.Level0)
314 {
315 struct hvb_ops *ops = FsHvbGetOps();
316 int ret = ops->read_partition(ops, "boot_not_exit", 0, 1, nullptr, nullptr);
317 EXPECT_EQ(ret, HVB_IO_ERROR_IO);
318 void *buf = malloc(1);
319 uint64_t outNumRead;
320 ret = ops->read_partition(ops, "boot_not_exit", 0, 1, buf, &outNumRead);
321 EXPECT_EQ(ret, HVB_IO_ERROR_IO);
322 free(buf);
323 }
324
325 HWTEST_F(FsHvbUnitTest, Init_HvbWriteToPartition_001, TestSize.Level0)
326 {
327 struct hvb_ops *ops = FsHvbGetOps();
328 void *buf = malloc(1);
329 int ret = ops->write_partition(ops, "boot", 0, 1, buf);
330 EXPECT_EQ(ret, HVB_IO_OK);
331 free(buf);
332 }
333
334 HWTEST_F(FsHvbUnitTest, Init_HvbInvaldateKey_001, TestSize.Level0)
335 {
336 struct hvb_ops *ops = FsHvbGetOps();
337 bool outIsTrusted;
338 int ret = ops->valid_rvt_key(ops, nullptr, 0, nullptr, 0, nullptr);
339 EXPECT_EQ(ret, HVB_IO_ERROR_IO);
340 ret = ops->valid_rvt_key(ops, nullptr, 0, nullptr, 0, &outIsTrusted);
341 EXPECT_EQ(ret, HVB_IO_OK);
342 }
343
344 HWTEST_F(FsHvbUnitTest, Init_HvbReadRollbackIdx_001, TestSize.Level0)
345 {
346 struct hvb_ops *ops = FsHvbGetOps();
347 int ret = ops->read_rollback(ops, 0, nullptr);
348 uint64_t outRollbackIndex;
349 EXPECT_EQ(ret, HVB_IO_ERROR_IO);
350 ret = ops->read_rollback(ops, 0, &outRollbackIndex);
351 EXPECT_EQ(ret, HVB_IO_OK);
352 }
353
354 HWTEST_F(FsHvbUnitTest, Init_HvbWriteRollbackIdx_001, TestSize.Level0)
355 {
356 struct hvb_ops *ops = FsHvbGetOps();
357 int ret = ops->write_rollback(ops, 0, 0);
358 EXPECT_EQ(ret, HVB_IO_OK);
359 }
360
361 HWTEST_F(FsHvbUnitTest, Init_HvbReadLockState_001, TestSize.Level0)
362 {
363 struct hvb_ops *ops = FsHvbGetOps();
364 bool locked;
365 const char *cmdLine;
366 int ret = ops->read_lock_state(ops, &locked);
367 EXPECT_EQ(ret, HVB_IO_ERROR_NO_SUCH_VALUE);
368
369 cmdLine = "ohos.boot.hvb.device_state=locked ";
370 CreateTestFile(BOOT_CMD_LINE, cmdLine);
371 ret = ops->read_lock_state(ops, &locked);
372 EXPECT_EQ(ret, HVB_IO_OK);
373 EXPECT_EQ(locked, true);
374 remove(BOOT_CMD_LINE);
375
376 cmdLine = "ohos.boot.hvb.device_state=unlocked ";
377 CreateTestFile(BOOT_CMD_LINE, cmdLine);
378 ret = ops->read_lock_state(ops, &locked);
379 EXPECT_EQ(ret, HVB_IO_OK);
380 EXPECT_EQ(locked, false);
381 remove(BOOT_CMD_LINE);
382
383 cmdLine = "ohos.boot.hvb.device_state=undefined ";
384 CreateTestFile(BOOT_CMD_LINE, cmdLine);
385 ret = ops->read_lock_state(ops, &locked);
386 EXPECT_EQ(ret, HVB_IO_ERROR_NO_SUCH_VALUE);
387 remove(BOOT_CMD_LINE);
388 }
389
390 HWTEST_F(FsHvbUnitTest, Init_HvbGetSizeOfPartition_001, TestSize.Level0)
391 {
392 struct hvb_ops *ops = FsHvbGetOps();
393 int ret = ops->get_partiton_size(ops, "boot", nullptr);
394 uint64_t size;
395 EXPECT_EQ(ret, HVB_IO_ERROR_IO);
396 ret = ops->get_partiton_size(ops, "boot", &size);
397 EXPECT_EQ(ret, HVB_IO_OK);
398 }
399 }