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