Merge branch 'bugfix/nvs_key_part_check_err' into 'master'

nvs_flash: Detect key partition as uninitialised even if encrypted by bootloader

See merge request idf/esp-idf!4224
This commit is contained in:
Angus Gratton
2019-02-19 10:22:04 +08:00
2 changed files with 73 additions and 51 deletions

View File

@@ -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]; 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;
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); auto err = spi_flash_read(partition->address, eky_raw, NVS_KEY_SIZE);
if(err != ESP_OK) { if(err != ESP_OK) {
return err; return err;
@@ -642,12 +652,7 @@ extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partitio
return err; return err;
} }
if(!check_if_initialized(eky_raw, tky_raw, crc_raw)) {
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) {
/* This is an uninitialized key partition*/ /* This is an uninitialized key partition*/
return ESP_ERR_NVS_KEYS_NOT_INITIALIZED; return ESP_ERR_NVS_KEYS_NOT_INITIALIZED;
} }
@@ -674,6 +679,10 @@ extern "C" esp_err_t nvs_flash_read_security_cfg(const esp_partition_t* partitio
crc_calc = crc32_le(crc_calc, cfg->tky, 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; return ESP_ERR_NVS_CORRUPT_KEY_PART;
} }

View File

@@ -310,27 +310,39 @@ TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]")
TEST_CASE("test nvs apis with encryption enabled", "[nvs]") TEST_CASE("test nvs apis with encryption enabled", "[nvs]")
{ {
if (!esp_flash_encryption_enabled()) { if (!esp_flash_encryption_enabled()) {
TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with 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( const esp_partition_t* key_part = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); 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( const esp_partition_t* nvs_partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
assert(nvs_partition && "partition table must have an NVS partition"); assert(nvs_partition && "partition table must have an NVS partition");
ESP_ERROR_CHECK( esp_partition_erase_range(key_part, 0, key_part->size) );
bool done = false;
do {
ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) ); ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) );
nvs_sec_cfg_t cfg; nvs_sec_cfg_t cfg;
esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg); esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg);
if(err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) { 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)); TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg));
} else { } else {
/* Second time key_partition exists already*/
ESP_ERROR_CHECK(err); ESP_ERROR_CHECK(err);
done = true;
} }
TEST_ESP_OK(nvs_flash_secure_init(&cfg)); TEST_ESP_OK(nvs_flash_secure_init(&cfg));
@@ -381,6 +393,7 @@ TEST_CASE("test nvs apis with encryption enabled", "[nvs]")
nvs_close(handle_2); 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]") TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]")