From 55e0730a8d2f9dcecae37ef26ba445b6f9cbd460 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 28 May 2025 12:57:00 +0530 Subject: [PATCH] change(esp_hw_support): Move security-related modules to the esp_security component - Also adds support to whitelist target specific expected dependency violations in check_dependencies.py --- components/bt/CMakeLists.txt | 1 + components/esp_common/src/esp_err_to_name.c | 2 +- components/esp_hw_support/CMakeLists.txt | 3 +- components/esp_security/CMakeLists.txt | 3 +- .../include/esp_crypto_lock.h | 0 .../include/esp_dpa_protection.h | 0 .../include/esp_ds.h | 0 .../include/esp_ds_err.h | 0 .../include/esp_hmac.h | 0 components/mbedtls/CMakeLists.txt | 2 + components/nvs_sec_provider/CMakeLists.txt | 3 +- components/spi_flash/CMakeLists.txt | 4 + docs/doxygen/Doxyfile | 4 +- .../hmac_soft_jtag/main/CMakeLists.txt | 2 +- .../nvs_encryption_hmac/main/CMakeLists.txt | 2 +- .../system/g1_components/CMakeLists.txt | 15 ++-- .../g1_components/check_dependencies.py | 79 ++++++++++++++++--- 17 files changed, 90 insertions(+), 30 deletions(-) rename components/{esp_hw_support => esp_security}/include/esp_crypto_lock.h (100%) rename components/{esp_hw_support => esp_security}/include/esp_dpa_protection.h (100%) rename components/{esp_hw_support => esp_security}/include/esp_ds.h (100%) rename components/{esp_hw_support => esp_security}/include/esp_ds_err.h (100%) rename components/{esp_hw_support => esp_security}/include/esp_hmac.h (100%) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 85653221d6..893d876ad4 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -917,6 +917,7 @@ set(bt_priv_requires esp_driver_spi esp_driver_gpio esp_gdbstub + esp_security ) idf_component_register(SRCS "${srcs}" diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 606e78124f..5671e424fb 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -816,7 +816,7 @@ static const esp_err_msg_t esp_err_msg_table[] = { ERR_TBL_IT(ESP_ERR_HW_CRYPTO_BASE), /* 49152 0xc000 Starting number of HW cryptography module error codes */ # endif - // components/esp_hw_support/include/esp_ds_err.h + // components/esp_security/include/esp_ds_err.h # ifdef ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL ERR_TBL_IT(ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL), /* 49153 0xc001 HMAC peripheral problem */ # endif diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index a640203ba5..08954cf9d7 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -11,8 +11,7 @@ endif() set(requires soc) # only esp_hw_support/adc_share_hw_ctrl.c requires efuse component -# TODO: remove esp_security from REQUIRES in ESP-IDF v6.0 (see IDF-10733) -set(priv_requires efuse spi_flash bootloader_support esp_security) +set(priv_requires efuse spi_flash bootloader_support) if(${target} STREQUAL "esp32c6") list(APPEND priv_requires hal) diff --git a/components/esp_security/CMakeLists.txt b/components/esp_security/CMakeLists.txt index 6b09a6294c..cc7a1fcb19 100644 --- a/components/esp_security/CMakeLists.txt +++ b/components/esp_security/CMakeLists.txt @@ -30,12 +30,11 @@ if(NOT non_os_build) endif() list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c") - list(APPEND priv_requires efuse esp_hw_support esp_system esp_timer) + list(APPEND priv_requires efuse esp_system esp_timer) elseif(esp_tee_build) list(APPEND srcs "src/esp_crypto_lock.c" "src/esp_crypto_periph_clk.c" "src/esp_hmac.c" "src/esp_ds.c") list(APPEND includes "src/${IDF_TARGET}") - list(APPEND priv_requires esp_hw_support) endif() idf_component_register(SRCS ${srcs} diff --git a/components/esp_hw_support/include/esp_crypto_lock.h b/components/esp_security/include/esp_crypto_lock.h similarity index 100% rename from components/esp_hw_support/include/esp_crypto_lock.h rename to components/esp_security/include/esp_crypto_lock.h diff --git a/components/esp_hw_support/include/esp_dpa_protection.h b/components/esp_security/include/esp_dpa_protection.h similarity index 100% rename from components/esp_hw_support/include/esp_dpa_protection.h rename to components/esp_security/include/esp_dpa_protection.h diff --git a/components/esp_hw_support/include/esp_ds.h b/components/esp_security/include/esp_ds.h similarity index 100% rename from components/esp_hw_support/include/esp_ds.h rename to components/esp_security/include/esp_ds.h diff --git a/components/esp_hw_support/include/esp_ds_err.h b/components/esp_security/include/esp_ds_err.h similarity index 100% rename from components/esp_hw_support/include/esp_ds_err.h rename to components/esp_security/include/esp_ds_err.h diff --git a/components/esp_hw_support/include/esp_hmac.h b/components/esp_security/include/esp_hmac.h similarity index 100% rename from components/esp_hw_support/include/esp_hmac.h rename to components/esp_security/include/esp_hmac.h diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 99981b04af..0b42e78c4e 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -23,6 +23,7 @@ if(NOT ${IDF_TARGET} STREQUAL "linux") set(priv_requires soc esp_hw_support) if(NOT BOOTLOADER_BUILD) list(APPEND priv_requires esp_pm) + set(requires esp_security) endif() endif() @@ -41,6 +42,7 @@ endif() idf_component_register(SRCS "${mbedtls_srcs}" INCLUDE_DIRS "${mbedtls_include_dirs}" PRIV_REQUIRES "${priv_requires}" + REQUIRES "${requires}" ) # Determine the type of mbedtls component library diff --git a/components/nvs_sec_provider/CMakeLists.txt b/components/nvs_sec_provider/CMakeLists.txt index 9de023e3d3..a10a0088d3 100644 --- a/components/nvs_sec_provider/CMakeLists.txt +++ b/components/nvs_sec_provider/CMakeLists.txt @@ -12,7 +12,8 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS include - PRIV_REQUIRES bootloader_support efuse esp_partition nvs_flash) + PRIV_REQUIRES bootloader_support efuse esp_partition nvs_flash + REQUIRES esp_security) # NOTE: In a case where only the default NVS partition is to be encrypted # and no custom NVS partitions exist, `nvs_flash_init` is the only API that diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 1cd7c874fe..73c42f54a9 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -53,6 +53,10 @@ else() list(APPEND srcs ${cache_srcs}) set(priv_requires bootloader_support soc esp_mm) + + if(${target} STREQUAL "esp32s2") + list(APPEND priv_requires esp_security) + endif() endif() idf_component_register(SRCS "${srcs}" diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index fcfd4d363c..b4b575fb29 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -171,8 +171,6 @@ INPUT = \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_cpu.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_crc.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_etm.h \ - $(PROJECT_PATH)/components/esp_hw_support/include/esp_ds.h \ - $(PROJECT_PATH)/components/esp_hw_support/include/esp_hmac.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_intr_alloc.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_intr_types.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_mac.h \ @@ -204,6 +202,8 @@ INPUT = \ $(PROJECT_PATH)/components/esp_pm/include/esp_pm.h \ $(PROJECT_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \ $(PROJECT_PATH)/components/esp_rom/include/esp_rom_sys.h \ + $(PROJECT_PATH)/components/esp_security/include/esp_ds.h \ + $(PROJECT_PATH)/components/esp_security/include/esp_hmac.h \ $(PROJECT_PATH)/components/esp_system/include/esp_expression_with_stack.h \ $(PROJECT_PATH)/components/esp_system/include/esp_freertos_hooks.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \ diff --git a/examples/security/hmac_soft_jtag/main/CMakeLists.txt b/examples/security/hmac_soft_jtag/main/CMakeLists.txt index 8767d118fc..7af022a731 100644 --- a/examples/security/hmac_soft_jtag/main/CMakeLists.txt +++ b/examples/security/hmac_soft_jtag/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "example_main.c" "jtag_commands.c" - PRIV_REQUIRES console efuse mbedtls nvs_flash + PRIV_REQUIRES console efuse mbedtls nvs_flash esp_security PRIV_INCLUDE_DIRS ".") diff --git a/examples/security/nvs_encryption_hmac/main/CMakeLists.txt b/examples/security/nvs_encryption_hmac/main/CMakeLists.txt index f5639600f1..c33b65ce3e 100644 --- a/examples/security/nvs_encryption_hmac/main/CMakeLists.txt +++ b/examples/security/nvs_encryption_hmac/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "main.c" - PRIV_REQUIRES nvs_flash spi_flash nvs_sec_provider + PRIV_REQUIRES nvs_flash spi_flash nvs_sec_provider esp_security INCLUDE_DIRS ".") diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index 2215ef3e4b..b8d7c4fd20 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -66,12 +66,12 @@ set(extra_components_which_shouldnt_be_included # IDF-10415 esp_pm - # esp_timer is a dependency of esp_pm, esp_system and esp_hw_support + # esp_timer is a dependency of esp_pm, esp_system, esp_security, esp_hw_support # esp_pm should be removed from G1 build # esp_system's dependency is due to usb_console (used for timeout functionality) # and task_wdt timer implementation on C2, we could possibly place this implementation in esp_timer instead - # esp_hw_support uses it for esp_ds (used for timeout functionality) - # and for componensating time after sleep (dependency could be reversed) IDF-10416 + # esp_security uses it for esp_ds (used for timeout functionality) + # esp_hw_support uses it for componensating time after sleep (dependency could be reversed) IDF-10416 esp_timer # esptool_py is a dependency of bootloader, app_update, partition_table, all of which @@ -92,9 +92,7 @@ set(extra_components_which_shouldnt_be_included # pthread is required by cxx. See [refactor-todo] about cxx, can it work without pthread? pthread - # esp_security is a private dependency of the following G1 components: - # esp_hw_support - # TODO: will be removed in IDF 6.x (see IDF-10733) + # esp_security is required by mbedtls and spi_flash esp_security ) @@ -117,10 +115,13 @@ if(NOT "${expected_components}" STREQUAL "${build_components}") endif() set(comp_deps_dot "${CMAKE_BINARY_DIR}/component_deps.dot") +idf_build_get_property(target IDF_TARGET) execute_process( COMMAND ${CMAKE_COMMAND} -E echo "Checking dependency violations" - COMMAND python "${CMAKE_SOURCE_DIR}/check_dependencies.py" --component_deps_file ${comp_deps_dot} + COMMAND python "${CMAKE_SOURCE_DIR}/check_dependencies.py" + --component_deps_file ${comp_deps_dot} + --target ${IDF_TARGET} RESULT_VARIABLE result ) diff --git a/tools/test_apps/system/g1_components/check_dependencies.py b/tools/test_apps/system/g1_components/check_dependencies.py index eb156e1729..56b1029112 100644 --- a/tools/test_apps/system/g1_components/check_dependencies.py +++ b/tools/test_apps/system/g1_components/check_dependencies.py @@ -4,6 +4,7 @@ import argparse import logging from typing import Dict from typing import List +from typing import Optional from typing import Tuple g1_g0_components = [ @@ -24,17 +25,62 @@ g1_g0_components = [ 'esp_mm', ] +# Global expected dependency violations that apply to all targets expected_dep_violations = { 'esp_system': ['esp_timer', 'bootloader_support', 'esp_pm'], 'spi_flash': ['bootloader_support'], - 'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer', 'esp_pm', 'esp_security'], + 'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer', 'esp_pm'], 'cxx': ['pthread'], } +# Target-specific expected dependency violations +target_specific_expected_dep_violations = { + # 'target': { + # Add target-specific violations for target here + # 'component_name': ['dependency1', 'dependency2'], + # }, + 'esp32s2': { + # ESP32-S2 uses the crypto DMA lock for encrypted writes, thus, spi_flash needs to depend on esp_security + 'spi_flash': ['esp_security'], + }, +} -def parse_dependencies(file_path: str) -> Tuple[Dict[str, List[str]], List[str]]: + +def merge_expected_violations(target: Optional[str] = None) -> Dict[str, List[str]]: + """ + Merge global and target-specific expected dependency violations. + + Args: + target: The target target name (e.g., 'esp32', 'esp32s3', etc.) + + Returns: + Merged dictionary of expected dependency violations + """ + # Start with a deep copy of global violations + merged_violations = {} + for component, deps in expected_dep_violations.items(): + merged_violations[component] = deps.copy() + + # Add target-specific violations if target is specified + if target and target in target_specific_expected_dep_violations: + target_violations = target_specific_expected_dep_violations[target] + for component, deps in target_violations.items(): + if component in merged_violations: + # Extend existing list with target-specific dependencies + merged_violations[component].extend(deps) + else: + # Add new component with its dependencies + merged_violations[component] = deps.copy() + + return merged_violations + + +def parse_dependencies(file_path: str, target: Optional[str] = None) -> Tuple[Dict[str, List[str]], List[str]]: new_dependency_errors = [] + # Get merged expected violations for the specified target + merged_expected_violations = merge_expected_violations(target) + with open(file_path, 'r') as file: for line in file: line = line.strip(' ;') @@ -43,22 +89,28 @@ def parse_dependencies(file_path: str) -> Tuple[Dict[str, List[str]], List[str]] parts = line.split(' -> ') if len(parts) >= 2: - source = parts[0] - target = parts[1].split()[0] # Extracting the target component - logging.debug(f'Parsed dependency: {source} -> {target}') + source_component = parts[0] + target_component = parts[1].split()[0] # Extracting the target component + logging.debug(f'Parsed dependency: {source_component} -> {target_component}') # Check that g1/g0 dependencies are either on the list of expected violations # or dependencies to other g1/g0 components - if source in g1_g0_components and target not in g1_g0_components: - if target in expected_dep_violations[source]: - logging.debug(f'Removing dependency {target} from {source} in list of expected violations') - expected_dep_violations[source].remove(target) + if source_component in g1_g0_components and target_component not in g1_g0_components: + if ( + source_component in merged_expected_violations + and target_component in merged_expected_violations[source_component] + ): + logging.debug( + f'Removing dependency {target_component} from {source_component} ' + f'in list of expected violations' + ) + merged_expected_violations[source_component].remove(target_component) else: - new_dependency_errors.append(f'{source} -> {target}') + new_dependency_errors.append(f'{source_component} -> {target_component}') - # Any leftover dependencies in the expected_dep_violations are no longer true dependencies and + # Any leftover dependencies in the merged_expected_violations are no longer true dependencies and # can be removed from the list - false_dependencies = {k: v for k, v in expected_dep_violations.items() if len(v) > 0} + false_dependencies = {k: v for k, v in merged_expected_violations.items() if len(v) > 0} return (false_dependencies, new_dependency_errors) @@ -68,10 +120,11 @@ if __name__ == '__main__': parser.add_argument( '--component_deps_file', required=True, type=str, help='The path to the component_deps.dot file' ) + parser.add_argument('--target', type=str, help='The target name (e.g., esp32, esp32s3, esp32c6, etc.)') args = parser.parse_args() - (false_dependencies, new_dependency_errors) = parse_dependencies(args.component_deps_file) + (false_dependencies, new_dependency_errors) = parse_dependencies(args.component_deps_file, args.target) if new_dependency_errors: print('Found the following new dependency violations:')