From e21b0cb6edb2df449e968560db9aa5a5ab41b536 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Tue, 4 Apr 2023 00:00:56 +0800 Subject: [PATCH] efuse: Prevent burning XTS_AES and ECDSA keys into BLOCK9 (BLOCK_KEY5) eFuse module has a hardware bug. It is related to ESP32-C3, C6, S3, H2 chips: - BLOCK9 (BLOCK_KEY5) can not be used by XTS_AES keys. For H2 chips, the BLOCK9 (BLOCK_KEY5) can not be used by ECDSA keys. S2 does not have such a hardware bug. --- components/efuse/src/esp_efuse_api.c | 14 ++++++++ components/efuse/test/test_efuse_keys.c | 36 +++++++++++++++++-- components/soc/esp32c3/include/soc/soc_caps.h | 3 ++ components/soc/esp32s3/include/soc/soc_caps.h | 3 ++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/components/efuse/src/esp_efuse_api.c b/components/efuse/src/esp_efuse_api.c index db62019f9c..749e7b2633 100644 --- a/components/efuse/src/esp_efuse_api.c +++ b/components/efuse/src/esp_efuse_api.c @@ -538,6 +538,20 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo unsigned idx = block - EFUSE_BLK_KEY0; ESP_EFUSE_CHK(esp_efuse_write_field_blob(s_table[idx].key, key, key_size_bytes * 8)); ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block)); + +#if SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + if (block == EFUSE_BLK9 && ( +#if SOC_FLASH_ENCRYPTION_XTS_AES_256 + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || +#endif + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY)) { + ESP_LOGE(TAG, "BLOCK9 can not have the %d purpose because of HW bug (see TRM for more details)", purpose); + err = ESP_ERR_NOT_SUPPORTED; + goto err_exit; + } +#endif // SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || diff --git a/components/efuse/test/test_efuse_keys.c b/components/efuse/test/test_efuse_keys.c index b7f1915211..08bc0027d2 100644 --- a/components/efuse/test/test_efuse_keys.c +++ b/components/efuse/test/test_efuse_keys.c @@ -43,6 +43,23 @@ TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial st } } +#if CONFIG_EFUSE_VIRTUAL +#if SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK +TEST_CASE("Test efuse API blocks burning XTS and ECDSA keys into BLOCK9", "[efuse]") +{ + uint8_t key[32] = {0}; + esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY; + TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_write_key(EFUSE_BLK9, purpose, &key, sizeof(key))); +#if SOC_FLASH_ENCRYPTION_XTS_AES_256 + purpose = ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1; + TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_write_key(EFUSE_BLK9, purpose, &key, sizeof(key))); + purpose = ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2; + TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_write_key(EFUSE_BLK9, purpose, &key, sizeof(key))); +#endif +} +#endif // SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK +#endif // CONFIG_EFUSE_VIRTUAL + // If using efuse is real, then turn off writing tests. #if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA @@ -110,14 +127,29 @@ TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]") TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, tmp_purpose, &rd_key, 33)); TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK10, tmp_purpose, &rd_key, sizeof(rd_key))); - for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_RESERVED; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) { + for (esp_efuse_purpose_t g_purpose = ESP_EFUSE_KEY_PURPOSE_USER; g_purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++g_purpose) { + if (g_purpose == ESP_EFUSE_KEY_PURPOSE_USER) { + continue; + } esp_efuse_utility_reset(); esp_efuse_utility_update_virt_blocks(); esp_efuse_utility_debug_dump_blocks(); - TEST_ASSERT_FALSE(esp_efuse_find_purpose(purpose, NULL)); + TEST_ASSERT_FALSE(esp_efuse_find_purpose(g_purpose, NULL)); for (esp_efuse_block_t num_key = (EFUSE_BLK_KEY_MAX - 1); num_key >= EFUSE_BLK_KEY0; --num_key) { + esp_efuse_purpose_t purpose = g_purpose; +#if SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + if (num_key == EFUSE_BLK9 && ( +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || +#endif //#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS + purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY)) { + printf("BLOCK9 can not have the %d purpose, use RESERVED instead\n", purpose); + purpose = ESP_EFUSE_KEY_PURPOSE_RESERVED; + } +#endif // SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK int id = num_key - EFUSE_BLK_KEY0; TEST_ASSERT_EQUAL(id + 1, esp_efuse_count_unused_key_blocks()); test_write_key(num_key, purpose); diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index dd7065889b..7793526ecc 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -224,6 +224,9 @@ #define SOC_TWAI_BRP_MAX 16384 #define SOC_TWAI_SUPPORTS_RX_STATUS 1 +/*-------------------------- eFuse CAPS----------------------------*/ +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS key purpose not supported for this block + /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-C3 has 2 UARTs #define SOC_UART_NUM (2) diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 17e38fa49c..a8aa73f9ec 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -167,6 +167,9 @@ #define SOC_GDMA_SHA_DMA_CHANNEL (3) #define SOC_GDMA_AES_DMA_CHANNEL (4) +/*-------------------------- eFuse CAPS----------------------------*/ +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS key purpose not supported for this block + /*-------------------------- WI-FI HARDWARE TSF CAPS -------------------------------*/ #define SOC_WIFI_HW_TSF (1)