1 #include <stdio.h>
2 #include <ctype.h>
3 #include <errno.h>
4 #include <stdlib.h>
5 #include <time.h>
6 #include "unity.h"
7 #include "nvs.h"
8 #include "nvs_flash.h"
9 #include "esp_partition.h"
10 #include "esp_flash_encrypt.h"
11 #include "esp_log.h"
12 #include <string.h>
13 #include "esp_system.h"
14 
15 #ifdef CONFIG_NVS_ENCRYPTION
16 #include "mbedtls/aes.h"
17 #endif
18 
19 static const char* TAG = "test_nvs";
20 
21 TEST_CASE("Partition name no longer than 16 characters", "[nvs]")
22 {
23     const char *TOO_LONG_NAME = "0123456789abcdefg";
24 
25     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, nvs_flash_init_partition(TOO_LONG_NAME));
26 
27     nvs_flash_deinit_partition(TOO_LONG_NAME); // just in case
28 }
29 
30 TEST_CASE("flash erase deinitializes initialized partition", "[nvs]")
31 {
32     nvs_handle_t handle;
33     esp_err_t err = nvs_flash_init();
34     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
35         nvs_flash_erase();
36         err = nvs_flash_init();
37     }
38     TEST_ESP_OK( err );
39 
40     TEST_ESP_OK(nvs_flash_init());
41     TEST_ESP_OK(nvs_open("uninit_ns", NVS_READWRITE, &handle));
42     nvs_close(handle);
43     TEST_ESP_OK(nvs_flash_erase());
44 
45     // exptected: no partition is initialized since nvs_flash_erase() deinitialized the partition again
46     TEST_ESP_ERR(ESP_ERR_NVS_NOT_INITIALIZED, nvs_open("uninit_ns", NVS_READWRITE, &handle));
47 
48     // just to be sure it's deinitialized in case of error and not affecting other tests
49     nvs_flash_deinit();
50 }
51 
52 // test could have different output on host tests
53 TEST_CASE("nvs deinit with open handle", "[nvs]")
54 {
55     nvs_handle_t handle_1;
56     esp_err_t err = nvs_flash_init();
57     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
58         ESP_LOGW(TAG, "nvs_flash_init failed (0x%x), erasing partition and retrying", err);
59         ESP_ERROR_CHECK(nvs_flash_erase());
60         err = nvs_flash_init();
61     }
62     ESP_ERROR_CHECK( err );
63 
64     TEST_ESP_OK(nvs_open("deinit_ns", NVS_READWRITE, &handle_1));
65     nvs_flash_deinit();
66 }
67 
68 TEST_CASE("various nvs tests", "[nvs]")
69 {
70     nvs_handle_t handle_1;
71     esp_err_t err = nvs_flash_init();
72     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
73         ESP_LOGW(TAG, "nvs_flash_init failed (0x%x), erasing partition and retrying", err);
74         ESP_ERROR_CHECK(nvs_flash_erase());
75         err = nvs_flash_init();
76     }
77     ESP_ERROR_CHECK( err );
78 
79     TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, nvs_open("test_namespace1", NVS_READONLY, &handle_1));
80 
81     TEST_ESP_ERR(ESP_ERR_NVS_INVALID_HANDLE, nvs_set_i32(handle_1, "foo", 0x12345678));
82     nvs_close(handle_1);
83 
84     TEST_ESP_OK(nvs_open("test_namespace2", NVS_READWRITE, &handle_1));
85     TEST_ESP_OK(nvs_erase_all(handle_1));
86     TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678));
87     TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789));
88 
89     nvs_handle_t handle_2;
90     TEST_ESP_OK(nvs_open("test_namespace3", NVS_READWRITE, &handle_2));
91     TEST_ESP_OK(nvs_erase_all(handle_2));
92     TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a));
93     const char* str = "value 0123456789abcdef0123456789abcdef";
94     TEST_ESP_OK(nvs_set_str(handle_2, "key", str));
95 
96     int32_t v1;
97     TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1));
98     TEST_ASSERT_EQUAL_INT32(0x23456789, v1);
99 
100     int32_t v2;
101     TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2));
102     TEST_ASSERT_EQUAL_INT32(0x3456789a, v2);
103 
104     char buf[strlen(str) + 1];
105     size_t buf_len = sizeof(buf);
106 
107     TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
108 
109     TEST_ASSERT_EQUAL_INT32(0, strcmp(buf, str));
110 
111     nvs_close(handle_1);
112 
113     // check that deinit does not leak memory if some handles are still open
114     nvs_flash_deinit();
115 
116     nvs_close(handle_2);
117 }
118 
119 TEST_CASE("calculate used and free space", "[nvs]")
120 {
121     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, nvs_get_stats(NULL, NULL));
122     nvs_stats_t stat1;
123     nvs_stats_t stat2;
124     TEST_ESP_ERR(ESP_ERR_NVS_NOT_INITIALIZED, nvs_get_stats(NULL, &stat1));
125     TEST_ASSERT_TRUE(stat1.free_entries == 0);
126     TEST_ASSERT_TRUE(stat1.namespace_count == 0);
127     TEST_ASSERT_TRUE(stat1.total_entries == 0);
128     TEST_ASSERT_TRUE(stat1.used_entries == 0);
129 
130     nvs_handle_t handle = 0;
131     size_t h_count_entries;
132     TEST_ESP_ERR(ESP_ERR_NVS_INVALID_HANDLE, nvs_get_used_entry_count(handle, &h_count_entries));
133     TEST_ASSERT_TRUE(h_count_entries == 0);
134 
135     esp_err_t err = nvs_flash_init();
136     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
137         ESP_LOGW(TAG, "nvs_flash_init failed (0x%x), erasing partition and retrying", err);
138         const esp_partition_t* nvs_partition = esp_partition_find_first(
139                 ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
140         assert(nvs_partition && "partition table must have an NVS partition");
141         ESP_ERROR_CHECK(nvs_flash_erase());
142         err = nvs_flash_init();
143     }
144     ESP_ERROR_CHECK( err );
145 
146     // erase if have any namespace
147     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
148     if(stat1.namespace_count != 0) {
149         TEST_ESP_OK(nvs_flash_deinit());
150         TEST_ESP_OK(nvs_flash_erase());
151         TEST_ESP_OK(nvs_flash_init());
152     }
153 
154     // after erase. empty partition
155     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
156     TEST_ASSERT_TRUE(stat1.free_entries != 0);
157     TEST_ASSERT_TRUE(stat1.namespace_count == 0);
158     TEST_ASSERT_TRUE(stat1.total_entries != 0);
159     TEST_ASSERT_TRUE(stat1.used_entries == 0);
160 
161     // create namespace test_k1
162     nvs_handle_t handle_1;
163     TEST_ESP_OK(nvs_open("test_k1", NVS_READWRITE, &handle_1));
164     TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
165     TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
166     TEST_ASSERT_TRUE(stat2.namespace_count == 1);
167     TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
168     TEST_ASSERT_TRUE(stat2.used_entries == 1);
169 
170     // create pair key-value com
171     TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x12345678));
172     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
173     TEST_ASSERT_TRUE(stat1.free_entries + 1 == stat2.free_entries);
174     TEST_ASSERT_TRUE(stat1.namespace_count == 1);
175     TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
176     TEST_ASSERT_TRUE(stat1.used_entries == 2);
177 
178     // change value in com
179     TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x01234567));
180     TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
181     TEST_ASSERT_TRUE(stat2.free_entries == stat1.free_entries);
182     TEST_ASSERT_TRUE(stat2.namespace_count == 1);
183     TEST_ASSERT_TRUE(stat2.total_entries != 0);
184     TEST_ASSERT_TRUE(stat2.used_entries == 2);
185 
186     // create pair key-value ru
187     TEST_ESP_OK(nvs_set_i32(handle_1, "ru", 0x00FF00FF));
188     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
189     TEST_ASSERT_TRUE(stat1.free_entries + 1 == stat2.free_entries);
190     TEST_ASSERT_TRUE(stat1.namespace_count == 1);
191     TEST_ASSERT_TRUE(stat1.total_entries != 0);
192     TEST_ASSERT_TRUE(stat1.used_entries == 3);
193 
194     // amount valid pair in namespace 1
195     size_t h1_count_entries;
196     TEST_ESP_OK(nvs_get_used_entry_count(handle_1, &h1_count_entries));
197     TEST_ASSERT_TRUE(h1_count_entries == 2);
198 
199     nvs_handle_t handle_2;
200     // create namespace test_k2
201     TEST_ESP_OK(nvs_open("test_k2", NVS_READWRITE, &handle_2));
202     TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
203     TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
204     TEST_ASSERT_TRUE(stat2.namespace_count == 2);
205     TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
206     TEST_ASSERT_TRUE(stat2.used_entries == 4);
207 
208     // create pair key-value
209     TEST_ESP_OK(nvs_set_i32(handle_2, "su1", 0x00000001));
210     TEST_ESP_OK(nvs_set_i32(handle_2, "su2", 0x00000002));
211     TEST_ESP_OK(nvs_set_i32(handle_2, "sus", 0x00000003));
212     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
213     TEST_ASSERT_TRUE(stat1.free_entries + 3 == stat2.free_entries);
214     TEST_ASSERT_TRUE(stat1.namespace_count == 2);
215     TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
216     TEST_ASSERT_TRUE(stat1.used_entries == 7);
217 
218     TEST_ASSERT_TRUE(stat1.total_entries == (stat1.used_entries + stat1.free_entries));
219 
220     // amount valid pair in namespace 2
221     size_t h2_count_entries;
222     TEST_ESP_OK(nvs_get_used_entry_count(handle_2, &h2_count_entries));
223     TEST_ASSERT_TRUE(h2_count_entries == 3);
224 
225     TEST_ASSERT_TRUE(stat1.used_entries == (h1_count_entries + h2_count_entries + stat1.namespace_count));
226 
227     nvs_close(handle_1);
228     nvs_close(handle_2);
229 
230     size_t temp = h2_count_entries;
231     TEST_ESP_ERR(ESP_ERR_NVS_INVALID_HANDLE, nvs_get_used_entry_count(handle_1, &h2_count_entries));
232     TEST_ASSERT_TRUE(h2_count_entries == 0);
233     h2_count_entries = temp;
234     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, nvs_get_used_entry_count(handle_1, NULL));
235 
236     nvs_handle_t handle_3;
237     // create namespace test_k3
238     TEST_ESP_OK(nvs_open("test_k3", NVS_READWRITE, &handle_3));
239     TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
240     TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
241     TEST_ASSERT_TRUE(stat2.namespace_count == 3);
242     TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
243     TEST_ASSERT_TRUE(stat2.used_entries == 8);
244 
245     // create pair blobs
246     uint32_t blob[12];
247     TEST_ESP_OK(nvs_set_blob(handle_3, "bl1", &blob, sizeof(blob)));
248     TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
249     TEST_ASSERT_TRUE(stat1.free_entries + 4 == stat2.free_entries);
250     TEST_ASSERT_TRUE(stat1.namespace_count == 3);
251     TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
252     TEST_ASSERT_TRUE(stat1.used_entries == 12);
253 
254     // amount valid pair in namespace 2
255     size_t h3_count_entries;
256     TEST_ESP_OK(nvs_get_used_entry_count(handle_3, &h3_count_entries));
257     TEST_ASSERT_TRUE(h3_count_entries == 4);
258 
259     TEST_ASSERT_TRUE(stat1.used_entries == (h1_count_entries + h2_count_entries + h3_count_entries + stat1.namespace_count));
260 
261     nvs_close(handle_3);
262 
263     TEST_ESP_OK(nvs_flash_deinit());
264     TEST_ESP_OK(nvs_flash_erase());
265 }
266 
267 TEST_CASE("check for memory leaks in nvs_set_blob", "[nvs]")
268 {
269     esp_err_t err = nvs_flash_init();
270     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
271         ESP_ERROR_CHECK(nvs_flash_erase());
272         err = nvs_flash_init();
273     }
274     TEST_ESP_OK( err );
275 
276     for (int i = 0; i < 500; ++i) {
277         nvs_handle_t my_handle;
278         uint8_t key[20] = {0};
279 
280         TEST_ESP_OK( nvs_open("leak_check_ns", NVS_READWRITE, &my_handle) );
281         TEST_ESP_OK( nvs_set_blob(my_handle, "key", key, sizeof(key)) );
282         TEST_ESP_OK( nvs_commit(my_handle) );
283         nvs_close(my_handle);
284         printf("%d\n", esp_get_free_heap_size());
285     }
286 
287     nvs_flash_deinit();
288     printf("%d\n", esp_get_free_heap_size());
289     /* heap leaks will be checked in unity_platform.c */
290 }
291 
292 #ifdef CONFIG_NVS_ENCRYPTION
293 TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs]")
294 {
295     uint8_t eky_hex[2 * NVS_KEY_SIZE] = { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
296         0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
297         0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
298         0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
299         /* Tweak key below*/
300         0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
301         0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
302         0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
303         0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 };
304 
305     uint8_t ba_hex[16] = { 0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,
306         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
307 
308     uint8_t ptxt_hex[32] = { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
309         0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
310         0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
311         0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 };
312 
313 
314     uint8_t ctxt_hex[32] = { 0xe6,0x22,0x33,0x4f,0x18,0x4b,0xbc,0xe1,
315         0x29,0xa2,0x5b,0x2a,0xc7,0x6b,0x3d,0x92,
316         0xab,0xf9,0x8e,0x22,0xdf,0x5b,0xdd,0x15,
317         0xaf,0x47,0x1f,0x3d,0xb8,0x94,0x6a,0x85 };
318 
319     mbedtls_aes_xts_context ectx[1];
320     mbedtls_aes_xts_context dctx[1];
321 
322     mbedtls_aes_xts_init(ectx);
323     mbedtls_aes_xts_init(dctx);
324 
325     TEST_ASSERT_TRUE(!mbedtls_aes_xts_setkey_enc(ectx, eky_hex, 2 * NVS_KEY_SIZE * 8));
326     TEST_ASSERT_TRUE(!mbedtls_aes_xts_setkey_enc(dctx, eky_hex, 2 * NVS_KEY_SIZE * 8));
327 
328     TEST_ASSERT_TRUE(!mbedtls_aes_crypt_xts(ectx, MBEDTLS_AES_ENCRYPT, 32, ba_hex, ptxt_hex, ptxt_hex));
329 
330     TEST_ASSERT_TRUE(!memcmp(ptxt_hex, ctxt_hex, 32));
331 }
332 
333 TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]")
334 {
335     nvs_sec_cfg_t cfg, cfg2;
336 
337     const esp_partition_t* key_part = esp_partition_find_first(
338             ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL);
339 
340     if (!esp_flash_encryption_enabled()) {
341         TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_key partition related tests");
342     }
343 
344     TEST_ESP_OK(esp_partition_erase_range(key_part, 0, key_part->size));
345     TEST_ESP_ERR(ESP_ERR_NVS_KEYS_NOT_INITIALIZED, nvs_flash_read_security_cfg(key_part, &cfg));
346 
347     TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg));
348 
349     TEST_ESP_OK(nvs_flash_read_security_cfg(key_part, &cfg2));
350 
351     TEST_ASSERT_TRUE(!memcmp(&cfg, &cfg2, sizeof(nvs_sec_cfg_t)));
352 }
353 
354 
355 TEST_CASE("test nvs apis with encryption enabled", "[nvs]")
356 {
357     if (!esp_flash_encryption_enabled()) {
358         TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled");
359     }
360     const esp_partition_t* key_part = esp_partition_find_first(
361             ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL);
362 
363     assert(key_part && "partition table must have an NVS Key partition");
364 
365     const esp_partition_t* nvs_partition = esp_partition_find_first(
366             ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
367     assert(nvs_partition && "partition table must have an NVS partition");
368 
369     ESP_ERROR_CHECK( esp_partition_erase_range(key_part, 0, key_part->size) );
370 
371     bool done = false;
372 
373     do {
374         ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) );
375 
376         nvs_sec_cfg_t cfg;
377         esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg);
378 
379         if(err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) {
380             uint8_t value[4096] = {[0 ... 4095] = 0xff};
381             TEST_ESP_OK(esp_partition_write(key_part, 0, value, sizeof(value)));
382 
383             TEST_ESP_ERR(ESP_ERR_NVS_KEYS_NOT_INITIALIZED, nvs_flash_read_security_cfg(key_part, &cfg));
384 
385             TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg));
386         } else {
387             /* Second time key_partition exists already*/
388             ESP_ERROR_CHECK(err);
389             done = true;
390         }
391         TEST_ESP_OK(nvs_flash_secure_init(&cfg));
392 
393         nvs_handle_t handle_1;
394 
395         TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, nvs_open("namespace1", NVS_READONLY, &handle_1));
396 
397 
398         TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1));
399 
400         TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678));
401         TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789));
402 
403         nvs_handle_t handle_2;
404         TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2));
405         TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a));
406         const char* str = "value 0123456789abcdef0123456789abcdef";
407         TEST_ESP_OK(nvs_set_str(handle_2, "key", str));
408 
409         int32_t v1;
410         TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1));
411         TEST_ASSERT_TRUE(0x23456789 == v1);
412 
413         int32_t v2;
414         TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2));
415         TEST_ASSERT_TRUE(0x3456789a == v2);
416 
417         char buf[strlen(str) + 1];
418         size_t buf_len = sizeof(buf);
419 
420         size_t buf_len_needed;
421         TEST_ESP_OK(nvs_get_str(handle_2, "key", NULL, &buf_len_needed));
422         TEST_ASSERT_TRUE(buf_len_needed == buf_len);
423 
424         size_t buf_len_short = buf_len - 1;
425         TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short));
426         TEST_ASSERT_TRUE(buf_len_short == buf_len);
427 
428         size_t buf_len_long = buf_len + 1;
429         TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long));
430         TEST_ASSERT_TRUE(buf_len_long == buf_len);
431 
432         TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
433 
434         TEST_ASSERT_TRUE(0 == strcmp(buf, str));
435 
436         nvs_close(handle_1);
437         nvs_close(handle_2);
438 
439         TEST_ESP_OK(nvs_flash_deinit());
440     } while(!done);
441 }
442 
443 TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]")
444 {
445 
446     if (!esp_flash_encryption_enabled()) {
447         TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled");
448     }
449 
450     nvs_handle_t handle;
451     nvs_sec_cfg_t xts_cfg;
452 
453     extern const char nvs_key_start[] asm("_binary_encryption_keys_bin_start");
454     extern const char nvs_key_end[]   asm("_binary_encryption_keys_bin_end");
455 
456     extern const char nvs_data_start[] asm("_binary_partition_encrypted_bin_start");
457 
458     extern const char sample_bin_start[] asm("_binary_sample_bin_start");
459 
460     const esp_partition_t* key_part = esp_partition_find_first(
461             ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL);
462 
463     const esp_partition_t* nvs_part = esp_partition_find_first(
464             ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
465 
466     assert(key_part && "partition table must have a KEY partition");
467     TEST_ASSERT_TRUE((nvs_key_end - nvs_key_start - 1) == SPI_FLASH_SEC_SIZE);
468 
469     assert(nvs_part && "partition table must have an NVS partition");
470     printf("\n nvs_part size:%d\n", nvs_part->size);
471 
472     ESP_ERROR_CHECK(esp_partition_erase_range(key_part, 0, key_part->size));
473     ESP_ERROR_CHECK( esp_partition_erase_range(nvs_part, 0, nvs_part->size) );
474 
475     for (int i = 0; i < key_part->size; i+= SPI_FLASH_SEC_SIZE) {
476         ESP_ERROR_CHECK( esp_partition_write(key_part, i, nvs_key_start + i, SPI_FLASH_SEC_SIZE) );
477     }
478 
479     for (int i = 0; i < nvs_part->size; i+= SPI_FLASH_SEC_SIZE) {
480         ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_start + i, SPI_FLASH_SEC_SIZE) );
481     }
482 
483     esp_err_t err = nvs_flash_read_security_cfg(key_part, &xts_cfg);
484     ESP_ERROR_CHECK(err);
485 
486     TEST_ESP_OK(nvs_flash_secure_init(&xts_cfg));
487 
488     TEST_ESP_OK(nvs_open("dummyNamespace", NVS_READONLY, &handle));
489     uint8_t u8v;
490     TEST_ESP_OK( nvs_get_u8(handle, "dummyU8Key", &u8v));
491     TEST_ASSERT_TRUE(u8v == 127);
492     int8_t i8v;
493     TEST_ESP_OK( nvs_get_i8(handle, "dummyI8Key", &i8v));
494     TEST_ASSERT_TRUE(i8v == -128);
495     uint16_t u16v;
496     TEST_ESP_OK( nvs_get_u16(handle, "dummyU16Key", &u16v));
497     TEST_ASSERT_TRUE(u16v == 32768);
498     uint32_t u32v;
499     TEST_ESP_OK( nvs_get_u32(handle, "dummyU32Key", &u32v));
500     TEST_ASSERT_TRUE(u32v == 4294967295);
501     int32_t i32v;
502     TEST_ESP_OK( nvs_get_i32(handle, "dummyI32Key", &i32v));
503     TEST_ASSERT_TRUE(i32v == -2147483648);
504 
505     char buf[64] = {0};
506     size_t buflen = 64;
507     TEST_ESP_OK( nvs_get_str(handle, "dummyStringKey", buf, &buflen));
508     TEST_ASSERT_TRUE(strncmp(buf, "0A:0B:0C:0D:0E:0F", buflen) == 0);
509 
510     uint8_t hexdata[] = {0x01, 0x02, 0x03, 0xab, 0xcd, 0xef};
511     buflen = 64;
512     TEST_ESP_OK( nvs_get_blob(handle, "dummyHex2BinKey", buf, &buflen));
513     TEST_ASSERT_TRUE(memcmp(buf, hexdata, buflen) == 0);
514 
515     uint8_t base64data[] = {'1', '2', '3', 'a', 'b', 'c'};
516     buflen = 64;
517     TEST_ESP_OK( nvs_get_blob(handle, "dummyBase64Key", buf, &buflen));
518     TEST_ASSERT_TRUE(memcmp(buf, base64data, buflen) == 0);
519 
520     uint8_t hexfiledata[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
521     buflen = 64;
522     TEST_ESP_OK( nvs_get_blob(handle, "hexFileKey", buf, &buflen));
523     TEST_ASSERT_TRUE(memcmp(buf, hexfiledata, buflen) == 0);
524 
525     uint8_t base64filedata[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xab, 0xcd, 0xef};
526     buflen = 64;
527     TEST_ESP_OK( nvs_get_blob(handle, "base64FileKey", buf, &buflen));
528     TEST_ASSERT_TRUE(memcmp(buf, base64filedata, buflen) == 0);
529 
530     uint8_t strfiledata[64] = "abcdefghijklmnopqrstuvwxyz\0";
531     buflen = 64;
532     TEST_ESP_OK( nvs_get_str(handle, "stringFileKey", buf, &buflen));
533     TEST_ASSERT_TRUE(memcmp(buf, strfiledata, buflen) == 0);
534 
535     char bin_data[5120];
536     size_t bin_len = sizeof(bin_data);
537     TEST_ESP_OK( nvs_get_blob(handle, "binFileKey", bin_data, &bin_len));
538     TEST_ASSERT_TRUE(memcmp(bin_data, sample_bin_start, bin_len) == 0);
539 
540     nvs_close(handle);
541     TEST_ESP_OK(nvs_flash_deinit());
542 
543 }
544 #endif
545