test_nvs.c 20 KB

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