1 /*
2  * Copyright (c) 2017 Nordic Semiconductor ASA
3  * Copyright (c) 2020 Gerson Fernando Budke <nandojve@gmail.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/ztest.h>
9 #include <zephyr/storage/flash_map.h>
10 #include <zephyr/dfu/flash_img.h>
11 
12 #define SLOT0_PARTITION		slot0_partition
13 #define SLOT1_PARTITION		slot1_partition
14 
15 #define SLOT0_PARTITION_ID	FIXED_PARTITION_ID(SLOT0_PARTITION)
16 
17 #define SLOT1_PARTITION_ID	FIXED_PARTITION_ID(SLOT1_PARTITION)
18 
ZTEST(img_util,test_init_id)19 ZTEST(img_util, test_init_id)
20 {
21 	struct flash_img_context ctx_no_id;
22 	struct flash_img_context ctx_id;
23 	int ret;
24 
25 	ret = flash_img_init(&ctx_no_id);
26 	zassert_true(ret == 0, "Flash img init");
27 
28 	ret = flash_img_init_id(&ctx_id, SLOT1_PARTITION_ID);
29 	zassert_true(ret == 0, "Flash img init id");
30 
31 	/* Verify that the default partition ID is IMAGE_1 */
32 	zassert_equal(ctx_id.flash_area, ctx_no_id.flash_area,
33 		      "Default partition ID is incorrect");
34 
35 	/* Note: IMAGE_0, not IMAGE_1 as above */
36 	ret = flash_img_init_id(&ctx_id, SLOT0_PARTITION_ID);
37 	zassert_true(ret == 0, "Flash img init id");
38 
39 	zassert_equal(ctx_id.flash_area->fa_id, SLOT0_PARTITION_ID,
40 		      "Partition ID is not set correctly");
41 }
42 
ZTEST(img_util,test_collecting)43 ZTEST(img_util, test_collecting)
44 {
45 	const struct flash_area *fa;
46 	struct flash_img_context ctx;
47 	uint32_t i, j;
48 	uint8_t data[5], temp, k;
49 	int ret;
50 
51 	ret = flash_img_init(&ctx);
52 	zassert_true(ret == 0, "Flash img init");
53 
54 #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
55 	uint8_t erase_buf[8];
56 	(void)memset(erase_buf, 0xff, sizeof(erase_buf));
57 
58 	ret = flash_area_open(SLOT1_PARTITION_ID, &fa);
59 	if (ret) {
60 		printf("Flash driver was not found!\n");
61 		return;
62 	}
63 
64 	/* ensure image payload area dirt */
65 	for (i = 0U; i < 300 * sizeof(data) / sizeof(erase_buf); i++) {
66 		ret = flash_area_write(fa, i * sizeof(erase_buf), erase_buf,
67 				       sizeof(erase_buf));
68 		zassert_true(ret == 0, "Flash write failure (%d)", ret);
69 	}
70 
71 	/* ensure that the last page dirt */
72 	ret = flash_area_write(fa, fa->fa_size - sizeof(erase_buf), erase_buf,
73 			       sizeof(erase_buf));
74 	zassert_true(ret == 0, "Flash write failure (%d)", ret);
75 #else
76 	ret = flash_area_flatten(ctx.flash_area, 0, ctx.flash_area->fa_size);
77 	zassert_true(ret == 0, "Flash erase failure (%d)", ret);
78 #endif
79 
80 	zassert(flash_img_bytes_written(&ctx) == 0, "pass", "fail");
81 
82 	k = 0U;
83 	for (i = 0U; i < 300; i++) {
84 		for (j = 0U; j < ARRAY_SIZE(data); j++) {
85 			data[j] = k++;
86 		}
87 		ret = flash_img_buffered_write(&ctx, data, sizeof(data), false);
88 		zassert_true(ret == 0, "image collection fail: %d\n", ret);
89 	}
90 
91 	zassert(flash_img_buffered_write(&ctx, data, 0, true) == 0, "pass",
92 					 "fail");
93 
94 
95 	ret = flash_area_open(SLOT1_PARTITION_ID, &fa);
96 	if (ret) {
97 		printf("Flash driver was not found!\n");
98 		return;
99 	}
100 
101 	k = 0U;
102 	for (i = 0U; i < 300 * sizeof(data); i++) {
103 		zassert(flash_area_read(fa, i, &temp, 1) == 0, "pass", "fail");
104 		zassert(temp == k, "pass", "fail");
105 		k++;
106 	}
107 
108 #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
109 	uint8_t buf[sizeof(erase_buf)];
110 
111 	ret = flash_area_read(fa, fa->fa_size - sizeof(buf), buf, sizeof(buf));
112 	zassert_true(ret == 0, "Flash read failure (%d)", ret);
113 	zassert_true(memcmp(erase_buf, buf, sizeof(buf)) == 0,
114 		     "Image trailer was not cleared");
115 #endif
116 }
117 
ZTEST(img_util,test_check_flash)118 ZTEST(img_util, test_check_flash)
119 {
120 	/* echo $'0123456789abcdef\nfedcba9876543201' > tst.sha
121 	 * hexdump tst.sha
122 	 */
123 	uint8_t tst_vec[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
124 			      0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
125 			      0x0a, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x39,
126 			      0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
127 			      0x30, 0x0a };
128 	/* sha256sum tst.sha */
129 	uint8_t tst_sha[] = { 0xc6, 0xb6, 0x7c, 0x46, 0xe7, 0x2e, 0x14, 0x17,
130 			      0x49, 0xa4, 0xd2, 0xf1, 0x38, 0x58, 0xb2, 0xa7,
131 			      0x54, 0xaf, 0x6d, 0x39, 0x50, 0x6b, 0xd5, 0x41,
132 			      0x90, 0xf6, 0x18, 0x1a, 0xe0, 0xc2, 0x7f, 0x98 };
133 
134 	struct flash_img_check fic = { NULL, 0 };
135 	struct flash_img_context ctx;
136 	int ret;
137 
138 	ret = flash_img_init_id(&ctx, SLOT1_PARTITION_ID);
139 	zassert_true(ret == 0, "Flash img init 1");
140 	ret = flash_area_flatten(ctx.flash_area, 0, ctx.flash_area->fa_size);
141 	zassert_true(ret == 0, "Flash erase failure (%d)\n", ret);
142 	ret = flash_img_buffered_write(&ctx, tst_vec, sizeof(tst_vec), true);
143 	zassert_true(ret == 0, "Flash img buffered write\n");
144 
145 	ret = flash_img_check(NULL, NULL, 0);
146 	zassert_true(ret == -EINVAL, "Flash img check params 1, 2\n");
147 	ret = flash_img_check(NULL, &fic, 0);
148 	zassert_true(ret == -EINVAL, "Flash img check params 2\n");
149 	ret = flash_img_check(&ctx, NULL, 0);
150 	zassert_true(ret == -EINVAL, "Flash img check params 1\n");
151 
152 	ret = flash_img_check(&ctx, &fic, SLOT1_PARTITION_ID);
153 	zassert_true(ret == -EINVAL, "Flash img check fic match\n");
154 	fic.match = tst_sha;
155 	ret = flash_img_check(&ctx, &fic, SLOT1_PARTITION_ID);
156 	zassert_true(ret == -EINVAL, "Flash img check fic len\n");
157 	fic.clen = sizeof(tst_vec);
158 
159 	ret = flash_img_check(&ctx, &fic, SLOT1_PARTITION_ID);
160 	zassert_true(ret == 0, "Flash img check\n");
161 	tst_sha[0] = 0x00;
162 	ret = flash_img_check(&ctx, &fic, SLOT1_PARTITION_ID);
163 	zassert_false(ret == 0, "Flash img check wrong sha\n");
164 
165 	flash_area_close(ctx.flash_area);
166 }
167 
168 ZTEST_SUITE(img_util, NULL, NULL, NULL, NULL, NULL);
169