diff --git a/components/nvs_flash/src/nvs_api.cpp b/components/nvs_flash/src/nvs_api.cpp index 35462dd338..e993c9637a 100644 --- a/components/nvs_flash/src/nvs_api.cpp +++ b/components/nvs_flash/src/nvs_api.cpp @@ -627,6 +627,16 @@ extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partitio uint8_t eky_raw[NVS_KEY_SIZE], tky_raw[NVS_KEY_SIZE]; uint32_t crc_raw, crc_read, crc_calc; + auto check_if_initialized = [](uint8_t* eky, uint8_t* tky, uint32_t crc) { + uint8_t cnt = 0; + while(cnt < NVS_KEY_SIZE && eky[cnt] == 0xff && tky[cnt] == 0xff) cnt++; + + if(cnt == NVS_KEY_SIZE && crc == 0xffffffff) { + return false; + } + return true; + }; + auto err = spi_flash_read(partition->address, eky_raw, NVS_KEY_SIZE); if(err != ESP_OK) { return err; @@ -642,12 +652,7 @@ extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partitio return err; } - - uint8_t cnt = 0; - - while(cnt < NVS_KEY_SIZE && eky_raw[cnt] == 0xff && tky_raw[cnt] == 0xff) cnt++; - - if(cnt == NVS_KEY_SIZE && crc_raw == 0xffffffff) { + if(!check_if_initialized(eky_raw, tky_raw, crc_raw)) { /* This is an uninitialized key partition*/ return ESP_ERR_NVS_KEYS_NOT_INITIALIZED; } @@ -673,7 +678,11 @@ extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partitio crc_calc = crc32_le(0xffffffff, cfg->eky, NVS_KEY_SIZE); crc_calc = crc32_le(crc_calc, cfg->tky, NVS_KEY_SIZE); - if(crc_calc != crc_read) { + if(crc_calc != crc_read) { + if(!check_if_initialized(cfg->eky, cfg->tky, crc_read)) { + /* This is an uninitialized key partition*/ + return ESP_ERR_NVS_KEYS_NOT_INITIALIZED; + } return ESP_ERR_NVS_CORRUPT_KEY_PART; } diff --git a/components/nvs_flash/test/test_nvs.c b/components/nvs_flash/test/test_nvs.c index 2e10ebde20..a8667dc016 100644 --- a/components/nvs_flash/test/test_nvs.c +++ b/components/nvs_flash/test/test_nvs.c @@ -310,77 +310,90 @@ TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]") TEST_CASE("test nvs apis with encryption enabled", "[nvs]") { - - if (!esp_flash_encryption_enabled()) { TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled"); } const esp_partition_t* key_part = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); + + assert(key_part && "partition table must have an NVS Key partition"); const esp_partition_t* nvs_partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); assert(nvs_partition && "partition table must have an NVS partition"); - ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) ); + ESP_ERROR_CHECK( esp_partition_erase_range(key_part, 0, key_part->size) ); - nvs_sec_cfg_t cfg; - esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg); + bool done = false; - if(err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) { - TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg)); - } else { - ESP_ERROR_CHECK(err); - } - TEST_ESP_OK(nvs_flash_secure_init(&cfg)); - - nvs_handle handle_1; + do { + ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) ); - TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND); + nvs_sec_cfg_t cfg; + esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg); + + if(err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) { + uint8_t value[4096] = {[0 ... 4095] = 0xff}; + TEST_ESP_OK(esp_partition_write(key_part, 0, value, sizeof(value))); + + TEST_ESP_ERR(nvs_flash_read_security_cfg(key_part, &cfg), ESP_ERR_NVS_KEYS_NOT_INITIALIZED); + + TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg)); + } else { + /* Second time key_partition exists already*/ + ESP_ERROR_CHECK(err); + done = true; + } + TEST_ESP_OK(nvs_flash_secure_init(&cfg)); + + nvs_handle handle_1; + + TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND); - TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1)); + TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1)); - TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678)); - TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789)); + TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678)); + TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789)); - nvs_handle handle_2; - TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2)); - TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a)); - const char* str = "value 0123456789abcdef0123456789abcdef"; - TEST_ESP_OK(nvs_set_str(handle_2, "key", str)); + nvs_handle handle_2; + TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2)); + TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a)); + const char* str = "value 0123456789abcdef0123456789abcdef"; + TEST_ESP_OK(nvs_set_str(handle_2, "key", str)); - int32_t v1; - TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1)); - TEST_ASSERT_TRUE(0x23456789 == v1); + int32_t v1; + TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1)); + TEST_ASSERT_TRUE(0x23456789 == v1); - int32_t v2; - TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2)); - TEST_ASSERT_TRUE(0x3456789a == v2); + int32_t v2; + TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2)); + TEST_ASSERT_TRUE(0x3456789a == v2); - char buf[strlen(str) + 1]; - size_t buf_len = sizeof(buf); + char buf[strlen(str) + 1]; + size_t buf_len = sizeof(buf); - size_t buf_len_needed; - TEST_ESP_OK(nvs_get_str(handle_2, "key", NULL, &buf_len_needed)); - TEST_ASSERT_TRUE(buf_len_needed == buf_len); + size_t buf_len_needed; + TEST_ESP_OK(nvs_get_str(handle_2, "key", NULL, &buf_len_needed)); + TEST_ASSERT_TRUE(buf_len_needed == buf_len); - size_t buf_len_short = buf_len - 1; - TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short)); - TEST_ASSERT_TRUE(buf_len_short == buf_len); + size_t buf_len_short = buf_len - 1; + TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short)); + TEST_ASSERT_TRUE(buf_len_short == buf_len); - size_t buf_len_long = buf_len + 1; - TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long)); - TEST_ASSERT_TRUE(buf_len_long == buf_len); + size_t buf_len_long = buf_len + 1; + TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long)); + TEST_ASSERT_TRUE(buf_len_long == buf_len); - TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len)); + TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len)); - TEST_ASSERT_TRUE(0 == strcmp(buf, str)); + TEST_ASSERT_TRUE(0 == strcmp(buf, str)); - nvs_close(handle_1); - nvs_close(handle_2); + nvs_close(handle_1); + nvs_close(handle_2); - TEST_ESP_OK(nvs_flash_deinit()); + TEST_ESP_OK(nvs_flash_deinit()); + } while(!done); } TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]")