Przeglądaj źródła

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.
KonstantinKondrashov 2 lat temu
rodzic
commit
3d695b9768

+ 16 - 0
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 ||

+ 38 - 3
components/efuse/test_apps/main/with_key_purposes/test_efuse_keys.c

@@ -50,6 +50,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.
@@ -124,8 +144,8 @@ 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_USER; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
-        if (purpose == ESP_EFUSE_KEY_PURPOSE_USER) {
+    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();
@@ -136,9 +156,24 @@ TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
 #endif
         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);

+ 4 - 0
components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

@@ -771,6 +771,10 @@ config SOC_EFUSE_DIS_ICACHE
     bool
     default y
 
+config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
+    bool
+    default y
+
 config SOC_SECURE_BOOT_V2_RSA
     bool
     default y

+ 1 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -340,6 +340,7 @@
 #define SOC_EFUSE_DIS_DIRECT_BOOT 1
 #define SOC_EFUSE_SOFT_DIS_JTAG 1
 #define SOC_EFUSE_DIS_ICACHE 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

+ 4 - 0
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -983,6 +983,10 @@ config SOC_EFUSE_DIS_ICACHE
     bool
     default y
 
+config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
+    bool
+    default y
+
 config SOC_SECURE_BOOT_V2_RSA
     bool
     default y

+ 1 - 0
components/soc/esp32c6/include/soc/soc_caps.h

@@ -404,6 +404,7 @@
 #define SOC_EFUSE_DIS_DIRECT_BOOT 1
 #define SOC_EFUSE_SOFT_DIS_JTAG 1
 #define SOC_EFUSE_DIS_ICACHE 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

+ 4 - 0
components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

@@ -975,6 +975,10 @@ config SOC_EFUSE_DIS_ICACHE
     bool
     default y
 
+config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
+    bool
+    default y
+
 config SOC_SECURE_BOOT_V2_RSA
     bool
     default y

+ 1 - 0
components/soc/esp32h2/include/soc/soc_caps.h

@@ -410,6 +410,7 @@
 #define SOC_EFUSE_DIS_DIRECT_BOOT 1
 #define SOC_EFUSE_SOFT_DIS_JTAG 1
 #define SOC_EFUSE_DIS_ICACHE 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

+ 4 - 0
components/soc/esp32h4/include/soc/Kconfig.soc_caps.in

@@ -743,6 +743,10 @@ config SOC_EFUSE_DIS_ICACHE
     bool
     default y
 
+config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
+    bool
+    default y
+
 config SOC_SECURE_BOOT_V2_RSA
     bool
     default y

+ 1 - 0
components/soc/esp32h4/include/soc/soc_caps.h

@@ -351,6 +351,7 @@
 #define SOC_EFUSE_DIS_DIRECT_BOOT 1
 #define SOC_EFUSE_SOFT_DIS_JTAG 1
 #define SOC_EFUSE_DIS_ICACHE 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

+ 4 - 0
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -1095,6 +1095,10 @@ config SOC_EFUSE_DIS_ICACHE
     bool
     default y
 
+config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
+    bool
+    default y
+
 config SOC_SECURE_BOOT_V2_RSA
     bool
     default y

+ 1 - 0
components/soc/esp32s3/include/soc/soc_caps.h

@@ -440,6 +440,7 @@
 #define SOC_EFUSE_SOFT_DIS_JTAG 1
 #define SOC_EFUSE_DIS_DIRECT_BOOT 1
 #define SOC_EFUSE_DIS_ICACHE 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