From 94ae902d780ca2ace7f1c0c1e35cf7b5bf50cf4a Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Tue, 4 Apr 2023 00:00:56 +0800 Subject: [PATCH 1/3] 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. --- .../with_key_purposes/esp_efuse_api_key.c | 16 +++++++ .../test/with_key_purposes/test_efuse_keys.c | 42 ++++++++++++++++++- .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32s3/include/soc/soc_caps.h | 1 + 8 files changed, 71 insertions(+), 2 deletions(-) diff --git a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c index 2af5f863c2..8896395335 100644 --- a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c +++ b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c @@ -282,6 +282,22 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo 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 +#if SOC_ECDSA_SUPPORTED + purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || +#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_128_KEY || #ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || diff --git a/components/efuse/test/with_key_purposes/test_efuse_keys.c b/components/efuse/test/with_key_purposes/test_efuse_keys.c index b7a4994e1e..3cee68ec38 100644 --- a/components/efuse/test/with_key_purposes/test_efuse_keys.c +++ b/components/efuse/test/with_key_purposes/test_efuse_keys.c @@ -47,6 +47,26 @@ TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial st printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0); } } + +#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 +#if SOC_ECDSA_SUPPORTED + purpose = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY; + 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. @@ -118,14 +138,32 @@ 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 +#if SOC_ECDSA_SUPPORTED + purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || +#endif + 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/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index ddb8e16f1f..1c635e2eaa 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -695,6 +695,10 @@ config SOC_EFUSE_SOFT_DIS_JTAG bool default y +config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + bool + default y + config SOC_SECURE_BOOT_V2_RSA bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 18f69561f3..1a5ce1f50d 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -320,6 +320,7 @@ #define SOC_EFUSE_DIS_USB_JTAG 1 #define SOC_EFUSE_DIS_DIRECT_BOOT 1 #define SOC_EFUSE_SOFT_DIS_JTAG 1 +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS key purpose not supported for this block /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 65bad0061d..03029234c5 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -667,6 +667,10 @@ config SOC_EFUSE_SOFT_DIS_JTAG bool default y +config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + bool + default y + config SOC_SECURE_BOOT_V2_RSA bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index a85f1ae429..b75d037aa4 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -324,6 +324,7 @@ #define SOC_EFUSE_DIS_USB_JTAG 1 #define SOC_EFUSE_DIS_DIRECT_BOOT 1 #define SOC_EFUSE_SOFT_DIS_JTAG 1 +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS and ECDSA key purposes not supported for this block /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1 diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index cb8ca4179f..cfe59ae4fb 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -943,6 +943,10 @@ config SOC_EFUSE_DIS_DIRECT_BOOT bool default y +config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK + bool + default y + config SOC_SECURE_BOOT_V2_RSA bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index e3ee515c53..f8224d1ef4 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -394,6 +394,7 @@ #define SOC_EFUSE_DIS_USB_JTAG 1 #define SOC_EFUSE_SOFT_DIS_JTAG 1 #define SOC_EFUSE_DIS_DIRECT_BOOT 1 +#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS key purpose not supported for this block /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1 From da96a8a104d51057a46ae902a41c45f59d3b36bd Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 5 Apr 2023 14:19:32 +0530 Subject: [PATCH 2/3] docs: add a note regarding EFuse Block9 key purpose quirk for some chips --- docs/en/api-reference/system/efuse.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index 3e28e20f2b..b92f365c1f 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -29,6 +29,8 @@ For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Co .. only:: not esp32 and not esp32c2 + .. list:: + {IDF_TARGET_NAME} has 11 eFuse blocks each of the size of 256 bits (not all bits are available): * EFUSE_BLK0 is used entirely for system purposes; @@ -40,7 +42,8 @@ For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Co * EFUSE_BLK6 (also named EFUSE_BLK_KEY2) can be used as key (for secure_boot or flash_encryption) or for user purposes; * EFUSE_BLK7 (also named EFUSE_BLK_KEY3) can be used as key (for secure_boot or flash_encryption) or for user purposes; * EFUSE_BLK8 (also named EFUSE_BLK_KEY4) can be used as key (for secure_boot or flash_encryption) or for user purposes; - * EFUSE_BLK9 (also named EFUSE_BLK_KEY5) can be used as key (for secure_boot or flash_encryption) or for user purposes; + :SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK: * EFUSE_BLK9 (also named EFUSE_BLK_KEY5) can be used for any purpose except for flash encryption (due to a HW bug); + :not SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK: * EFUSE_BLK9 (also named EFUSE_BLK_KEY5) can be used as key (for secure_boot or flash_encryption) or for user purposes; * EFUSE_BLK10 (also named EFUSE_BLK_SYS_DATA_PART2) is reseved for system purposes. .. only:: esp32c2 From 11e71cd3eb3a02a84931e81d7e9f0c850c2ed5b9 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Mon, 24 Apr 2023 15:13:04 +0800 Subject: [PATCH 3/3] fixup! efuse: Prevent burning XTS_AES and ECDSA keys into BLOCK9 (BLOCK_KEY5) --- .../keys/with_key_purposes/esp_efuse_api_key.c | 3 --- components/efuse/test/with_key_purposes/test_efuse_keys.c | 7 ------- 2 files changed, 10 deletions(-) diff --git a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c index 8896395335..a177a92ee4 100644 --- a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c +++ b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c @@ -287,9 +287,6 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo #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 -#if SOC_ECDSA_SUPPORTED - purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || #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); diff --git a/components/efuse/test/with_key_purposes/test_efuse_keys.c b/components/efuse/test/with_key_purposes/test_efuse_keys.c index 3cee68ec38..1341795ed3 100644 --- a/components/efuse/test/with_key_purposes/test_efuse_keys.c +++ b/components/efuse/test/with_key_purposes/test_efuse_keys.c @@ -60,10 +60,6 @@ TEST_CASE("Test efuse API blocks burning XTS and ECDSA keys into BLOCK9", "[efus 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 -#if SOC_ECDSA_SUPPORTED - purpose = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY; - 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 @@ -156,9 +152,6 @@ TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]") 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 -#if SOC_ECDSA_SUPPORTED - purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || -#endif 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;