Przeglądaj źródła

efuse(esp32c2): Support eFuse key APIs

KonstantinKondrashov 4 lat temu
rodzic
commit
ebdc52d4e2
41 zmienionych plików z 1703 dodań i 457 usunięć
  1. 2 0
      components/bootloader/Kconfig.projbuild
  2. 8 11
      components/bootloader_support/src/secure_boot_v2/secure_boot.c
  3. 12 6
      components/efuse/CMakeLists.txt
  4. 12 3
      components/efuse/esp32c2/esp_efuse_fields.c
  5. 108 54
      components/efuse/esp32c2/esp_efuse_table.c
  6. 32 33
      components/efuse/esp32c2/esp_efuse_table.csv
  7. 84 7
      components/efuse/esp32c2/esp_efuse_utility.c
  8. 12 13
      components/efuse/esp32c2/include/esp_efuse.h
  9. 27 104
      components/efuse/esp32c2/include/esp_efuse_table.h
  10. 5 3
      components/efuse/include/esp_efuse.h
  11. 7 23
      components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
  12. 247 0
      components/efuse/src/efuse_controller/keys/without_key_purposes/one_key_block/esp_efuse_api_key.c
  13. 8 1
      components/efuse/src/efuse_controller/keys/without_key_purposes/three_key_blocks/esp_efuse_api_key.c
  14. 1 4
      components/efuse/src/esp_efuse_fields.c
  15. 14 2
      components/efuse/test/CMakeLists.txt
  16. 109 0
      components/efuse/test/one_key_block/esp_efuse_test_table.c
  17. 34 0
      components/efuse/test/one_key_block/esp_efuse_test_table.csv
  18. 28 0
      components/efuse/test/one_key_block/include/esp_efuse_test_table.h
  19. 154 0
      components/efuse/test/one_key_block/test_efuse.c
  20. 292 0
      components/efuse/test/one_key_block/test_efuse_keys.c
  21. 12 177
      components/efuse/test/test_efuse.c
  22. 1 1
      components/efuse/test/three_key_blocks/esp_efuse_test_table.c
  23. 0 0
      components/efuse/test/three_key_blocks/esp_efuse_test_table.csv
  24. 1 1
      components/efuse/test/three_key_blocks/include/esp_efuse_test_table.h
  25. 86 0
      components/efuse/test/three_key_blocks/test_efuse.c
  26. 1 3
      components/efuse/test/three_key_blocks/test_efuse_coding_scheme.c
  27. 107 0
      components/efuse/test/with_key_purposes/esp_efuse_test_table.c
  28. 33 0
      components/efuse/test/with_key_purposes/esp_efuse_test_table.csv
  29. 28 0
      components/efuse/test/with_key_purposes/include/esp_efuse_test_table.h
  30. 195 0
      components/efuse/test/with_key_purposes/test_efuse.c
  31. 7 5
      components/efuse/test/with_key_purposes/test_efuse_keys.c
  32. 10 2
      components/soc/esp32c2/include/soc/Kconfig.soc_caps.in
  33. 4 2
      components/soc/esp32c2/include/soc/soc_caps.h
  34. 4 0
      components/soc/esp32c3/include/soc/Kconfig.soc_caps.in
  35. 2 1
      components/soc/esp32c3/include/soc/soc_caps.h
  36. 4 0
      components/soc/esp32h2/include/soc/Kconfig.soc_caps.in
  37. 2 1
      components/soc/esp32h2/include/soc/soc_caps.h
  38. 4 0
      components/soc/esp32s2/include/soc/Kconfig.soc_caps.in
  39. 1 0
      components/soc/esp32s2/include/soc/soc_caps.h
  40. 4 0
      components/soc/esp32s3/include/soc/Kconfig.soc_caps.in
  41. 1 0
      components/soc/esp32s3/include/soc/soc_caps.h

+ 2 - 0
components/bootloader/Kconfig.projbuild

@@ -273,6 +273,8 @@ menu "Bootloader config"
         depends on BOOTLOADER_APP_ANTI_ROLLBACK
         range 1 32 if IDF_TARGET_ESP32
         default 32 if IDF_TARGET_ESP32
+        range 1 4 if IDF_TARGET_ESP32C2
+        default 4 if IDF_TARGET_ESP32C2
         range 1 16
         default 16
         help

+ 8 - 11
components/bootloader_support/src/secure_boot_v2/secure_boot.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -131,26 +131,23 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
 static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t *image_data)
 {
     esp_err_t ret;
-#ifdef CONFIG_IDF_TARGET_ESP8684
-    esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
-        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
-    };
-#elif CONFIG_IDF_TARGET_ESP32
-    esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
-        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
-    };
+#ifdef CONFIG_IDF_TARGET_ESP32
     esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
     if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
         ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
         return ESP_ERR_NOT_SUPPORTED;
     }
-#else
+#endif // CONFIG_IDF_TARGET_ESP32
+
     esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+#if SECURE_BOOT_NUM_BLOCKS == 1
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
+#else
         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
+#endif
     };
-#endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP8684
 
     /* Verify the bootloader */
     esp_image_metadata_t bootloader_data = { 0 };

+ 12 - 6
components/efuse/CMakeLists.txt

@@ -13,15 +13,21 @@ if(EXISTS "${COMPONENT_DIR}/${target}")
     add_prefix(srcs "${target}/" ${EFUSE_SOC_SRCS})
 endif()
 
-list(APPEND srcs "src/esp_efuse_api.c"
-                 "src/esp_efuse_fields.c"
-                 "src/esp_efuse_utility.c")
-if("esp32" STREQUAL "${target}")
-    list(APPEND srcs "src/esp_efuse_api_key_esp32.c")
+if(CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD)
+    set(type "with_key_purposes")
 else()
-    list(APPEND srcs "src/esp_efuse_api_key_esp32xx.c")
+    if(CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK)
+        set(type "without_key_purposes/one_key_block")
+    else()
+        set(type "without_key_purposes/three_key_blocks")
+    endif()
 endif()
 
+list(APPEND srcs "src/esp_efuse_api.c"
+                 "src/esp_efuse_fields.c"
+                 "src/esp_efuse_utility.c"
+                 "src/efuse_controller/keys/${type}/esp_efuse_api_key.c")
+
 idf_component_register(SRCS "${srcs}"
                     PRIV_REQUIRES bootloader_support soc spi_flash
                     INCLUDE_DIRS "${include_dirs}"

+ 12 - 3
components/efuse/esp32c2/esp_efuse_fields.c

@@ -40,15 +40,24 @@ uint32_t esp_efuse_get_pkg_ver(void)
 
 esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme)
 {
-    abort();
+    int cur_log_scheme = 0;
+    esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, ESP_EFUSE_UART_PRINT_CONTROL[0]->bit_count);
+    if (!cur_log_scheme) { // not burned yet
+        return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, ESP_EFUSE_UART_PRINT_CONTROL[0]->bit_count);
+    } else {
+        return ESP_ERR_INVALID_STATE;
+    }
 }
 
 esp_err_t esp_efuse_disable_rom_download_mode(void)
 {
-    abort();
+    return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE);
 }
 
 esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
 {
-    abort();
+    if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) {
+        return ESP_ERR_INVALID_STATE;
+    }
+    return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
 }

+ 108 - 54
components/efuse/esp32c2/esp_efuse_table.c

@@ -9,7 +9,7 @@
 #include <assert.h>
 #include "esp_efuse_table.h"
 
-// md5_digest_table 3bf086fa10d850cbaeccbd70fcba1c2f
+// md5_digest_table af57e8a6a405ebf239cc552f713c91d0
 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
 // If you want to change some fields, you need to change esp_efuse_table.csv file
 // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@@ -24,15 +24,19 @@ static const esp_efuse_desc_t WR_DIS_KEY0_RD_DIS[] = {
 };
 
 static const esp_efuse_desc_t WR_DIS_GROUP_1[] = {
-    {EFUSE_BLK0, 1, 1}, 	 // Write protection for WDT_DELAY DIS_PAD_JTAG,
+    {EFUSE_BLK0, 1, 1}, 	 // Write protection for WDT_DELAY DIS_PAD_JTAG DIS_DOWNLOAD_ICACHE,
 };
 
 static const esp_efuse_desc_t WR_DIS_GROUP_2[] = {
-    {EFUSE_BLK0, 2, 1}, 	 // Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256,
+    {EFUSE_BLK0, 2, 1}, 	 // Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_CRYPT_CNT XTS_KEY_LENGTH_256 SECURE_BOOT_EN,
+};
+
+static const esp_efuse_desc_t WR_DIS_SPI_BOOT_CRYPT_CNT[] = {
+    {EFUSE_BLK0, 2, 1}, 	 // Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT [SPI_BOOT_CRYPT_CNT] XTS_KEY_LENGTH_256 SECURE_BOOT_EN,
 };
 
 static const esp_efuse_desc_t WR_DIS_GROUP_3[] = {
-    {EFUSE_BLK0, 3, 1}, 	 // Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN,
+    {EFUSE_BLK0, 3, 1}, 	 // Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW,
 };
 
 static const esp_efuse_desc_t WR_DIS_BLK0_RESERVED[] = {
@@ -48,79 +52,87 @@ static const esp_efuse_desc_t WR_DIS_SYS_DATA_PART1[] = {
 };
 
 static const esp_efuse_desc_t WR_DIS_KEY0[] = {
-    {EFUSE_BLK0, 7, 1}, 	 // Write protection for EFUSE_BLK3.  KEY0,
+    {EFUSE_BLK0, 7, 1}, 	 // Write protection for EFUSE_BLK3.  whole KEY0,
 };
 
 static const esp_efuse_desc_t RD_DIS[] = {
-    {EFUSE_BLK0, 8, 2}, 	 // Read protection,
+    {EFUSE_BLK0, 32, 2}, 	 // Read protection,
 };
 
 static const esp_efuse_desc_t RD_DIS_KEY0[] = {
     {EFUSE_BLK0, 32, 2}, 	 // Read protection for EFUSE_BLK3.  KEY0,
 };
 
+static const esp_efuse_desc_t RD_DIS_KEY0_LOW[] = {
+    {EFUSE_BLK0, 32, 1}, 	 // Read protection for EFUSE_BLK3.  KEY0 lower 128-bit key,
+};
+
+static const esp_efuse_desc_t RD_DIS_KEY0_HI[] = {
+    {EFUSE_BLK0, 33, 1}, 	 // Read protection for EFUSE_BLK3.  KEY0 higher 128-bit key,
+};
+
 static const esp_efuse_desc_t WDT_DELAY_SEL[] = {
-    {EFUSE_BLK0, 34, 2}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 34, 2}, 	 // RTC WDT timeout threshold,
 };
 
 static const esp_efuse_desc_t DIS_PAD_JTAG[] = {
-    {EFUSE_BLK0, 36, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 36, 1}, 	 // Hardware Disable JTAG permanently,
 };
 
-static const esp_efuse_desc_t EFUSE_DIS_DOWNLOAD_ICACHE[] = {
-    {EFUSE_BLK0, 37, 1}, 	 // /* TODO: Need Description*/,
+static const esp_efuse_desc_t DIS_DOWNLOAD_ICACHE[] = {
+    {EFUSE_BLK0, 37, 1}, 	 // Disable ICache in Download mode,
 };
 
 static const esp_efuse_desc_t DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
-    {EFUSE_BLK0, 38, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 38, 1}, 	 // Disable flash encryption in Download boot mode,
 };
 
