ソースを参照

Merge branch 'bugfix/nvs_check_external_partition' into 'release/v4.2'

NVS: ensuring default partition

See merge request espressif/esp-idf!8934
Ivan Grokhotkov 5 年 前
コミット
967c07b6ae

+ 16 - 10
components/nvs_flash/include/nvs_flash.h

@@ -14,13 +14,12 @@
 #ifndef nvs_flash_h
 #define nvs_flash_h
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include "nvs.h"
 #include "esp_partition.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #define NVS_KEY_SIZE 32 // AES-256
 
@@ -57,6 +56,7 @@ esp_err_t nvs_flash_init(void);
  *      - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
  *        (which may happen if NVS partition was truncated)
  *      - ESP_ERR_NOT_FOUND if specified partition is not found in the partition table
+ *      - ESP_ERR_NOT_SUPPORTED if the partition with name partition_label is not in internal flash
  *      - one of the error codes from the underlying flash storage driver
  */
 esp_err_t nvs_flash_init_partition(const char *partition_label);
@@ -71,6 +71,7 @@ esp_err_t nvs_flash_init_partition(const char *partition_label);
  *      - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
  *        (which may happen if NVS partition was truncated)
  *      - ESP_ERR_INVALID_ARG in case partition is NULL
+ *      - ESP_ERR_NOT_SUPPORTED if the partition is not in internal flash
  *      - one of the error codes from the underlying flash storage driver
  */
 esp_err_t nvs_flash_init_partition_ptr(const esp_partition_t *partition);
@@ -128,6 +129,7 @@ esp_err_t nvs_flash_erase(void);
  *      - ESP_OK on success
  *      - ESP_ERR_NOT_FOUND if there is no NVS partition with the specified name
  *        in the partition table
