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