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

NVS: ensuring default partition

See merge request espressif/esp-idf!8934
This commit is contained in:
Ivan Grokhotkov
2021-01-20 07:44:28 +08:00
7 changed files with 89 additions and 12 deletions

View File

@@ -14,13 +14,12 @@
#ifndef nvs_flash_h #ifndef nvs_flash_h
#define nvs_flash_h #define nvs_flash_h
#ifdef __cplusplus
extern "C" {
#endif
#include "nvs.h" #include "nvs.h"
#include "esp_partition.h" #include "esp_partition.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NVS_KEY_SIZE 32 // AES-256 #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 * - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
* (which may happen if NVS partition was truncated) * (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_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 * - one of the error codes from the underlying flash storage driver
*/ */
esp_err_t nvs_flash_init_partition(const char *partition_label); 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 * - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
* (which may happen if NVS partition was truncated) * (which may happen if NVS partition was truncated)
* - ESP_ERR_INVALID_ARG in case partition is NULL * - 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 * - one of the error codes from the underlying flash storage driver
*/ */
esp_err_t nvs_flash_init_partition_ptr(const esp_partition_t *partition); 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_OK on success
* - ESP_ERR_NOT_FOUND if there is no NVS partition with the specified name * - ESP_ERR_NOT_FOUND if there is no NVS partition with the specified name
* in the partition table * 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) * - different error in case de-initialization fails (shouldn't happen)
*/ */
esp_err_t nvs_flash_erase_partition(const char *part_name); 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 * - ESP_ERR_NOT_FOUND if there is no partition with the specified
* parameters in the partition table * parameters in the partition table
* - ESP_ERR_INVALID_ARG in case partition is NULL * - 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 * - one of the error codes from the underlying flash storage driver
*/ */
esp_err_t nvs_flash_erase_partition_ptr(const esp_partition_t *partition); 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 * - ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages
* (which may happen if NVS partition was truncated) * (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_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 * - 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); 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 * @return
* -ESP_OK, if cfg was read successfully; * - ESP_OK, if cfg was read successfully;
* -or error codes from esp_partition_write/erase APIs. * - 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); 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'. * @note Provided parition is assumed to be marked 'encrypted'.
* *
* @return * @return
* -ESP_OK, if cfg was read successfully; * - 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_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_NVS_CORRUPT_KEY_PART, if the partition containing keys is found to be corrupt
* -or error codes from esp_partition_read API. * - 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); esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partition, nvs_sec_cfg_t* cfg);

View File

@@ -136,6 +136,10 @@ extern "C" esp_err_t nvs_flash_init_partition_ptr(const esp_partition_t *partiti
return ESP_ERR_INVALID_ARG; 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, return nvs_flash_init_custom(partition->label,
partition->address / SPI_FLASH_SEC_SIZE, partition->address / SPI_FLASH_SEC_SIZE,
partition->size / 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; 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, return nvs_flash_secure_init_custom(part_name, partition->address / SPI_FLASH_SEC_SIZE,
partition->size / SPI_FLASH_SEC_SIZE, cfg); 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; 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); 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; 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 the partition is initialized, uninitialize it first
if (NVSPartitionManager::get_instance()->lookup_storage_from_name(partition->label)) { if (NVSPartitionManager::get_instance()->lookup_storage_from_name(partition->label)) {
const esp_err_t err = close_handles_and_deinit(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) 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); auto err = esp_partition_erase_range(partition, 0, partition->size);
if(err != ESP_OK) { if(err != ESP_OK) {
return err; 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) 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]; uint8_t eky_raw[NVS_KEY_SIZE], tky_raw[NVS_KEY_SIZE];
uint32_t crc_raw, crc_read, crc_calc; uint32_t crc_raw, crc_read, crc_calc;

View File

@@ -45,6 +45,10 @@ esp_err_t NVSPartitionManager::init_partition(const char *partition_label)
return ESP_ERR_NOT_FOUND; 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, return init_custom(partition_label, partition->address / SPI_FLASH_SEC_SIZE,
partition->size / 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; 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, return secure_init_custom(part_name, partition->address / SPI_FLASH_SEC_SIZE,
partition->size / SPI_FLASH_SEC_SIZE, cfg); partition->size / SPI_FLASH_SEC_SIZE, cfg);
} }

View File

@@ -1,3 +1,4 @@
idf_component_register(SRC_DIRS "." idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_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)

View File

@@ -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_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]") TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]")
{ {
nvs_sec_cfg_t cfg, cfg2; nvs_sec_cfg_t cfg, cfg2;

View File

@@ -12,11 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "esp_spi_flash.h" #include "esp_spi_flash.h"
#include "esp_flash.h"
#include "spi_flash_emulation.h" #include "spi_flash_emulation.h"
static SpiFlashEmulator* s_emulator = nullptr; 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) void spi_flash_emulator_set(SpiFlashEmulator* e)
{ {
s_emulator = e; s_emulator = e;

View File

@@ -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); 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]") TEST_CASE("nvs_flash_init_partition_ptr inits one partition", "[nvs_custom_part]")
{ {
const uint32_t NVS_FLASH_SECTOR = 6; 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"); strcpy(partition.label, "test");
partition.address = NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE; partition.address = NVS_FLASH_SECTOR * SPI_FLASH_SEC_SIZE;
partition.size = NVS_FLASH_SECTOR_COUNT_MIN * 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(nvs_flash_init_partition_ptr(&partition) == ESP_OK);
CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") != nullptr); CHECK(NVSPartitionManager::get_instance()->lookup_storage_from_name("test") != nullptr);