-static const esp_efuse_desc_t SPI_BOOT_ENCRYPT_DECRYPT_CNT[] = {
-    {EFUSE_BLK0, 39, 3}, 	 // /* TODO: Need Description*/,
+static const esp_efuse_desc_t SPI_BOOT_CRYPT_CNT[] = {
+    {EFUSE_BLK0, 39, 3}, 	 // Enable SPI boot encrypt/decrypt. Odd number: enable; even number: disable,
 };
 
 static const esp_efuse_desc_t XTS_KEY_LENGTH_256[] = {
-    {EFUSE_BLK0, 42, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 42, 1}, 	 // Select XTS_AES key length. 1: 256-bit of whole block3; 0: Lower 128-bit of block3,
 };
 
 static const esp_efuse_desc_t UART_PRINT_CONTROL[] = {
-    {EFUSE_BLK0, 43, 2}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 43, 2}, 	 // Set UART boot message output mode. 00: Force print; 01: Low-level print controlled by GPIO 8; 10: High-level print controlled by GPIO 8; 11: Print force disabled,
 };
 
 static const esp_efuse_desc_t FORCE_SEND_RESUME[] = {
-    {EFUSE_BLK0, 45, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 45, 1}, 	 // Force ROM code to send an SPI flash resume command during SPI boot,
 };
 
 static const esp_efuse_desc_t DIS_DOWNLOAD_MODE[] = {
-    {EFUSE_BLK0, 46, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 46, 1}, 	 // Disable all download boot modes,
 };
 
 static const esp_efuse_desc_t DIS_DIRECT_BOOT[] = {
-    {EFUSE_BLK0, 47, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 47, 1}, 	 // Disable direct_boot mode,
 };
 
 static const esp_efuse_desc_t ENABLE_SECURITY_DOWNLOAD[] = {
-    {EFUSE_BLK0, 48, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 48, 1}, 	 // Enable secure UART download mode,
 };
 
 static const esp_efuse_desc_t FLASH_TPUW[] = {
-    {EFUSE_BLK0, 49, 4}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 49, 4}, 	 // Configure flash startup delay after SoC being powered up (the unit is ms/2). When the value is 15 delay will be 7.5 ms,
 };
 
 static const esp_efuse_desc_t SECURE_BOOT_EN[] = {
-    {EFUSE_BLK0, 53, 1}, 	 // /* TODO: Need Description*/,
+    {EFUSE_BLK0, 53, 1}, 	 // Enable secure boot,
 };
 
