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
commit 967c07b6ae
7 changed files with 89 additions and 12 deletions

View File

@ -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);

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;
}
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;

View File

@ -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);
}

View File

@ -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)

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_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;

View File

@ -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;

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);
}
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);