test_nvs.c 26 KB

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