-static const esp_efuse_desc_t SYSTEM_DATA0[] = {
-    {EFUSE_BLK1, 0, 32}, 	 // EFUSE_SYSTEM_DATA0,
+static const esp_efuse_desc_t SECURE_VERSION[] = {
+    {EFUSE_BLK0, 54, 4}, 	 // Secure version for anti-rollback,
 };
 
-static const esp_efuse_desc_t SYSTEM_DATA1[] = {
-    {EFUSE_BLK1, 32, 32}, 	 // EFUSE_SYSTEM_DATA1,
+static const esp_efuse_desc_t USER_DATA[] = {
+    {EFUSE_BLK1, 0, 88}, 	 // User data block,
 };
 
-static const esp_efuse_desc_t SYSTEM_DATA2[] = {
-    {EFUSE_BLK1, 64, 23}, 	 // EFUSE_SYSTEM_DATA2,
+static const esp_efuse_desc_t USER_DATA_MAC_CUSTOM[] = {
+    {EFUSE_BLK1, 0, 48}, 	 // Custom MAC addr,
 };
 
 static const esp_efuse_desc_t MAC_FACTORY[] = {
@@ -177,7 +189,19 @@ static const esp_efuse_desc_t ADC_CALIBRATION_2[] = {
 };
 
 static const esp_efuse_desc_t KEY0[] = {
-    {EFUSE_BLK3, 0, 256}, 	 // Key0 or user data,
+    {EFUSE_BLK3, 0, 256}, 	 // [256bit FE key] or [128bit FE key and 128key SB key] or [user data],
+};
+
+static const esp_efuse_desc_t KEY0_FE_256BIT[] = {
+    {EFUSE_BLK3, 0, 256}, 	 // [256bit FE key],
+};
+
+static const esp_efuse_desc_t KEY0_FE_128BIT[] = {
+    {EFUSE_BLK3, 0, 128}, 	 // [128bit FE key],
+};
+
+static const esp_efuse_desc_t KEY0_SB_128BIT[] = {
+    {EFUSE_BLK3, 128, 128}, 	 // [128bit SB key],
 };
 
 
@@ -195,17 +219,22 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0_RD_DIS[] = {
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_1[] = {
-    &WR_DIS_GROUP_1[0],    		// Write protection for WDT_DELAY DIS_PAD_JTAG
+    &WR_DIS_GROUP_1[0],    		// Write protection for WDT_DELAY DIS_PAD_JTAG DIS_DOWNLOAD_ICACHE
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_2[] = {
-    &WR_DIS_GROUP_2[0],    		// Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256
+    &WR_DIS_GROUP_2[0],    		// Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_CRYPT_CNT XTS_KEY_LENGTH_256 SECURE_BOOT_EN
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[] = {
+    &WR_DIS_SPI_BOOT_CRYPT_CNT[0],    		// Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT [SPI_BOOT_CRYPT_CNT] XTS_KEY_LENGTH_256 SECURE_BOOT_EN
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[] = {
-    &WR_DIS_GROUP_3[0],    		// Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN
+    &WR_DIS_GROUP_3[0],    		// Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW
     NULL
 };
 
@@ -225,7 +254,7 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[] = {
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0[] = {
-    &WR_DIS_KEY0[0],    		// Write protection for EFUSE_BLK3.  KEY0
+    &WR_DIS_KEY0[0],    		// Write protection for EFUSE_BLK3.  whole KEY0
     NULL
 };
 
@@ -239,83 +268,93 @@ const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0[] = {
     NULL
 };
 
+const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0_LOW[] = {
+    &RD_DIS_KEY0_LOW[0],    		// Read protection for EFUSE_BLK3.  KEY0 lower 128-bit key
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0_HI[] = {
+    &RD_DIS_KEY0_HI[0],    		// Read protection for EFUSE_BLK3.  KEY0 higher 128-bit key
+    NULL
+};
+
 const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[] = {
-    &WDT_DELAY_SEL[0],    		// /* TODO: Need Description*/
+    &WDT_DELAY_SEL[0],    		// RTC WDT timeout threshold
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[] = {
-    &DIS_PAD_JTAG[0],    		// /* TODO: Need Description*/
+    &DIS_PAD_JTAG[0],    		// Hardware Disable JTAG permanently
     NULL
 };
 
-const esp_efuse_desc_t* ESP_EFUSE_EFUSE_DIS_DOWNLOAD_ICACHE[] = {
-    &EFUSE_DIS_DOWNLOAD_ICACHE[0],    		// /* TODO: Need Description*/
+const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[] = {
+    &DIS_DOWNLOAD_ICACHE[0],    		// Disable ICache in Download mode
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
-    &DIS_DOWNLOAD_MANUAL_ENCRYPT[0],    		// /* TODO: Need Description*/
+    &DIS_DOWNLOAD_MANUAL_ENCRYPT[0],    		// Disable flash encryption in Download boot mode
     NULL
 };
 
-const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_ENCRYPT_DECRYPT_CNT[] = {
-    &SPI_BOOT_ENCRYPT_DECRYPT_CNT[0],    		// /* TODO: Need Description*/
+const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[] = {
+    &SPI_BOOT_CRYPT_CNT[0],    		// Enable SPI boot encrypt/decrypt. Odd number: enable; even number: disable
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_XTS_KEY_LENGTH_256[] = {
-    &XTS_KEY_LENGTH_256[0],    		// /* TODO: Need Description*/
+    &XTS_KEY_LENGTH_256[0],    		// Select XTS_AES key length. 1: 256-bit of whole block3; 0: Lower 128-bit of block3
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = {
-    &UART_PRINT_CONTROL[0],    		// /* TODO: Need Description*/
+    &UART_PRINT_CONTROL[0],    		// Set UART boot message output mode. 00: Force print; 01: Low-level print controlled by GPIO 8; 10: High-level print controlled by GPIO 8; 11: Print force disabled
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = {
-    &FORCE_SEND_RESUME[0],    		// /* TODO: Need Description*/
+    &FORCE_SEND_RESUME[0],    		// Force ROM code to send an SPI flash resume command during SPI boot
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[] = {
-    &DIS_DOWNLOAD_MODE[0],    		// /* TODO: Need Description*/
+    &DIS_DOWNLOAD_MODE[0],    		// Disable all download boot modes
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[] = {
-    &DIS_DIRECT_BOOT[0],    		// /* TODO: Need Description*/
+    &DIS_DIRECT_BOOT[0],    		// Disable direct_boot mode
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[] = {
-    &ENABLE_SECURITY_DOWNLOAD[0],    		// /* TODO: Need Description*/
+    &ENABLE_SECURITY_DOWNLOAD[0],    		// Enable secure UART download mode
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[] = {
-    &FLASH_TPUW[0],    		// /* TODO: Need Description*/
+    &FLASH_TPUW[0],    		// Configure flash startup delay after SoC being powered up (the unit is ms/2). When the value is 15 delay will be 7.5 ms
     NULL
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[] = {
-    &SECURE_BOOT_EN[0],    		// /* TODO: Need Description*/
+    &SECURE_BOOT_EN[0],    		// Enable secure boot
     NULL
 };
 
-const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA0[] = {
-    &SYSTEM_DATA0[0],    		// EFUSE_SYSTEM_DATA0
+const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[] = {
+    &SECURE_VERSION[0],    		// Secure version for anti-rollback
     NULL
 };
 
-const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA1[] = {
-    &SYSTEM_DATA1[0],    		// EFUSE_SYSTEM_DATA1
+const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[] = {
+    &USER_DATA[0],    		// User data block
     NULL
 };
 
-const esp_efuse_desc_t* ESP_EFUSE_SYSTEM_DATA2[] = {
-    &SYSTEM_DATA2[0],    		// EFUSE_SYSTEM_DATA2
+const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[] = {
+    &USER_DATA_MAC_CUSTOM[0],    		// Custom MAC addr
     NULL
 };
 
@@ -385,6 +424,21 @@ const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_2[] = {
 };
 
 const esp_efuse_desc_t* ESP_EFUSE_KEY0[] = {
-    &KEY0[0],    		// Key0 or user data
+    &KEY0[0],    		// [256bit FE key] or [128bit FE key and 128key SB key] or [user data]
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_256BIT[] = {
+    &KEY0_FE_256BIT[0],    		// [256bit FE key]
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_128BIT[] = {
+    &KEY0_FE_128BIT[0],    		// [128bit FE key]
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_KEY0_SB_128BIT[] = {
+    &KEY0_SB_128BIT[0],    		// [128bit SB key]
     NULL
 };

+ 32 - 33
components/efuse/esp32c2/esp_efuse_table.csv

@@ -1,10 +1,8 @@
 # field_name,       |    efuse_block, | bit_start, | bit_count, |comment #
-#                   |    (EFUSE_BLK0  | (0..255)   | (1..-)     |        #
-#                   |     EFUSE_BLK1  |            |MAX_BLK_LEN*|        #
-#                   |        ...      |            |            |        #
-#                   |     EFUSE_BLK10)|            |            |        #
+#                   |    (EFUSE_BLK0  | (0..255)   | (1-256)    |        #
+#                   |     EFUSE_BLK1  |            |            |        #
+#                   |     EFUSE_BLK3) |            |            |        #
 ##########################################################################
-# *) The value MAX_BLK_LEN depends on CONFIG_EFUSE_MAX_BLK_LEN, will be replaced with "None" - 256. "3/4" - 192. "REPEAT" - 128.
 # !!!!!!!!!!! #
 # After editing this file, run the command manually "make efuse_common_table" or "idf.py efuse_common_table"
 # this will generate new source files, next rebuild all the sources.
@@ -15,39 +13,40 @@
     # EFUSE_RD_WR_DIS_REG #
         WR_DIS,                           EFUSE_BLK0,    0,    8,      Write protection
             WR_DIS.KEY0_RD_DIS,           EFUSE_BLK0,    0,    1,      Write protection for KEY0_RD_DIS
-            WR_DIS.GROUP_1,               EFUSE_BLK0,    1,    1,      Write protection for WDT_DELAY DIS_PAD_JTAG
-            WR_DIS.GROUP_2,               EFUSE_BLK0,    2,    1,      Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_ENCRYPT_DECRYPT_CNT XTS_KEY_LENGTH_256
-            WR_DIS.GROUP_3,               EFUSE_BLK0,    3,    1,      Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW SECURE_BOOT_EN
+            WR_DIS.GROUP_1,               EFUSE_BLK0,    1,    1,      Write protection for WDT_DELAY DIS_PAD_JTAG DIS_DOWNLOAD_ICACHE
+            WR_DIS.GROUP_2,               EFUSE_BLK0,    2,    1,      Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT SPI_BOOT_CRYPT_CNT XTS_KEY_LENGTH_256 SECURE_BOOT_EN
+            WR_DIS.SPI_BOOT_CRYPT_CNT,    EFUSE_BLK0,    2,    1,      Write protection for DOWNLOAD_DIS_MANUAL_ENCRYPT [SPI_BOOT_CRYPT_CNT] XTS_KEY_LENGTH_256 SECURE_BOOT_EN
+            WR_DIS.GROUP_3,               EFUSE_BLK0,    3,    1,      Write protection for UART_PRINT_CONTROL FORCE_SEND_RESUME DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT ENABLE_SECURITY_DOWNLOAD FLASH_TPUW
             WR_DIS.BLK0_RESERVED,         EFUSE_BLK0,    4,    1,      Write protection for BLK0_RESERVED
             WR_DIS.SYS_DATA_PART0,        EFUSE_BLK0,    5,    1,      Write protection for EFUSE_BLK1.  SYS_DATA_PART0
             WR_DIS.SYS_DATA_PART1,        EFUSE_BLK0,    6,    1,      Write protection for EFUSE_BLK2.  SYS_DATA_PART2
-            WR_DIS.KEY0,                  EFUSE_BLK0,    7,    1,      Write protection for EFUSE_BLK3.  KEY0
-
+            WR_DIS.KEY0,                  EFUSE_BLK0,    7,    1,      Write protection for EFUSE_BLK3.  whole KEY0
     # EFUSE_RD_REPEAT_DATA0_REG #
-        RD_DIS,                           EFUSE_BLK0,    8,    2,      Read protection
-            RD_DIS.KEY0,                  EFUSE_BLK0,    8,    2,      Read protection for EFUSE_BLK3.  KEY0
+        RD_DIS,                           EFUSE_BLK0,   32,    2,      Read protection
+            RD_DIS.KEY0,                  EFUSE_BLK0,   32,    2,      Read protection for EFUSE_BLK3.  KEY0
+            RD_DIS.KEY0.LOW,              EFUSE_BLK0,   32,    1,      Read protection for EFUSE_BLK3.  KEY0 lower 128-bit key
+            RD_DIS.KEY0.HI,               EFUSE_BLK0,   33,    1,      Read protection for EFUSE_BLK3.  KEY0 higher 128-bit key
 
-        WDT_DELAY_SEL,                    EFUSE_BLK0,   10,    2,      /* TODO: Need Description*/
-        DIS_PAD_JTAG,                     EFUSE_BLK0,   12,    1,      /* TODO: Need Description*/
-        EFUSE_DIS_DOWNLOAD_ICACHE,        EFUSE_BLK0,   13,    1,      /* TODO: Need Description*/
-        DIS_DOWNLOAD_MANUAL_ENCRYPT,      EFUSE_BLK0,   14,    1,      /* TODO: Need Description*/
-        SPI_BOOT_ENCRYPT_DECRYPT_CNT,     EFUSE_BLK0,   15,    3,      /* TODO: Need Description*/
-        XTS_KEY_LENGTH_256,               EFUSE_BLK0,   18,    1,      /* TODO: Need Description*/
-        UART_PRINT_CONTROL,               EFUSE_BLK0,   19,    2,      /* TODO: Need Description*/
-        FORCE_SEND_RESUME,                EFUSE_BLK0,   21,    1,      /* TODO: Need Description*/
-        DIS_DOWNLOAD_MODE,                EFUSE_BLK0,   22,    1,      /* TODO: Need Description*/
-        DIS_DIRECT_BOOT,                  EFUSE_BLK0,   23,    1,      /* TODO: Need Description*/
-        ENABLE_SECURITY_DOWNLOAD,         EFUSE_BLK0,   24,    1,      /* TODO: Need Description*/
-        FLASH_TPUW,                       EFUSE_BLK0,   25,    4,      /* TODO: Need Description*/
-        SECURE_BOOT_EN,                   EFUSE_BLK0,   29,    1,      /* TODO: Need Description*/
+        WDT_DELAY_SEL,                    EFUSE_BLK0,   34,    2,      RTC WDT timeout threshold
+        DIS_PAD_JTAG,                     EFUSE_BLK0,   36,    1,      Hardware Disable JTAG permanently
+        DIS_DOWNLOAD_ICACHE,              EFUSE_BLK0,   37,    1,      Disable ICache in Download mode
+        DIS_DOWNLOAD_MANUAL_ENCRYPT,      EFUSE_BLK0,   38,    1,      Disable flash encryption in Download boot mode
+        SPI_BOOT_CRYPT_CNT,               EFUSE_BLK0,   39,    3,      Enable SPI boot encrypt/decrypt. Odd number: enable; even number: disable
+        XTS_KEY_LENGTH_256,               EFUSE_BLK0,   42,    1,      Select XTS_AES key length. 1: 256-bit of whole block3; 0: Lower 128-bit of block3
+        UART_PRINT_CONTROL,               EFUSE_BLK0,   43,    2,      Set UART boot message output mode. 00: Force print; 01: Low-level print controlled by GPIO 8; 10: High-level print controlled by GPIO 8; 11: Print force disabled
+        FORCE_SEND_RESUME,                EFUSE_BLK0,   45,    1,      Force ROM code to send an SPI flash resume command during SPI boot
+        DIS_DOWNLOAD_MODE,                EFUSE_BLK0,   46,    1,      Disable all download boot modes
+        DIS_DIRECT_BOOT,                  EFUSE_BLK0,   47,    1,      Disable direct_boot mode
+        ENABLE_SECURITY_DOWNLOAD,         EFUSE_BLK0,   48,    1,      Enable secure UART download mode
+        FLASH_TPUW,                       EFUSE_BLK0,   49,    4,      Configure flash startup delay after SoC being powered up (the unit is ms/2). When the value is 15 delay will be 7.5 ms
+        SECURE_BOOT_EN,                   EFUSE_BLK0,   53,    1,      Enable secure boot
+        SECURE_VERSION,                   EFUSE_BLK0,   54,    4,      Secure version for anti-rollback
 
 
-# SYS_DATA_PART0 BLOCK# - System configuration
+# USER_DATA BLOCK# - System configuration
 #######################
-    SYSTEM_DATA0,                         EFUSE_BLK1,    0,   32,     EFUSE_SYSTEM_DATA0
-    SYSTEM_DATA1,                         EFUSE_BLK1,   32,   32,     EFUSE_SYSTEM_DATA1
-    SYSTEM_DATA2,                         EFUSE_BLK1,   64,   23,     EFUSE_SYSTEM_DATA2
-
+    USER_DATA,                            EFUSE_BLK1,    0,   88,     User data block
+    USER_DATA.MAC_CUSTOM,                 EFUSE_BLK1,    0,   48,     Custom MAC addr
 
 
 # SYS_DATA_PART1 BLOCK# - System configuration
@@ -77,6 +76,6 @@
 
 ################
 KEY0,                                     EFUSE_BLK3,    0,  256,     [256bit FE key] or [128bit FE key and 128key SB key] or [user data]
-KEY0.FLASH_ENCRYPTION                     EFUSE_BLK3,    0,  256,     [256bit FE key]
-KEY0.FLASH_ENCRYPTION_128                 EFUSE_BLK3,    0,  128,     [128bit FE key]
-KEY0.SECURE_BOOT_128                      EFUSE_BLK3,    128, 256,    [128bit SB key]
+KEY0.FE_256BIT,                           EFUSE_BLK3,    0,  256,     [256bit FE key]
+KEY0.FE_128BIT,                           EFUSE_BLK3,    0,  128,     [128bit FE key]
+KEY0.SB_128BIT,                           EFUSE_BLK3,  128,  128,     [128bit SB key]

+ 84 - 7
components/efuse/esp32c2/esp_efuse_utility.c

@@ -13,24 +13,84 @@
 #include "esp_private/esp_clk.h"
 #include "esp32c2/rom/efuse.h"
 
+static const char *TAG = "efuse";
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
+#endif // CONFIG_EFUSE_VIRTUAL
+
 /*Range addresses to read blocks*/
 const esp_efuse_range_addr_t range_read_addr_blocks[] = {
-    {EFUSE_RD_WR_DIS_REG,       EFUSE_RD_REPEAT_DATA0_REG},      // range address of EFUSE_BLK0  REPEAT
-    {EFUSE_RD_BLK1_DATA0_REG,   EFUSE_RD_BLK1_DATA2_REG},        // range address of EFUSE_BLK1  SYS_DATA_PART0
-    {EFUSE_RD_BLK2_DATA0_REG,   EFUSE_RD_BLK2_DATA7_REG},        // range address of EFUSE_BLK2  SYS_DATA_PART_1
-    {EFUSE_RD_BLK3_DATA0_REG,   EFUSE_RD_BLK3_DATA7_REG},        // range address of EFUSE_BLK3  KEY0
+    {EFUSE_RD_WR_DIS_REG,       EFUSE_RD_REPEAT_DATA0_REG}, // range address of EFUSE_BLK0 (2 regs) REPEAT
+    {EFUSE_RD_BLK1_DATA0_REG,   EFUSE_RD_BLK1_DATA2_REG},   // range address of EFUSE_BLK1 (3 regs) SYS_DATA_PART0
+    {EFUSE_RD_BLK2_DATA0_REG,   EFUSE_RD_BLK2_DATA7_REG},   // range address of EFUSE_BLK2 (8 regs) SYS_DATA_PART_1
+    {EFUSE_RD_BLK3_DATA0_REG,   EFUSE_RD_BLK3_DATA7_REG},   // range address of EFUSE_BLK3 (8 regs) KEY0
+};
+
+static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
+
+/*Range addresses to write blocks (it is not real regs, it is buffer) */
+const esp_efuse_range_addr_t range_write_addr_blocks[] = {
+    {(uint32_t) &write_mass_blocks[EFUSE_BLK0][0],  (uint32_t) &write_mass_blocks[EFUSE_BLK0][1]},
+    {(uint32_t) &write_mass_blocks[EFUSE_BLK1][0],  (uint32_t) &write_mass_blocks[EFUSE_BLK1][2]},
+    {(uint32_t) &write_mass_blocks[EFUSE_BLK2][0],  (uint32_t) &write_mass_blocks[EFUSE_BLK2][7]},
+    {(uint32_t) &write_mass_blocks[EFUSE_BLK3][0],  (uint32_t) &write_mass_blocks[EFUSE_BLK3][7]},
 };
 
+#ifndef CONFIG_EFUSE_VIRTUAL
+// Update Efuse timing configuration
+static esp_err_t esp_efuse_set_timing(void)
+{
+    // no need to set special timing values
+    return ESP_OK;
+}
+#endif // ifndef CONFIG_EFUSE_VIRTUAL
+
 // Efuse read operation: copies data from physical efuses to efuse read registers.
 void esp_efuse_utility_clear_program_registers(void)
 {
-    abort();
+    ets_efuse_read();
+    ets_efuse_clear_program_registers();
 }
 
 // Burn values written to the efuse write registers
 void esp_efuse_utility_burn_chip(void)
 {
-    abort();
+#ifdef CONFIG_EFUSE_VIRTUAL
+    ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
+    for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
+        int subblock = 0;
+        for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
+            virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block);
+        }
+    }
+#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
+    esp_efuse_utility_write_efuses_to_flash();
+#endif
+#else
+    if (esp_efuse_set_timing() != ESP_OK) {
+        ESP_LOGE(TAG, "Efuse fields are not burnt");
+    } else {
+        // Permanently update values written to the efuse write registers
+        // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks.
+        for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
+            for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
+                if (REG_READ(addr_wr_block) != 0) {
+                    if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
+                        uint8_t block_rs[12];
+                        ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
+                        memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
+                    }
+                    int data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t);
+                    memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len);
+                    ets_efuse_program(num_block);
+                    break;
+                }
+            }
+        }
+    }
+#endif // CONFIG_EFUSE_VIRTUAL
+    esp_efuse_utility_reset();
 }
 
 // After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values.
@@ -39,5 +99,22 @@ void esp_efuse_utility_burn_chip(void)
 // They will be filled during the burn operation.
 esp_err_t esp_efuse_utility_apply_new_coding_scheme()
 {
-    abort();
+    // start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
+    for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
+        if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
+            for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
+                if (REG_READ(addr_wr_block)) {
+                    int num_reg = 0;
+                    for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, ++num_reg) {
+                        if (esp_efuse_utility_read_reg(num_block, num_reg)) {
+                            ESP_LOGE(TAG, "Bits are not empty. Write operation is forbidden.");
+                            return ESP_ERR_CODING;
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    return ESP_OK;
 }

+ 12 - 13
components/efuse/esp32c2/include/esp_efuse.h

@@ -11,7 +11,7 @@ extern "C" {
 #endif
 
 /**
- * @brief Type of eFuse blocks ESP32C2
+ * @brief Type of eFuse blocks
  */
 typedef enum {
     EFUSE_BLK0                 = 0,   /**< Number of eFuse BLOCK0. REPEAT_DATA */
@@ -22,11 +22,11 @@ typedef enum {
     EFUSE_BLK2                 = 2,   /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
     EFUSE_BLK_SYS_DATA_PART1   = 2,   /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
 
-    EFUSE_BLK3                 = 3,   /**< Number of eFuse BLOCK3. KEY0*/
-    EFUSE_BLK_KEY0             = 3,   /**< Number of eFuse BLOCK3. KEY0*/
+    EFUSE_BLK3                 = 3,   /**< Number of eFuse BLOCK3. KEY0. whole block */
+    EFUSE_BLK_KEY0             = 3,   /**< Number of eFuse BLOCK3. KEY0. whole block */
     EFUSE_BLK_KEY_MAX          = 4,
 
-    EFUSE_BLK_MAX              = 4,
+    EFUSE_BLK_MAX              = 4,   /**< Number of eFuse blocks */
 } esp_efuse_block_t;
 
 /**
@@ -37,16 +37,15 @@ typedef enum {
     EFUSE_CODING_SCHEME_RS      = 3,    /**< Reed-Solomon coding */
 } esp_efuse_coding_scheme_t;
 
-/** For ESP32C2, there's no key purpose region for efuse keys, In order to maintain
-  * compatibility with the previous apis, we should set the parameter of 'ets_efuse_purpose_t'
-  * as default value ETS_EFUSE_KEY_PURPOSE_INVALID.
-  * (In fact, this parameter can be any value, the api in the rom will not process key_purpose region)
-  */
+/**
+ * @brief Type of key purposes (they are virtual because this chip has only fixed purposes for block)
+ */
 typedef enum {
-    ESP_EFUSE_KEY_PURPOSE_INVALID = -1,
-    ESP_EFUSE_KEY_PURPOSE_USER = 0,
-    ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION = 1,
-    ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V1 = 2,
+    ESP_EFUSE_KEY_PURPOSE_USER              = 0,    /**< whole BLOCK3 */
+    ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY   = 1,    /**< FE uses the whole BLOCK3 (key is 256-bits) */
+    ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY    = 2,    /**< FE uses lower 128-bits of BLOCK3 (key is 128-bits) */
+    ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2    = 3,    /**< SB uses higher 128-bits of BLOCK3 (key is 128-bits) */
+    ESP_EFUSE_KEY_PURPOSE_MAX,                      /**< MAX PURPOSE */
 } esp_efuse_purpose_t;
 
 #ifdef __cplusplus

+ 27 - 104
components/efuse/esp32c2/include/esp_efuse_table.h

@@ -9,7 +9,7 @@ extern "C" {
 #endif
 
 
-// md5_digest_table 3f91b5a37afbcdf1379820626a92e69c
+// md5_digest_table af57e8a6a405ebf239cc552f713c91d0
 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
 // If you want to change some fields, you need to change esp_efuse_table.csv file
 // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@@ -17,128 +17,51 @@ extern "C" {
 
 
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[];
+extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0_RD_DIS[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_1[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_2[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5_PURPOSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
+extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK0_RESERVED[];
+extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART0[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USER_DATA[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY4[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY5[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART2[];
 extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[];
 extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY4[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY5[];
-extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_SYS_DATA_PART2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_RTC_RAM_BOOT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_ICACHE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DEVICE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_CAN[];
-extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[];
+extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0_LOW[];
+extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_KEY0_HI[];
+extern const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[];
 extern const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[];
+extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[];
 extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_USB_DREFH[];
-extern const esp_efuse_desc_t* ESP_EFUSE_USB_DREFL[];
-extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[];
-extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_AS_GPIO[];
-extern const esp_efuse_desc_t* ESP_EFUSE_BTLC_GPIO_ENABLE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_POWERGLITCH_EN[];
-extern const esp_efuse_desc_t* ESP_EFUSE_POWER_GLITCH_DSENSE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[];
 extern const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[];
-extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[];
+extern const esp_efuse_desc_t* ESP_EFUSE_XTS_KEY_LENGTH_256[];
 extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[];
-extern const esp_efuse_desc_t* ESP_EFUSE_PIN_POWER_SELECTION[];
-extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TYPE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[];
 extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[];
+extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[];
+extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[];
+extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[];
+extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[];
+extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[];
 extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[];
+extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
+extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];
 extern const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CLK[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_Q_D1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D_D0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CS[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_HD_D3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_WP_D2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_DQS[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D4[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D5[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[];
 extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[];
 extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
-extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK1_VERSION[];
-extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[];
 extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[];
-extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[];
-extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
-extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];
+extern const esp_efuse_desc_t* ESP_EFUSE_RF_REF_I_BIAS_CONFIG[];
+extern const esp_efuse_desc_t* ESP_EFUSE_LDO_VOL_BIAS_CONFIG_LOW[];
+extern const esp_efuse_desc_t* ESP_EFUSE_LDO_VOL_BIAS_CONFIG_HIGH[];
+extern const esp_efuse_desc_t* ESP_EFUSE_PVT_LOW[];
+extern const esp_efuse_desc_t* ESP_EFUSE_PVT_HIGH[];
+extern const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_0[];
+extern const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_1[];
+extern const esp_efuse_desc_t* ESP_EFUSE_ADC_CALIBRATION_2[];
 extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY3[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY4[];
-extern const esp_efuse_desc_t* ESP_EFUSE_KEY5[];
-extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[];
-extern const esp_efuse_desc_t* ESP_EFUSE_K_RTC_LDO[];
-extern const esp_efuse_desc_t* ESP_EFUSE_K_DIG_LDO[];
-extern const esp_efuse_desc_t* ESP_EFUSE_V_RTC_DBIAS20[];
-extern const esp_efuse_desc_t* ESP_EFUSE_V_DIG_DBIAS20[];
-extern const esp_efuse_desc_t* ESP_EFUSE_DIG_DBIAS_HVT[];
-extern const esp_efuse_desc_t* ESP_EFUSE_THRES_HVT[];
+extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_256BIT[];
+extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_128BIT[];
+extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_SB_128BIT[];
 
 #ifdef __cplusplus
 }

+ 5 - 3
components/efuse/include/esp_efuse.h

@@ -599,8 +599,7 @@ bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block);
  */
 esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block);
 
-
-#ifndef CONFIG_IDF_TARGET_ESP32
+#if SOC_EFUSE_KEY_PURPOSE_FIELD
 /**
  * @brief Returns a pointer to a key purpose for an efuse key block.
  *
@@ -662,6 +661,9 @@ esp_efuse_block_t esp_efuse_find_unused_key_block(void);
  */
 unsigned esp_efuse_count_unused_key_blocks(void);
 
+#endif // SOC_EFUSE_KEY_PURPOSE_FIELD
+
+#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
 /**
  * @brief Returns the status of the Secure Boot public key digest revocation bit.
  *
@@ -709,7 +711,7 @@ bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest);
  */
 esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest);
 
-#endif // not CONFIG_IDF_TARGET_ESP32
+#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
 
 /**
  * @brief Program a block of key data to an efuse block

+ 7 - 23
components/efuse/src/esp_efuse_api_key_esp32xx.c → components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c

@@ -11,6 +11,11 @@
 #include "sdkconfig.h"
 #include "esp_efuse_table.h"
 
+/*
+ * Each eFuse key block has a special field that defines the purpose of this block.
+ * This special field is called key_purpose.
+ */
+
 const static char *TAG = "efuse";
 
 /**
@@ -31,9 +36,6 @@ typedef struct {
 } esp_efuse_revokes_t;
 
 const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
-#if CONFIG_IDF_TARGET_ESP32C2
-    {ESP_EFUSE_KEY0, NULL, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, NULL},
-#else
     {ESP_EFUSE_KEY0, ESP_EFUSE_KEY_PURPOSE_0, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0_PURPOSE},
     {ESP_EFUSE_KEY1, ESP_EFUSE_KEY_PURPOSE_1, ESP_EFUSE_RD_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1_PURPOSE},
     {ESP_EFUSE_KEY2, ESP_EFUSE_KEY_PURPOSE_2, ESP_EFUSE_RD_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2_PURPOSE},
@@ -43,7 +45,6 @@ const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
 #if 0
     {ESP_EFUSE_KEY6, ESP_EFUSE_KEY_PURPOSE_6, ESP_EFUSE_RD_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6_PURPOSE},
 #endif
-#endif //#if CONFIG_IDF_TARGET_ESP32C2
 };
 
 #if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
@@ -76,7 +77,6 @@ bool esp_efuse_block_is_empty(esp_efuse_block_t block)
 // Sets a write protection for the whole block.
 esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
 {
-#if !CONFIG_IDF_TARGET_ESP32C2
     if (blk == EFUSE_BLK1) {
         return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
     } else if (blk == EFUSE_BLK2) {
@@ -89,8 +89,7 @@ esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
         unsigned idx = blk - EFUSE_BLK_KEY0;
         return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, 1);
     }
-#endif
-    return ESP_ERR_NOT_SUPPORTED; // IDF-3818
+    return ESP_ERR_NOT_SUPPORTED;
 }
 
 // read protect for blk.
@@ -100,11 +99,9 @@ esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
         unsigned idx = blk - EFUSE_BLK_KEY0;
         return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, 1);
     }
-#if !CONFIG_IDF_TARGET_ESP32C2 // IDF-3818
     else if (blk == EFUSE_BLK10) {
         return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
     }
-#endif
     return ESP_ERR_NOT_SUPPORTED;
 
 }
@@ -171,7 +168,6 @@ esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
     return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
 }
 
-#if !CONFIG_IDF_TARGET_ESP32C2 // cause esp32c2 efuse has no purpose region
 esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
 {
     if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
@@ -194,7 +190,6 @@ esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t
     unsigned idx = block - EFUSE_BLK_KEY0;
     return esp_efuse_write_field_blob(s_table[idx].keypurpose, &purpose, s_table[idx].keypurpose[0]->bit_count);
 }
-#endif //CONFIG_IDF_TARGET_ESP32C2
 
 bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
 {
@@ -256,11 +251,8 @@ bool esp_efuse_key_block_unused(esp_efuse_block_t block)
         return false; // Not a key block
     }
 
-    if (
-#if !CONFIG_IDF_TARGET_ESP32C2
-            esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
+    if (esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
             esp_efuse_get_keypurpose_dis_write(block) ||
-#endif
             esp_efuse_get_key_dis_read(block) ||
             esp_efuse_get_key_dis_write(block)) {
         return false; // Block in use!
@@ -277,15 +269,9 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
 {
     esp_err_t err = ESP_OK;
 
-#if CONFIG_IDF_TARGET_ESP32C2
-    if (block != EFUSE_BLK_KEY0) {
-        return ESP_ERR_INVALID_ARG;
-    }
-#else
     if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX || key_size_bytes > 32 || purpose >= ESP_EFUSE_KEY_PURPOSE_MAX) {
         return ESP_ERR_INVALID_ARG;
     }
-#endif
 
     esp_efuse_batch_write_begin();
 
@@ -296,7 +282,6 @@ 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 !CONFIG_IDF_TARGET_ESP32C2
         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 ||
@@ -310,7 +295,6 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
         }
         ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
         ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block));
-#endif //#if !CONFIG_IDF_TARGET_ESP32C2
         return esp_efuse_batch_write_commit();
     }
 err_exit:

+ 247 - 0
components/efuse/src/efuse_controller/keys/without_key_purposes/one_key_block/esp_efuse_api_key.c

@@ -0,0 +1,247 @@
+/*
+ * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "esp_efuse.h"
+#include "esp_efuse_utility.h"
+#include "soc/efuse_periph.h"
+#include "assert.h"
+#include "sdkconfig.h"
+#include "esp_efuse_table.h"
+
+/*
+ * The chip has only one eFuse key block.
+ * There are no eFuse key purpose fields (added only virtual key purposes to support key APIs).
+ * Flash Encryption key and Secure Boot key reside in one eFuse block.
+ * To burn the FE key and the SB key need to use the batch mode to do it at once.
+ */
+
+static esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose);
+
+static __attribute__((unused)) const char *TAG = "efuse";
+
+/**
+ * @brief Keys and their attributes are packed into a structure
+ */
+typedef struct {
+    const esp_efuse_desc_t** key;               /**< Key */
+    esp_efuse_purpose_t purpose;                /**< purpose of block */
+    const esp_efuse_desc_t** key_rd_dis;        /**< Read protection of a key */
+    const esp_efuse_desc_t** key_wr_dis;        /**< Write protection of a key*/
+} esp_efuse_keys_t;
+
+const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
+    {ESP_EFUSE_KEY0,            ESP_EFUSE_KEY_PURPOSE_USER,             ESP_EFUSE_RD_DIS_KEY0,     ESP_EFUSE_WR_DIS_KEY0},  // EFUSE_BLK_KEY0
+};
+
+// Sets a write protection for the whole block.
+esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
+{
+    if (blk < EFUSE_BLK_KEY0 || blk >= EFUSE_BLK_KEY_MAX) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    unsigned idx = blk - EFUSE_BLK_KEY0;
+    return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, s_table[idx].key_wr_dis[0]->bit_count);
+}
+
+// Sets a read protection for the whole block.
+esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
+{
+    if (blk < EFUSE_BLK_KEY0 || blk >= EFUSE_BLK_KEY_MAX) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    unsigned idx = blk - EFUSE_BLK_KEY0;
+    return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, s_table[idx].key_rd_dis[0]->bit_count);
+}
+
+// get efuse coding_scheme.
+esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
+{
+    esp_efuse_coding_scheme_t scheme;
+    if (blk == EFUSE_BLK0) {
+        scheme = EFUSE_CODING_SCHEME_NONE;
+    } else {
+        scheme = EFUSE_CODING_SCHEME_RS;
+    }
+    return scheme;
+}
+
+bool esp_efuse_block_is_empty(esp_efuse_block_t block)
+{
+    assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
+    const unsigned blk_len_bit = 256;
+    uint32_t key[8];
+    esp_err_t err = esp_efuse_read_block(block, &key, 0, blk_len_bit);
+    if (err != ESP_OK) {
+        return false;
+    }
+    unsigned zeros = 0;
+    for (unsigned i = 0; i < blk_len_bit / 32; ++i) {
+        if (key[i] == 0) {
+            ++zeros;
+        }
+    }
+    if (zeros == blk_len_bit / 32) {
+        return true;
+    }
+    return false;
+}
+
+bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)
+{
+    assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
+    unsigned idx = block - EFUSE_BLK_KEY0;
+    if (esp_efuse_get_key_purpose(block) == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
+        uint8_t value = 0;
+        esp_err_t err = esp_efuse_read_field_blob(s_table[idx].key_rd_dis, &value, s_table[idx].key_rd_dis[0]->bit_count);
+        assert(err == ESP_OK);
+        return (err == ESP_OK) && (value == ((1 << s_table[idx].key_rd_dis[0]->bit_count) - 1));
+    }
+    return esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_KEY0_LOW);
+}
+
+esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
+{
+    if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (esp_efuse_get_key_purpose(block) == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
+        unsigned idx = block - EFUSE_BLK_KEY0;
+        uint8_t value = (1 << s_table[idx].key_rd_dis[0]->bit_count) - 1;
+        return esp_efuse_write_field_blob(s_table[idx].key_rd_dis, &value, s_table[idx].key_rd_dis[0]->bit_count);
+    }
+    return esp_efuse_write_field_bit(ESP_EFUSE_RD_DIS_KEY0_LOW);
+}
+
+bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
+{
+    assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
+    unsigned idx = block - EFUSE_BLK_KEY0;
+    return esp_efuse_read_field_bit(s_table[idx].key_wr_dis);
+}
+
+esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
+{
+    if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    unsigned idx = block - EFUSE_BLK_KEY0;
+    return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
+}
+
+bool esp_efuse_key_block_unused(esp_efuse_block_t block)
+{
+    if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
+        return false; // Not a key block
+    }
+
+    if (esp_efuse_get_key_dis_read(block) || esp_efuse_get_key_dis_write(block) ||
+            !esp_efuse_block_is_empty(block)) {
+        return false; // Block in use!
+    }
+
+    return true; // Unused
+}
+
+esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
+{
+    if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
+        return ESP_EFUSE_KEY_PURPOSE_MAX;
+    }
+    if (esp_efuse_read_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256)) {
+        return ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
+    }
+    return ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY;
+}
+
+
+static esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose)
+{
+    (void)block;
+    if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
+        return esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256);
+    }
+    return ESP_OK;
+}
+
+bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
+{
+    (void)block;
+    return true;
+}
+
+bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block)
+{
+    (void)purpose;
+    esp_efuse_block_t dummy;
+    if (block == NULL) {
+        block = &dummy;
+    }
+    *block = EFUSE_BLK_KEY0;
+    return true;
+}
+
+esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes)
+{
+    esp_err_t err = ESP_OK;
+    if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX || key_size_bytes > 32 || purpose >= ESP_EFUSE_KEY_PURPOSE_MAX) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if ((purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY) && (key_size_bytes != 16)) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    esp_efuse_batch_write_begin();
+
+    if (!esp_efuse_key_block_unused(block)) {
+        err = ESP_ERR_INVALID_STATE;
+    } else {
+        size_t offset_in_bits = (purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) ? 16 * 8 : 0;
+        ESP_EFUSE_CHK(esp_efuse_write_block(block, key, offset_in_bits, key_size_bytes * 8));
+        if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
+            ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
+        }
+        if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY) {
+            ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
+        }
+        ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block));
+        return esp_efuse_batch_write_commit();
+    }
+err_exit:
+    esp_efuse_batch_write_cancel();
+    return err;
+}
+
+esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)
+{
+    esp_err_t err = ESP_FAIL;
+    if (number_of_keys == 0 || number_of_keys > 2 || keys == NULL || purposes == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    esp_efuse_purpose_t purpose = 0;
+
+    esp_efuse_batch_write_begin();
+    for (unsigned i_key = 0; i_key < number_of_keys; i_key++) {
+        purpose = purposes[i_key];
+        ESP_LOGI(TAG, "Writing EFUSE_BLK_KEY0 with purpose %d", purpose);
+        size_t key_size = (purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY) ? 16 : 32;
+        ESP_EFUSE_CHK(esp_efuse_write_key(EFUSE_BLK_KEY0, purpose, keys[i_key], key_size));
+    }
+    return esp_efuse_batch_write_commit();
+err_exit:
+    ESP_LOGE(TAG, "Failed to write EFUSE_BLK_KEY0 with purpose %d. Can't continue.", purpose);
+    esp_efuse_batch_write_cancel();
+    return err;
+}
+
+esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys)
+{
+    if (trusted_keys == NULL) {
+        return ESP_FAIL;
+    }
+    trusted_keys->key_digests[0] = (const void *)(esp_efuse_utility_get_read_register_address(EFUSE_BLK_KEY0) + 16);
+    return ESP_OK;
+}

+ 8 - 1
components/efuse/src/esp_efuse_api_key_esp32.c → components/efuse/src/efuse_controller/keys/without_key_purposes/three_key_blocks/esp_efuse_api_key.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -11,6 +11,13 @@
 #include "sdkconfig.h"
 #include "esp_efuse_table.h"
 
+/*
+ * FE uses eFuse block1.
+ * SB uses eFuse block2.
+ * Block3 can be used by customer.
+ * There are no eFuse key purpose fields (added only virtual key purposes to support key APIs).
+ */
+
 static __attribute__((unused)) const char *TAG = "efuse";
 
 /**

+ 1 - 4
components/efuse/src/esp_efuse_fields.c

@@ -24,7 +24,7 @@ static __attribute__((unused)) const char *TAG = "efuse";
 #ifdef CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
 #define APP_SEC_VER_SIZE_EFUSE_FIELD CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
 #else
-#define APP_SEC_VER_SIZE_EFUSE_FIELD 16 // smallest possible size for all chips
+#define APP_SEC_VER_SIZE_EFUSE_FIELD 4 // smallest possible size for all chips
 #endif
 
 // Reset efuse write registers
@@ -33,8 +33,6 @@ void esp_efuse_reset(void)
     esp_efuse_utility_reset();
 }
 
-#if !CONFIG_IDF_TARGET_ESP32C2
-// IDF-3818
 uint32_t esp_efuse_read_secure_version(void)
 {
     uint32_t secure_version = 0;
@@ -85,4 +83,3 @@ esp_err_t esp_efuse_update_secure_version(uint32_t secure_version)
     }
     return ESP_OK;
 }
-#endif

+ 14 - 2
components/efuse/test/CMakeLists.txt

@@ -1,6 +1,18 @@
 idf_build_get_property(target IDF_TARGET)
 
-idf_component_register(SRC_DIRS "."
-                       PRIV_INCLUDE_DIRS "." "include" "../private_include" ../${target}/private_include
+if(CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD)
+    set(dir "with_key_purposes")
+else()
+    if(CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK)
+        set(dir "one_key_block")
+    else()
+        set(dir "three_key_blocks")
+    endif()
+endif()
+
+set(src_dirs "." "${dir}")
+
+idf_component_register(SRC_DIRS "${src_dirs}"
+                       PRIV_INCLUDE_DIRS "." "${dir}/include" "../private_include" "../${target}/private_include"
                        PRIV_REQUIRES cmock test_utils efuse bootloader_support
                        )

+ 109 - 0
components/efuse/test/one_key_block/esp_efuse_test_table.c

@@ -0,0 +1,109 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "sdkconfig.h"
+#include "esp_efuse.h"
+#include <assert.h>
+#include "esp_efuse_test_table.h"
+
+// md5_digest_table df1ecf346aec29cf593e2f81dc4cd5e4
+// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
+// If you want to change some fields, you need to change esp_efuse_test_table.csv file
+// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
+// To show efuse_table run the command 'show_efuse_table'.
+
+#define MAX_BLK_LEN CONFIG_EFUSE_MAX_BLK_LEN
+
+// The last free bit in the block is counted over the entire file.
+#define LAST_FREE_BIT_BLK1 88
+#define LAST_FREE_BIT_BLK2 167
+#define LAST_FREE_BIT_BLK3 88
+
+_Static_assert(LAST_FREE_BIT_BLK1 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+_Static_assert(LAST_FREE_BIT_BLK2 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+_Static_assert(LAST_FREE_BIT_BLK3 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+
+static const esp_efuse_desc_t TEST1_LEN_8[] = {
+    {EFUSE_BLK3, 0, 8}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST2_LEN_16[] = {
+    {EFUSE_BLK3, 10, 8}, 	 // TEST field,
+    {EFUSE_BLK3, 80, 8}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST3_LEN_6[] = {
+    {EFUSE_BLK3, 22, 6}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST4_LEN_182[] = {
+    {EFUSE_BLK1, 22, 49}, 	 // TEST field,
+    {EFUSE_BLK2, 128, 39}, 	 // TEST field,
+    {EFUSE_BLK1, 71, 17}, 	 // TEST field,
+    {EFUSE_BLK1, 19, 1}, 	 // TEST field,
+    {EFUSE_BLK1, 0, 16}, 	 // TEST field,
+    {EFUSE_BLK2, 0, 17}, 	 // TEST field,
+    {EFUSE_BLK2, 60, 43}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST5_LEN_1[] = {
+    {EFUSE_BLK1, 16, 1}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST6_LEN_17[] = {
+    {EFUSE_BLK1, 17, 1}, 	 // TEST field,
+    {EFUSE_BLK2, 17, 2}, 	 // TEST field,
+    {EFUSE_BLK3, 29, 4}, 	 // TEST field,
+    {EFUSE_BLK2, 31, 3}, 	 // TEST field,
+    {EFUSE_BLK3, 60, 6}, 	 // TEST field,
+    {EFUSE_BLK2, 127, 1}, 	 // TEST field,
+};
+
+
+
+
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[] = {
+    &TEST1_LEN_8[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[] = {
+    &TEST2_LEN_16[0],    		// TEST field
+    &TEST2_LEN_16[1],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[] = {
+    &TEST3_LEN_6[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[] = {
+    &TEST4_LEN_182[0],    		// TEST field
+    &TEST4_LEN_182[1],    		// TEST field
+    &TEST4_LEN_182[2],    		// TEST field
+    &TEST4_LEN_182[3],    		// TEST field
+    &TEST4_LEN_182[4],    		// TEST field
+    &TEST4_LEN_182[5],    		// TEST field
+    &TEST4_LEN_182[6],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[] = {
+    &TEST5_LEN_1[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[] = {
+    &TEST6_LEN_17[0],    		// TEST field
+    &TEST6_LEN_17[1],    		// TEST field
+    &TEST6_LEN_17[2],    		// TEST field
+    &TEST6_LEN_17[3],    		// TEST field
+    &TEST6_LEN_17[4],    		// TEST field
+    &TEST6_LEN_17[5],    		// TEST field
+    NULL
+};

+ 34 - 0
components/efuse/test/one_key_block/esp_efuse_test_table.csv

@@ -0,0 +1,34 @@
+# field_name,       |    efuse_block, | bit_start, | bit_count, |comment #
+#                   |    (EFUSE_BLK0  | (0..255)   | (1..256)   |        #
+#                   |     EFUSE_BLK1  |            |            |        #
+#                   |     EFUSE_BLK2  |            |            |        #
+#                   |     EFUSE_BLK3) |            |            |        #
+##########################################################################
+
+# To generate a new source files. Run two commands:
+# cd ~/esp/esp-idf/components/efuse/
+# ./efuse_table_gen.py test/esp_efuse_test_table.csv
+
+TEST1_LEN_8,     EFUSE_BLK3,   0,    8, TEST field
+
+TEST2_LEN_16,    EFUSE_BLK3,  10,   8, TEST field
+,                EFUSE_BLK3,  80,   8, TEST field
+
+TEST3_LEN_6,     EFUSE_BLK3,  22,    6, TEST field
+
+TEST4_LEN_182,   EFUSE_BLK1,  22,   49, TEST field
+,                EFUSE_BLK2, 128,   39, TEST field
+,                EFUSE_BLK1,  71,   17, TEST field
+,                EFUSE_BLK1,  19,    1, TEST field
+,                EFUSE_BLK1,  0,    16, TEST field
+,                EFUSE_BLK2,  0,    17, TEST field
+,                EFUSE_BLK2,  60,   43, TEST field
+
+TEST5_LEN_1,     EFUSE_BLK1,  16,   1, TEST field
+
+TEST6_LEN_17,    EFUSE_BLK1,  17,    1, TEST field
+,                EFUSE_BLK2,  17,    2, TEST field
+,                EFUSE_BLK3,  29,    4, TEST field
+,                EFUSE_BLK2,  31,    3, TEST field
+,                EFUSE_BLK3,  60,    6, TEST field
+,                EFUSE_BLK2,  127,   1, TEST field

+ 28 - 0
components/efuse/test/one_key_block/include/esp_efuse_test_table.h

@@ -0,0 +1,28 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// md5_digest_table df1ecf346aec29cf593e2f81dc4cd5e4
+// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
+// If you want to change some fields, you need to change esp_efuse_test_table.csv file
+// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
+// To show efuse_table run the command 'show_efuse_table'.
+
+
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[];
+
+#ifdef __cplusplus
+}
+#endif

+ 154 - 0
components/efuse/test/one_key_block/test_efuse.c

@@ -0,0 +1,154 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "unity.h"
+#include "esp_log.h"
+#include <string.h>
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_efuse_utility.h"
+#include "esp_efuse_test_table.h"
+#include "bootloader_random.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "test_utils.h"
+#include "sdkconfig.h"
+#include "esp_rom_efuse.h"
+#include "bootloader_common.h"
+
+__attribute__((unused)) static const char* TAG = "efuse_test";
+
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+
+TEST_CASE("Test a write protection", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY0));
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+    TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK_KEY0));
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+
+TEST_CASE("Test a read protection", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY0));
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(2, out_cnt);
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+
+TEST_CASE("Test a key read protection 1", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+
+    TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
+    TEST_ESP_OK(esp_efuse_set_key_dis_read(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
+
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+
+TEST_CASE("Test a key read protection 2", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+
+    TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
+    TEST_ESP_OK(esp_efuse_set_key_dis_read(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
+
+    esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(2, out_cnt);
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+#endif // CONFIG_EFUSE_VIRTUAL
+
+#ifdef CONFIG_IDF_ENV_FPGA
+TEST_CASE("Test a real write (FPGA)2", "[efuse]")
+{
+    esp_efuse_utility_debug_dump_blocks();
+    ESP_LOGI(TAG, "1. Write KEY3");
+    uint8_t key[32] = {0};
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
+    for (int i = 0; i < sizeof(key); ++i) {
+        TEST_ASSERT_EQUAL_INT(0, key[i]);
+    }
+    uint8_t new_key[32] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
+                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
+                           30, 31};
+    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY0, &new_key, 256));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+    esp_efuse_utility_debug_dump_blocks();
+
+    ESP_LOGI(TAG, "2. Set a read protection for KEY0");
+    TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY0));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
+#ifndef CONFIG_EFUSE_VIRTUAL
+    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
+#else
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+#endif // CONFIG_EFUSE_VIRTUAL
+    esp_efuse_utility_debug_dump_blocks();
+}
+#endif  // CONFIG_IDF_ENV_FPGA

+ 292 - 0
components/efuse/test/one_key_block/test_efuse_keys.c

@@ -0,0 +1,292 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "unity.h"
+#include "test_utils.h"
+#include "esp_log.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_efuse_utility.h"
+#include "sdkconfig.h"
+
+__attribute__((unused)) static const char* TAG = "efuse_key_test";
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+
+TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+
+    for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
+        printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... \n", num_key - EFUSE_BLK_KEY0);
+        uint8_t key[32] = { 0xEE };
+        TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, sizeof(key) * 8));
+        TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
+        TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
+        TEST_ASSERT_FALSE(esp_efuse_get_key_dis_write(num_key));
+        TEST_ASSERT_EQUAL(ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY, esp_efuse_get_key_purpose(num_key));
+
+        esp_efuse_block_t key_block = EFUSE_BLK_MAX;
+        TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, NULL));
+        TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, &key_block));
+        TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
+
+        printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0);
+    }
+}
+#endif // CONFIG_EFUSE_VIRTUAL
+
+// If using efuse is real, then turn off writing tests.
+#if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
+
+static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key, esp_efuse_purpose_t purpose)
+{
+    size_t offset_in_bits = 0;
+    uint8_t key_size = 32;
+    if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
+        key_size = 16;
+    }
+
+    if (purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
+        offset_in_bits = 16 * 8;
+    }
+
+    uint8_t rd_key[32] = { 0xEE };
+    TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK_KEY0, &rd_key, offset_in_bits, key_size * 8));
+
+#ifndef CONFIG_IDF_ENV_FPGA
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
+#endif // not CONFIG_IDF_ENV_FPGA
+
+    TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key));
+    if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY) {
+        TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(num_key));
+#if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
+        TEST_ASSERT_EACH_EQUAL_HEX8(0, rd_key, key_size);
+#endif // CONFIG_IDF_ENV_FPGA && ! CONFIG_EFUSE_VIRTUAL
+    } else {
+        TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
+    }
+
+    return ESP_OK;
+}
+
+void test_write_key(esp_efuse_block_t num_key, esp_efuse_purpose_t purpose) {
+    int id = num_key - EFUSE_BLK_KEY0;
+    printf("EFUSE_BLK_KEY%d, purpose=%d ... \n", id, purpose);
+
+    uint8_t wr_key[32];
+    for (int i = 0; i < sizeof(wr_key); i++) {
+        wr_key[i] = id + 1 + i;
+    }
+
+    uint8_t key_size = sizeof(wr_key);
+    if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
+        key_size = 16;
+    }
+
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(num_key));
+
+    TEST_ESP_OK(esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
+    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
+
+    TEST_ESP_OK(s_check_key(num_key, wr_key, purpose));
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(num_key));
+
+    printf("EFUSE_BLK_KEY%d, purpose=%d ... OK\n", id, purpose);
+}
+
+#ifndef CONFIG_IDF_ENV_FPGA
+TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
+{
+    uint8_t rd_key[32] = { 0xEE };
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, 33));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK3, ESP_EFUSE_KEY_PURPOSE_USER, NULL, sizeof(rd_key)));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, sizeof(rd_key)));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY, &rd_key, sizeof(rd_key)));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2, &rd_key, sizeof(rd_key)));
+
+    for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_USER; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
+        esp_efuse_utility_reset();
+        esp_efuse_utility_update_virt_blocks();
+        esp_efuse_utility_debug_dump_blocks();
+
+        if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
+            TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
+        }
+
+        TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+        test_write_key(EFUSE_BLK_KEY0, purpose);
+        TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+
+        esp_efuse_utility_debug_dump_blocks();
+    }
+}
+#endif // not CONFIG_IDF_ENV_FPGA
+
+TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY, NULL));
+
+    test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY);
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+#ifdef CONFIG_IDF_ENV_FPGA
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#else
+    TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#endif
+
+    printf("reset efuses on the FPGA board for the next test\n");
+}
+
+TEST_CASE("Test 2 esp_efuse_write_key for FPGA", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY, NULL));
+
+    test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2);
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+
+    printf("reset efuses on the FPGA board for the next test\n");
+}
+
+TEST_CASE("Test 3 esp_efuse_write_key for FPGA", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+
+    TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
+    TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL));
+
+    test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY);
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+#ifdef CONFIG_IDF_ENV_FPGA
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#else
+    TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#endif
+
+    printf("reset efuses on the FPGA board for the next test\n");
+}
+
+TEST_CASE("Test esp_efuse_write_keys", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY, NULL));
+    esp_efuse_block_t key_block = EFUSE_BLK_MAX;
+
+    enum { BLOCKS_NEEDED1 = 2 };
+    esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
+        ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY,
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
+    };
+    uint8_t keys1[BLOCKS_NEEDED1][32] = {{0xEE}};
+
+    for (int num_key = 0; num_key < BLOCKS_NEEDED1; ++num_key) {
+        for (int i = 0; i < 32; ++i) {
+            keys1[num_key][i] = purpose1[num_key] + i + 1;
+        }
+    }
+
+    TEST_ESP_OK(esp_efuse_write_keys(purpose1, keys1, BLOCKS_NEEDED1));
+
+    TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[0], &key_block));
+    TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
+
+    TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[0], ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY));
+    TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[1], ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2));
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+
+    enum { BLOCKS_NEEDED2 = 1 };
+    esp_efuse_purpose_t purpose2[BLOCKS_NEEDED2] = {
+            ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
+    };
+    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_keys(purpose2, keys1, BLOCKS_NEEDED2));
+
+    printf("reset efuses on the FPGA board for the next test\n");
+}
+
+TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_update_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+
+    enum { BLOCKS_NEEDED = 2 };
+    esp_efuse_purpose_t purpose[BLOCKS_NEEDED] = {
+        ESP_EFUSE_KEY_PURPOSE_XTS_AES_64_KEY,
+        ESP_EFUSE_KEY_PURPOSE_MAX,                 // it leads  ESP_ERR_INVALID_ARG in esp_efuse_write_keys
+    };
+    uint8_t keys[BLOCKS_NEEDED][32];
+
+    for (int num_key = 0; num_key < BLOCKS_NEEDED; ++num_key) {
+        for (int i = 0; i < 32; ++i) {
+            keys[num_key][i] = purpose[num_key] + i + 1;
+        }
+    }
+
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(NULL, keys, BLOCKS_NEEDED));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, NULL, BLOCKS_NEEDED));
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED)); // ESP_EFUSE_KEY_PURPOSE_MAX is not a valid purpose.
+    TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, 3));
+    TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+    TEST_ESP_OK(esp_efuse_write_keys(purpose, keys, 1));
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
+#ifdef CONFIG_IDF_ENV_FPGA
+    TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#else
+    TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
+#endif
+}
+
+#endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA

+ 12 - 177
components/efuse/test/test_efuse.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -24,7 +24,12 @@
 #include "esp_rom_efuse.h"
 #include "bootloader_common.h"
 
-static const char* TAG = "efuse_test";
+#ifdef CONFIG_IDF_TARGET_ESP32
+#define MAC_FACTORY_HAS_CRC 1
+#endif
+
+__attribute__((unused)) static const char* TAG = "efuse_test";
+
 
 static void test_read_blob(void)
 {
@@ -39,12 +44,12 @@ static void test_read_blob(void)
     TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
     ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 
-#ifdef CONFIG_IDF_TARGET_ESP32
+#ifdef MAC_FACTORY_HAS_CRC
     ESP_LOGI(TAG, "2. Check CRC by MAC");
     uint8_t crc;
     TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
     TEST_ASSERT_EQUAL_HEX8(crc, esp_rom_efuse_mac_address_crc8(mac, sizeof(mac)));
-#endif // CONFIG_IDF_TARGET_ESP32
+#endif
 
     ESP_LOGI(TAG, "3. Test check args");
     uint32_t test_var;
@@ -588,7 +593,7 @@ TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
     uint8_t r_buff[32];
     int st_offset = -1;
     int num_block;
-    for (num_block = EFUSE_BLK1; num_block < 4; ++num_block) {
+    for (num_block = EFUSE_BLK_KEY0; num_block < EFUSE_BLK_KEY_MAX; ++num_block) {
         memset(r_buff, 0, sizeof(r_buff));
         esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
         if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
@@ -607,7 +612,7 @@ TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
 #else
         if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
             printf("EFUSE_CODING_SCHEME_RS\n");
-            if (num_block == EFUSE_BLK1) {
+            if (num_block == EFUSE_BLK_KEY0) {
                 count_useful_reg = 6;
             } else {
                 count_useful_reg = 8;
@@ -640,7 +645,7 @@ TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
         uint8_t val = 1;
         TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
     } else {
-        printf("Test skipped. It is not applicable, the device has no written bits.");
+        printf("Test skipped. It is not applicable, the device has no written bits.\n");
     }
 }
 
@@ -722,71 +727,6 @@ TEST_CASE("Batch mode is thread-safe", "[efuse]")
 }
 #endif // #ifndef CONFIG_FREERTOS_UNICORE
 
-static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
-{
-    size_t out_cnt;
-    TEST_ESP_OK(esp_efuse_set_write_protect(blk));
-    esp_efuse_read_field_cnt(field, &out_cnt);
-    TEST_ASSERT_EQUAL_INT(1, out_cnt);
-}
-
-static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
-{
-    size_t out_cnt;
-    if (read_first) {
-        esp_efuse_read_field_cnt(field, &out_cnt);
-        TEST_ASSERT_EQUAL_INT(0, out_cnt);
-    }
-    TEST_ESP_OK(esp_efuse_set_read_protect(blk));
-    esp_efuse_read_field_cnt(field, &out_cnt);
-    TEST_ASSERT_EQUAL_INT(1, out_cnt);
-    if (read_first) {
-        TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
-    }
-}
-
-TEST_CASE("Test a write/read protection", "[efuse]")
-{
-    esp_efuse_utility_reset();
-    esp_efuse_utility_erase_virt_blocks();
-
-    esp_efuse_utility_debug_dump_blocks();
-
-    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
-    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
-
-    size_t out_cnt;
-    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
-    TEST_ASSERT_EQUAL_INT(0, out_cnt);
-    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
-    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
-    TEST_ASSERT_EQUAL_INT(1, out_cnt);
-    TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
-
-#ifdef CONFIG_IDF_TARGET_ESP32
-    test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_BLK2);
-    test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_BLK3);
-
-    esp_efuse_utility_debug_dump_blocks();
-
-    test_rp(EFUSE_BLK1, ESP_EFUSE_RD_DIS_BLK1, true);
-    test_rp(EFUSE_BLK2, ESP_EFUSE_RD_DIS_BLK2, false);
-    test_rp(EFUSE_BLK3, ESP_EFUSE_RD_DIS_BLK3, false);
-#else
-    test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_SYS_DATA_PART1);
-    test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_USER_DATA);
-
-    esp_efuse_utility_debug_dump_blocks();
-
-    test_rp(EFUSE_BLK4, ESP_EFUSE_RD_DIS_KEY0, true);
-    test_rp(EFUSE_BLK5, ESP_EFUSE_RD_DIS_KEY1, false);
-    test_rp(EFUSE_BLK6, ESP_EFUSE_RD_DIS_KEY2, false);
-#endif
-
-    esp_efuse_utility_debug_dump_blocks();
-    esp_efuse_utility_reset();
-    esp_efuse_utility_erase_virt_blocks();
-}
 
 static volatile bool cmd_stop_reset_task1;
 static void efuse_burn_task(void* arg)
@@ -904,32 +844,7 @@ TEST_CASE("Test a real write (FPGA)", "[efuse]")
         TEST_ASSERT_EQUAL_HEX8_ARRAY(new_mac, mac, sizeof(new_mac));
         esp_efuse_utility_debug_dump_blocks();
     }
-#ifndef CONFIG_IDF_TARGET_ESP32
-    ESP_LOGI(TAG, "2. Write KEY3");
-    uint8_t key[32] = {0};
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
-    for (int i = 0; i < sizeof(key); ++i) {
-        TEST_ASSERT_EQUAL_INT(0, key[i]);
-    }
-    uint8_t new_key[32] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
-                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
-                           30, 31};
-    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
-    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
-    esp_efuse_utility_debug_dump_blocks();
 
-    ESP_LOGI(TAG, "3. Set a read protection for KEY3");
-    TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK7));
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
-#ifndef CONFIG_EFUSE_VIRTUAL
-    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
-#else
-    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
-#endif // CONFIG_EFUSE_VIRTUAL
-    esp_efuse_utility_debug_dump_blocks();
-#endif // not CONFIG_IDF_TARGET_ESP32
     ESP_LOGI(TAG, "4. Write SECURE_VERSION");
     int max_bits = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
     size_t read_sec_version;
@@ -955,83 +870,3 @@ TEST_CASE("Test chip_revision APIs return the same value", "[efuse]")
     esp_efuse_utility_update_virt_blocks();
     TEST_ASSERT_EQUAL_INT(esp_efuse_get_chip_ver(), bootloader_common_get_chip_revision());
 }
-
-#ifndef CONFIG_IDF_TARGET_ESP32
-#if CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
-TEST_CASE("Test writing order is BLK_MAX->BLK0", "[efuse]")
-{
-    uint8_t new_key[32] = {33,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
-                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
-                           30, 31};
-    esp_efuse_utility_erase_virt_blocks();
-    esp_efuse_utility_debug_dump_blocks();
-
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-
-    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY4, &new_key, 256));
-    // If the order of writing blocks is wrong (ex. BLK0 -> BLK_MAX)
-    // then the write protection bit will be set early and the key was left un-updated.
-    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY4));
-
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    esp_efuse_utility_debug_dump_blocks();
-
-    uint8_t key[32] = { 0xEE };
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY4, &key, 256));
-    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
-}
-
-TEST_CASE("Test reading inside of batch mode in a nested way", "[efuse]")
-{
-    uint8_t new_key[32] = {44,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
-                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
-                           30, 31};
-    uint8_t key[32] = { 0xEE };
-    esp_efuse_utility_reset();
-    esp_efuse_utility_erase_virt_blocks();
-    esp_efuse_utility_debug_dump_blocks();
-
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
-    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
-
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY5, &new_key, 256));
-    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY5));
-    ESP_LOGI(TAG, "Reading inside Batch mode, the key was not burn yet and it is empty");
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
-    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
-    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-
-    esp_efuse_utility_debug_dump_blocks();
-
-    ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
-    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_commit());
-    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_cancel());
-    TEST_ESP_OK(esp_efuse_batch_write_begin());
-    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY2, &new_key, 256));
-    TEST_ESP_OK(esp_efuse_batch_write_commit());
-    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY2, &key, 256));
-    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
-
-    esp_efuse_utility_debug_dump_blocks();
-}
-#endif  // CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
-#endif  // not CONFIG_IDF_TARGET_ESP32

+ 1 - 1
components/efuse/test/esp_efuse_test_table.c → components/efuse/test/three_key_blocks/esp_efuse_test_table.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */

+ 0 - 0
components/efuse/test/esp_efuse_test_table.csv → components/efuse/test/three_key_blocks/esp_efuse_test_table.csv


+ 1 - 1
components/efuse/test/include/esp_efuse_test_table.h → components/efuse/test/three_key_blocks/include/esp_efuse_test_table.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */

+ 86 - 0
components/efuse/test/three_key_blocks/test_efuse.c

@@ -0,0 +1,86 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "unity.h"
+#include "esp_log.h"
+#include <string.h>
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_efuse_utility.h"
+#include "esp_efuse_test_table.h"
+#include "bootloader_random.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "test_utils.h"
+#include "sdkconfig.h"
+#include "esp_rom_efuse.h"
+#include "bootloader_common.h"
+
+__attribute__((unused)) static const char* TAG = "efuse_test";
+
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+
+static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
+{
+    size_t out_cnt;
+    TEST_ESP_OK(esp_efuse_set_write_protect(blk));
+    esp_efuse_read_field_cnt(field, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+}
+
+static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
+{
+    size_t out_cnt;
+    if (read_first) {
+        esp_efuse_read_field_cnt(field, &out_cnt);
+        TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    }
+    TEST_ESP_OK(esp_efuse_set_read_protect(blk));
+    esp_efuse_read_field_cnt(field, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+    if (read_first) {
+        TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
+    }
+}
+
+TEST_CASE("Test a write/read protection", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+    TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
+
+    test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_BLK2);
+    test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_BLK3);
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    test_rp(EFUSE_BLK1, ESP_EFUSE_RD_DIS_BLK1, true);
+    test_rp(EFUSE_BLK2, ESP_EFUSE_RD_DIS_BLK2, false);
+    test_rp(EFUSE_BLK3, ESP_EFUSE_RD_DIS_BLK3, false);
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+#endif // #ifdef CONFIG_EFUSE_VIRTUAL

+ 1 - 3
components/efuse/test/test_efuse_coding_scheme.c → components/efuse/test/three_key_blocks/test_efuse_coding_scheme.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -11,7 +11,6 @@
 #include "unity.h"
 #include "bootloader_random.h"
 
-#ifdef CONFIG_IDF_TARGET_ESP32
 typedef struct {
     uint8_t unencoded[24];
     uint32_t encoded[8];
@@ -209,4 +208,3 @@ TEST_CASE("Test data does not match the coding scheme", "[efuse]")
 
     esp_efuse_utility_reset();
 }
-#endif // CONFIG_IDF_TARGET_ESP32

+ 107 - 0
components/efuse/test/with_key_purposes/esp_efuse_test_table.c

@@ -0,0 +1,107 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "sdkconfig.h"
+#include "esp_efuse.h"
+#include <assert.h>
+#include "esp_efuse_test_table.h"
+
+// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
+// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
+// If you want to change some fields, you need to change esp_efuse_test_table.csv file
+// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
+// To show efuse_table run the command 'show_efuse_table'.
+
+#define MAX_BLK_LEN CONFIG_EFUSE_MAX_BLK_LEN
+
+// The last free bit in the block is counted over the entire file.
+#define LAST_FREE_BIT_BLK1 128
+#define LAST_FREE_BIT_BLK2 128
+#define LAST_FREE_BIT_BLK3 88
+
+_Static_assert(LAST_FREE_BIT_BLK1 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+_Static_assert(LAST_FREE_BIT_BLK2 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+_Static_assert(LAST_FREE_BIT_BLK3 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
+
+static const esp_efuse_desc_t TEST1_LEN_8[] = {
+    {EFUSE_BLK3, 0, 8}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST2_LEN_16[] = {
+    {EFUSE_BLK3, 10, 8}, 	 // TEST field,
+    {EFUSE_BLK3, 80, 8}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST3_LEN_6[] = {
+    {EFUSE_BLK3, 22, 6}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST4_LEN_182[] = {
+    {EFUSE_BLK1, 22, 49}, 	 // TEST field,
+    {EFUSE_BLK1, 89, 39}, 	 // TEST field,
+    {EFUSE_BLK1, 71, 18}, 	 // TEST field,
+    {EFUSE_BLK1, 0, 16}, 	 // TEST field,
+    {EFUSE_BLK2, 0, 17}, 	 // TEST field,
+    {EFUSE_BLK2, 60, 43}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST5_LEN_1[] = {
+    {EFUSE_BLK1, 16, 1}, 	 // TEST field,
+};
+
+static const esp_efuse_desc_t TEST6_LEN_17[] = {
+    {EFUSE_BLK1, 17, 1}, 	 // TEST field,
+    {EFUSE_BLK2, 17, 2}, 	 // TEST field,
+    {EFUSE_BLK3, 29, 4}, 	 // TEST field,
+    {EFUSE_BLK2, 31, 3}, 	 // TEST field,
+    {EFUSE_BLK3, 60, 6}, 	 // TEST field,
+    {EFUSE_BLK2, 127, 1}, 	 // TEST field,
+};
+
+
+
+
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[] = {
+    &TEST1_LEN_8[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[] = {
+    &TEST2_LEN_16[0],    		// TEST field
+    &TEST2_LEN_16[1],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[] = {
+    &TEST3_LEN_6[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[] = {
+    &TEST4_LEN_182[0],    		// TEST field
+    &TEST4_LEN_182[1],    		// TEST field
+    &TEST4_LEN_182[2],    		// TEST field
+    &TEST4_LEN_182[3],    		// TEST field
+    &TEST4_LEN_182[4],    		// TEST field
+    &TEST4_LEN_182[5],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[] = {
+    &TEST5_LEN_1[0],    		// TEST field
+    NULL
+};
+
+const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[] = {
+    &TEST6_LEN_17[0],    		// TEST field
+    &TEST6_LEN_17[1],    		// TEST field
+    &TEST6_LEN_17[2],    		// TEST field
+    &TEST6_LEN_17[3],    		// TEST field
+    &TEST6_LEN_17[4],    		// TEST field
+    &TEST6_LEN_17[5],    		// TEST field
+    NULL
+};

+ 33 - 0
components/efuse/test/with_key_purposes/esp_efuse_test_table.csv

@@ -0,0 +1,33 @@
+# field_name,       |    efuse_block, | bit_start, | bit_count, |comment #
+#                   |    (EFUSE_BLK0  | (0..255)   | (1..256)   |        #
+#                   |     EFUSE_BLK1  |            |            |        #
+#                   |     EFUSE_BLK2  |            |            |        #
+#                   |     EFUSE_BLK3) |            |            |        #
+##########################################################################
+
+# To generate a new source files. Run two commands:
+# cd ~/esp/esp-idf/components/efuse/
+# ./efuse_table_gen.py test/esp_efuse_test_table.csv
+
+TEST1_LEN_8,     EFUSE_BLK3,   0,    8, TEST field
+
+TEST2_LEN_16,    EFUSE_BLK3,  10,   8, TEST field
+,                EFUSE_BLK3,  80,   8, TEST field
+
+TEST3_LEN_6,     EFUSE_BLK3,  22,    6, TEST field
+
+TEST4_LEN_182,   EFUSE_BLK1,  22,   49, TEST field
+,                EFUSE_BLK1,  89,   39, TEST field
+,                EFUSE_BLK1,  71,   18, TEST field
+,                EFUSE_BLK1,  0,    16, TEST field
+,                EFUSE_BLK2,  0,    17, TEST field
+,                EFUSE_BLK2,  60,   43, TEST field
+
+TEST5_LEN_1,     EFUSE_BLK1,  16,   1, TEST field
+
+TEST6_LEN_17,    EFUSE_BLK1,  17,    1, TEST field
+,                EFUSE_BLK2,  17,    2, TEST field
+,                EFUSE_BLK3,  29,    4, TEST field
+,                EFUSE_BLK2,  31,    3, TEST field
+,                EFUSE_BLK3,  60,    6, TEST field
+,                EFUSE_BLK2,  127,   1, TEST field

+ 28 - 0
components/efuse/test/with_key_purposes/include/esp_efuse_test_table.h

@@ -0,0 +1,28 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
+// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
+// If you want to change some fields, you need to change esp_efuse_test_table.csv file
+// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
+// To show efuse_table run the command 'show_efuse_table'.
+
+
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[];
+extern const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[];
+
+#ifdef __cplusplus
+}
+#endif

+ 195 - 0
components/efuse/test/with_key_purposes/test_efuse.c

@@ -0,0 +1,195 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "unity.h"
+#include "esp_log.h"
+#include <string.h>
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_efuse_utility.h"
+#include "esp_efuse_test_table.h"
+#include "bootloader_random.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "test_utils.h"
+#include "sdkconfig.h"
+#include "esp_rom_efuse.h"
+#include "bootloader_common.h"
+
+__attribute__((unused)) static const char* TAG = "efuse_test";
+
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+
+static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
+{
+    size_t out_cnt;
+    TEST_ESP_OK(esp_efuse_set_write_protect(blk));
+    esp_efuse_read_field_cnt(field, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+}
+
+static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
+{
+    size_t out_cnt;
+    if (read_first) {
+        esp_efuse_read_field_cnt(field, &out_cnt);
+        TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    }
+    TEST_ESP_OK(esp_efuse_set_read_protect(blk));
+    esp_efuse_read_field_cnt(field, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+    if (read_first) {
+        TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
+    }
+}
+
+TEST_CASE("Test a write/read protection", "[efuse]")
+{
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
+    TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
+
+    size_t out_cnt;
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(0, out_cnt);
+    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
+    esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
+    TEST_ASSERT_EQUAL_INT(1, out_cnt);
+    TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
+
+    test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_SYS_DATA_PART1);
+    test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_USER_DATA);
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    test_rp(EFUSE_BLK4, ESP_EFUSE_RD_DIS_KEY0, true);
+    test_rp(EFUSE_BLK5, ESP_EFUSE_RD_DIS_KEY1, false);
+    test_rp(EFUSE_BLK6, ESP_EFUSE_RD_DIS_KEY2, false);
+
+    esp_efuse_utility_debug_dump_blocks();
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+}
+#endif // CONFIG_EFUSE_VIRTUAL
+
+#ifdef CONFIG_IDF_ENV_FPGA
+TEST_CASE("Test a real write (FPGA)2", "[efuse]")
+{
+    esp_efuse_utility_debug_dump_blocks();
+    ESP_LOGI(TAG, "1. Write KEY3");
+    uint8_t key[32] = {0};
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
+    for (int i = 0; i < sizeof(key); ++i) {
+        TEST_ASSERT_EQUAL_INT(0, key[i]);
+    }
+    uint8_t new_key[32] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
+                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
+                           30, 31};
+    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+    esp_efuse_utility_debug_dump_blocks();
+
+    ESP_LOGI(TAG, "2. Set a read protection for KEY3");
+    TEST_ESP_OK(esp_efuse_set_read_protect(ESP_EFUSE_KEY3));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
+#ifndef CONFIG_EFUSE_VIRTUAL
+    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
+#else
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+#endif // CONFIG_EFUSE_VIRTUAL
+    esp_efuse_utility_debug_dump_blocks();
+}
+#endif  // CONFIG_IDF_ENV_FPGA
+
+#if CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
+TEST_CASE("Test writing order is BLK_MAX->BLK0", "[efuse]")
+{
+    uint8_t new_key[32] = {33,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
+                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
+                           30, 31};
+    esp_efuse_utility_erase_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+
+    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY4, &new_key, 256));
+    // If the order of writing blocks is wrong (ex. BLK0 -> BLK_MAX)
+    // then the write protection bit will be set early and the key was left un-updated.
+    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY4));
+
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    esp_efuse_utility_debug_dump_blocks();
+
+    uint8_t key[32] = { 0xEE };
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY4, &key, 256));
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+}
+
+TEST_CASE("Test reading inside of batch mode in a nested way", "[efuse]")
+{
+    uint8_t new_key[32] = {44,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+                           10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
+                           20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
+                           30, 31};
+    uint8_t key[32] = { 0xEE };
+    esp_efuse_utility_reset();
+    esp_efuse_utility_erase_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
+    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
+
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY5, &new_key, 256));
+    TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY5));
+    ESP_LOGI(TAG, "Reading inside Batch mode, the key was not burn yet and it is empty");
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
+    TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+
+    esp_efuse_utility_debug_dump_blocks();
+
+    ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
+    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_commit());
+    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_cancel());
+    TEST_ESP_OK(esp_efuse_batch_write_begin());
+    TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY2, &new_key, 256));
+    TEST_ESP_OK(esp_efuse_batch_write_commit());
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY2, &key, 256));
+    TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
+
+    esp_efuse_utility_debug_dump_blocks();
+}
+#endif  // CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL

+ 7 - 5
components/efuse/test/test_efuse_keys.c → components/efuse/test/with_key_purposes/test_efuse_keys.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -17,10 +17,10 @@
 #include "esp_efuse_utility.h"
 #include "sdkconfig.h"
 
-__attribute__((unused)) static const char* TAG = "efuse_test";
+__attribute__((unused)) static const char* TAG = "efuse_key_test";
 
 
-#ifndef CONFIG_IDF_TARGET_ESP32
+#ifdef CONFIG_EFUSE_VIRTUAL
 
 TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
 {
@@ -47,6 +47,7 @@ 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);
     }
 }
+#endif // CONFIG_EFUSE_VIRTUAL
 
 // If using efuse is real, then turn off writing tests.
 #if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
@@ -309,6 +310,8 @@ TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
     TEST_ESP_ERR(ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS, esp_efuse_write_keys(purpose, keys, unused_keys + 1));
 }
 
+#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
+
 TEST_CASE("Test revocation APIs", "[efuse]")
 {
     esp_efuse_utility_reset();
@@ -381,7 +384,6 @@ TEST_CASE("Test set_write_protect_of_digest_revoke", "[efuse]")
     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(2));
 #endif // CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
 }
+#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
 
 #endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
-
-#endif // not CONFIG_IDF_TARGET_ESP32

+ 10 - 2
components/soc/esp32c2/include/soc/Kconfig.soc_caps.in

@@ -36,10 +36,18 @@ config SOC_SUPPORTS_SECURE_DL_MODE
     default y
 
 config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS
-    int
-    default 3
+    bool
+    default y
 
 config SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+    bool
+    default n
+
+config SOC_EFUSE_KEY_PURPOSE_FIELD
+    bool
+    default n
+
+config SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
     bool
     default y
 

+ 4 - 2
components/soc/esp32c2/include/soc/soc_caps.h

@@ -33,8 +33,10 @@
 #define SOC_WIFI_SUPPORTED              0 // Enable during bringup, IDF-3905
 #define SOC_ASYNC_MEMCPY_SUPPORTED      1
 #define SOC_SUPPORTS_SECURE_DL_MODE     1
-#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
-#define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1
+#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 1
+#define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 0
+#define SOC_EFUSE_KEY_PURPOSE_FIELD     0
+#define SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK 1
 #define SOC_RTC_FAST_MEM_SUPPORTED      0
 #define SOC_RTC_SLOW_MEM_SUPPORTED      0
 #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY             0

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

@@ -71,6 +71,10 @@ config SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
     bool
     default y
 
+config SOC_EFUSE_KEY_PURPOSE_FIELD
+    bool
+    default y
+
 config SOC_ICACHE_ACCESS_RODATA_SUPPORTED
     bool
     default y

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

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -42,6 +42,7 @@
 #define SOC_SUPPORTS_SECURE_DL_MODE     1
 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS   3
 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS   1
+#define SOC_EFUSE_KEY_PURPOSE_FIELD         1
 #define SOC_ICACHE_ACCESS_RODATA_SUPPORTED  1
 #define SOC_RTC_FAST_MEM_SUPPORTED        1
 #define SOC_RTC_SLOW_MEM_SUPPORTED        0

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

@@ -51,6 +51,10 @@ config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS
     int
     default 3
 
+config SOC_EFUSE_KEY_PURPOSE_FIELD
+    bool
+    default y
+
 config SOC_ICACHE_ACCESS_RODATA_SUPPORTED
     bool
     default y

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

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -36,6 +36,7 @@
 #define SOC_USB_SERIAL_JTAG_SUPPORTED   1
 #define SOC_SUPPORTS_SECURE_DL_MODE         1
 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS   3
+#define SOC_EFUSE_KEY_PURPOSE_FIELD         1
 #define SOC_ICACHE_ACCESS_RODATA_SUPPORTED  1
 #define SOC_TEMP_SENSOR_SUPPORTED           1
 #define SOC_RTC_FAST_MEM_SUPPORTED          1

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

@@ -75,6 +75,10 @@ config SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
     bool
     default y
 
+config SOC_EFUSE_KEY_PURPOSE_FIELD
+    bool
+    default y
+
 config SOC_ICACHE_ACCESS_RODATA_SUPPORTED
     bool
     default y

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

@@ -57,6 +57,7 @@
 #define SOC_ASYNC_MEMCPY_SUPPORTED      1
 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS   3
 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS   1
+#define SOC_EFUSE_KEY_PURPOSE_FIELD         1
 #define SOC_ICACHE_ACCESS_RODATA_SUPPORTED  1
 #define SOC_TEMP_SENSOR_SUPPORTED           1
 #define SOC_CACHE_SUPPORT_WRAP              1

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

@@ -215,6 +215,10 @@ config SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
     bool
     default y
 
+config SOC_EFUSE_KEY_PURPOSE_FIELD
+    bool
+    default y
+
 config SOC_SDMMC_HOST_SUPPORTED
     bool
     default y

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

@@ -47,6 +47,7 @@
 #define SOC_SUPPORTS_SECURE_DL_MODE     1
 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1
+#define SOC_EFUSE_KEY_PURPOSE_FIELD       1
 #define SOC_SDMMC_HOST_SUPPORTED          1
 #define SOC_FLASH_ENCRYPTION_XTS_AES      1
 #define SOC_RTC_FAST_MEM_SUPPORTED        1