+ *      - ESP_ERR_NOT_SUPPORTED if the partition with part_name is not in internal flash
  *      - different error in case de-initialization fails (shouldn't happen)
  */
 esp_err_t nvs_flash_erase_partition(const char *part_name);
@@ -148,6 +150,7 @@ esp_err_t nvs_flash_erase_partition(const char *part_name);
  *      - ESP_ERR_NOT_FOUND if there is no partition with the specified
  *        parameters in the partition table
  *      - ESP_ERR_INVALID_ARG in case partition is NULL
+ *      - ESP_ERR_NOT_SUPPORTED if the partition is not in internal flash
  *      - one of the error codes from the underlying flash storage driver
  */
 esp_err_t nvs_flash_erase_partition_ptr(const esp_partition_t *partition);
@@ -183,6 +186,7 @@ esp_err_t nvs_flash_secure_init(nvs_sec_cfg_t* cfg);
  *      - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
  *        (which may happen if NVS partition was truncated)
  *      - ESP_ERR_NOT_FOUND if specified partition is not found in the partition table
+ *      - ESP_ERR_NOT_SUPPORTED if the partition is not in internal flash
  *      - one of the error codes from the underlying flash storage driver
  */
 esp_err_t nvs_flash_secure_init_partition(const char *partition_label, nvs_sec_cfg_t* cfg);
@@ -199,8 +203,9 @@ esp_err_t nvs_flash_secure_init_partition(const char *partition_label, nvs_sec_c
  *
  *
  * @return
- *      -ESP_OK, if cfg was read successfully;
- *      -or error codes from esp_partition_write/erase APIs.
+ *      - ESP_OK, if cfg was read successfully;
+ *      - ESP_ERR_NOT_SUPPORTED if the partition is not in internal flash
+ *      - or error codes from esp_partition_write/erase APIs.
  */
 
 esp_err_t nvs_flash_generate_keys(const esp_partition_t* partition, nvs_sec_cfg_t* cfg);
@@ -218,10 +223,11 @@ esp_err_t nvs_flash_generate_keys(const esp_partition_t* partition, nvs_sec_cfg_
  * @note  Provided parition is assumed to be marked 'encrypted'.
  *
  * @return
- *      -ESP_OK, if cfg was read successfully;
- *      -ESP_ERR_NVS_KEYS_NOT_INITIALIZED, if the partition is not yet written with keys.
- *      -ESP_ERR_NVS_CORRUPT_KEY_PART, if the partition containing keys is found to be corrupt
- *      -or error codes from esp_partition_read API.
+ *      - ESP_OK, if cfg was read successfully;
+ *      - ESP_ERR_NVS_KEYS_NOT_INITIALIZED, if the partition is not yet written with keys.
+ *      - ESP_ERR_NVS_CORRUPT_KEY_PART, if the partition containing keys is found to be corrupt
+ *      - ESP_ERR_NOT_SUPPORTED if the partition is not in internal flash
+ *      - or error codes from esp_partition_read API.
  */
 
 esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partition, nvs_sec_cfg_t* cfg);

+ 24 - 0
components/nvs_flash/src/nvs_api.cpp

@@ -136,6 +136,10 @@ extern "C" esp_err_t nvs_flash_init_partition_ptr(const esp_partition_t *partiti
         return ESP_ERR_INVALID_ARG;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     return nvs_flash_init_custom(partition->label,
                                  partition->address / SPI_FLASH_SEC_SIZE,
                                  partition->size / SPI_FLASH_SEC_SIZE);
@@ -173,6 +177,10 @@ extern "C" esp_err_t nvs_flash_secure_init_partition(const char *part_name, nvs_
         return ESP_ERR_NOT_FOUND;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     return nvs_flash_secure_init_custom(part_name, partition->address / SPI_FLASH_SEC_SIZE,
             partition->size / SPI_FLASH_SEC_SIZE, cfg);
 }
@@ -204,6 +212,10 @@ extern "C" esp_err_t nvs_flash_erase_partition(const char *part_name)
         return ESP_ERR_NOT_FOUND;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     return esp_partition_erase_range(partition, 0, partition->size);
 }
 
@@ -216,6 +228,10 @@ extern "C" esp_err_t nvs_flash_erase_partition_ptr(const esp_partition_t *partit
         return ESP_ERR_INVALID_ARG;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     // if the partition is initialized, uninitialize it first
     if (NVSPartitionManager::get_instance()->lookup_storage_from_name(partition->label)) {
         const esp_err_t err = close_handles_and_deinit(partition->label);
@@ -561,6 +577,10 @@ extern "C" esp_err_t nvs_get_used_entry_count(nvs_handle_t c_handle, size_t* use
 
 extern "C" esp_err_t nvs_flash_generate_keys(const esp_partition_t* partition, nvs_sec_cfg_t* cfg)
 {
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     auto err = esp_partition_erase_range(partition, 0, partition->size);
     if(err != ESP_OK) {
         return err;
@@ -609,6 +629,10 @@ extern "C" esp_err_t nvs_flash_generate_keys(const esp_partition_t* partition, n
 
 extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partition, nvs_sec_cfg_t* cfg)
 {
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     uint8_t eky_raw[NVS_KEY_SIZE], tky_raw[NVS_KEY_SIZE];
     uint32_t crc_raw, crc_read, crc_calc;
 

+ 8 - 0
components/nvs_flash/src/nvs_partition_manager.cpp

@@ -45,6 +45,10 @@ esp_err_t NVSPartitionManager::init_partition(const char *partition_label)
         return ESP_ERR_NOT_FOUND;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     return init_custom(partition_label, partition->address / SPI_FLASH_SEC_SIZE,
             partition->size / SPI_FLASH_SEC_SIZE);
 }
@@ -92,6 +96,10 @@ esp_err_t NVSPartitionManager::secure_init_partition(const char *part_name, nvs_
         return ESP_ERR_NOT_FOUND;
     }
 
+    if (partition->flash_chip != esp_flash_default_chip) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+
     return secure_init_custom(part_name, partition->address / SPI_FLASH_SEC_SIZE,
             partition->size / SPI_FLASH_SEC_SIZE, cfg);
 }

+ 2 - 1
components/nvs_flash/test/CMakeLists.txt

@@ -1,3 +1,4 @@
 idf_component_register(SRC_DIRS "."
                     PRIV_INCLUDE_DIRS "."
-                    PRIV_REQUIRES unity test_utils nvs_flash bootloader_support)
+                    PRIV_REQUIRES unity test_utils nvs_flash bootloader_support
+                    EMBED_TXTFILES encryption_keys.bin partition_encrypted.bin sample.bin)

+ 18 - 0
components/nvs_flash/test/test_nvs.c

@@ -321,6 +321,24 @@ TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs]
     TEST_ASSERT_TRUE(!memcmp(ptxt_hex, ctxt_hex, 32));
 }
 
+TEST_CASE("nvs_flash_generate_keys fails due to external partition", "[nvs_custom_part]")
+{
+    nvs_sec_cfg_t keys;
+    struct esp_flash_t spi_flash = {};
+    esp_partition_t partition = {};
+    partition.flash_chip = &spi_flash;
+    TEST_ESP_ERR(nvs_flash_generate_keys(&partition, &keys), ESP_ERR_NOT_SUPPORTED);
+}
+
+TEST_CASE("nvs_flash_read_security_cfg fails due to external partition", "[nvs_custom_part]")
+{
+    nvs_sec_cfg_t keys;
+    struct esp_flash_t spi_flash = {};
+    esp_partition_t partition = {};
+    partition.flash_chip = &spi_flash;
+    TEST_ESP_ERR(nvs_flash_read_security_cfg(&partition, &keys), ESP_ERR_NOT_SUPPORTED);
+}
+
 TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]")
 {
     nvs_sec_cfg_t cfg, cfg2;

+ 5 - 1
components/nvs_flash/test_nvs_host/spi_flash_emulation.cpp

@@ -12,11 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #include "esp_spi_flash.h"
+#include "esp_flash.h"
 #include "spi_flash_emulation.h"
 
-
 static SpiFlashEmulator* s_emulator = nullptr;
 
+static esp_flash_t esp_flash_default_chip_instance;
+
+esp_flash_t *esp_flash_default_chip = &esp_flash_default_chip_instance;
+
 void spi_flash_emulator_set(SpiFlashEmulator* e)
 {
     s_emulator = e;

+ 16 - 0
components/nvs_flash/test_nvs_host/test_nvs_initialization.cpp

@@ -29,6 +29,21 @@ TEST_CASE("nvs_flash_init_partition_ptr fails due to nullptr arg", "[nvs_custom_
     CHECK(nvs_flash_init_partition_ptr(nullptr) == ESP_ERR_INVALID_ARG);
 }
 
+TEST_CASE("nvs_flash_init_partition_ptr fails due to external partition", "[nvs_custom_part]")
+{
+    const uint32_t NVS_FLASH_SECTOR = 6;
+    const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
+    SpiFlashEmulator emu(10);
+
+    struct esp_flash_t spi_flash = {};
+    esp_partition_t partition = {};
+    strcpy(partition.label, "test");
+    partition.address = NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE;
+    partition.size = NVS_FLASH_SECTOR_COUNT_MIN * SPI_FLASH_SEC_SIZE;
+    partition.flash_chip = &spi_flash;
+    CHECK(nvs_flash_init_partition_ptr(&partition) == ESP_ERR_NOT_SUPPORTED);
+}
+
 TEST_CASE("nvs_flash_init_partition_ptr inits one partition", "[nvs_custom_part]")
 {
     const uint32_t NVS_FLASH_SECTOR = 6;
@@ -39,6 +54,7 @@ TEST_CASE("nvs_flash_init_partition_ptr inits one partition", "[nvs_custom_part]
     strcpy(partition.label, "test");
     partition.address = NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE;
     partition.size = NVS_FLASH_SECTOR_COUNT_MIN * SPI_FLASH_SEC_SIZE;
+    partition.flash_chip = esp_flash_default_chip;
 
     CHECK(nvs_flash_init_partition_ptr(&partition) == ESP_OK);
     CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") != nullptr);