diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 580a5bfc48..0570c4de84 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -156,6 +156,13 @@ if(BOOTLOADER_BUILD) endif() endif() + if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER) + rom_linker_script("mbedtls") + # For ESP32C2(ECO4), mbedTLS in ROM has been updated to v3.6.0-LTS + if(CONFIG_ESP32C2_REV_MIN_FULL GREATER_EQUAL 200) + rom_linker_script("mbedtls.eco4") + endif() + endif() else() # Regular app build if(target STREQUAL "esp32") diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 8bc72f6179..8662869c89 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -5,6 +5,18 @@ idf_build_get_property(esp_tee_build ESP_TEE_BUILD) if(esp_tee_build) include(${COMPONENT_DIR}/esp_tee/esp_tee_mbedtls.cmake) return() + +elseif(BOOTLOADER_BUILD) # TODO: IDF-11673 + if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER) + set(include_dirs "${COMPONENT_DIR}/mbedtls/include" + "port/mbedtls_rom") + set(srcs "port/mbedtls_rom/mbedtls_rom_osi_bootloader.c") + endif() + + idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "${include_dirs}" + PRIV_REQUIRES hal) + return() endif() if(NOT ${IDF_TARGET} STREQUAL "linux") @@ -88,7 +100,6 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) "${crt_bundle}") endif() - # Only build mbedtls libraries set(ENABLE_TESTING CACHE BOOL OFF) set(ENABLE_PROGRAMS CACHE BOOL OFF) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 7fd3d87ab6..b1edb31fba 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -1212,6 +1212,17 @@ menu "mbedTLS" Disabling this config can save some code/rodata size as the error string conversion implementation is replaced with an empty stub. + config MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER + bool "Use ROM implementation of the crypto algorithm in the bootloader" + depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB + default "n" + select MBEDTLS_AES_C + help + Enable this flag to use mbedtls crypto algorithm from ROM instead of ESP-IDF + in case of a bootloader build. + Similar to the MBEDTLS_USE_CRYPTO_ROM_IMPL config but enables usage of the + mbedtls crypto algorithm from ROM for the bootloader build. + config MBEDTLS_USE_CRYPTO_ROM_IMPL bool "Use ROM implementation of the crypto algorithm" depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB diff --git a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h index b612adfa55..52fe58de3e 100644 --- a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h +++ b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include #include "mbedtls/aes.h" #include "mbedtls/asn1.h" #include "mbedtls/asn1write.h" @@ -43,6 +44,7 @@ extern "C" { #endif +#ifndef BOOTLOADER_BUILD #if (!defined(CONFIG_MBEDTLS_THREADING_C)) #error CONFIG_MBEDTLS_THREADING_C #endif @@ -51,6 +53,9 @@ typedef void (*_rom_mbedtls_threading_set_alt_t)(void (*mutex_init)(mbedtls_thre void (*mutex_free)(mbedtls_threading_mutex_t *), int (*mutex_lock)(mbedtls_threading_mutex_t *), int (*mutex_unlock)(mbedtls_threading_mutex_t *)); +#else /* BOOTLOADER_BUILD */ +typedef void mbedtls_threading_mutex_t; +#endif /* BOOTLOADER_BUILD */ typedef struct mbedtls_rom_funcs { void (*_rom_mbedtls_aes_init)( mbedtls_aes_context *ctx ); @@ -659,8 +664,8 @@ typedef struct mbedtls_rom_eco4_funcs { #define STRUCT_OFFSET_CHECK(x, y, z) _Static_assert((offsetof(x,y)==(z)), "The variables type of "#x" before "#y" should be "#z) #define STRUCT_SIZE_CHECK(x, y) _Static_assert((sizeof(x)==(y)), "The sizeof "#x" should be "#y) -#if (!defined(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)) -#error "CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL" +#if (!defined(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) && !defined(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER)) +#error "Please enable CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL or CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER" #endif /* platform_util.c */ @@ -668,6 +673,7 @@ typedef struct mbedtls_rom_eco4_funcs { #error "MBEDTLS_PLATFORM_ZEROIZE_ALT" #endif +#ifndef BOOTLOADER_BUILD /* sha1.c */ STRUCT_OFFSET_CHECK(mbedtls_sha1_context, total, 0); STRUCT_OFFSET_CHECK(mbedtls_sha1_context, state, 8); @@ -788,6 +794,11 @@ STRUCT_OFFSET_CHECK(mbedtls_md5_context, MBEDTLS_PRIVATE(state), 8); STRUCT_OFFSET_CHECK(mbedtls_md5_context, MBEDTLS_PRIVATE(buffer), 24); STRUCT_SIZE_CHECK(mbedtls_md5_context, 88); #endif +#endif /* BOOTLOADER_BUILD */ + +#if BOOTLOADER_BUILD +void mbedtls_rom_osi_functions_init_bootloader(void); +#endif /* BOOTLOADER_BUILD */ #ifdef __cplusplus } diff --git a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi_bootloader.c b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi_bootloader.c new file mode 100644 index 0000000000..2c730a9ff7 --- /dev/null +++ b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi_bootloader.c @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" +#include "mbedtls_rom_osi.h" + +/* This structure can be automatically generated by the script with rom.mbedtls.ld. */ +static const mbedtls_rom_funcs_t mbedtls_rom_funcs_table = { + /* Fill the ROM functions into mbedtls rom function table. */ + /* aes module */ + ._rom_mbedtls_aes_init = mbedtls_aes_init, + ._rom_mbedtls_aes_free = mbedtls_aes_free, + ._rom_mbedtls_aes_setkey_enc = mbedtls_aes_setkey_enc, + ._rom_mbedtls_aes_setkey_dec = mbedtls_aes_setkey_dec, + ._rom_mbedtls_aes_crypt_ecb = mbedtls_aes_crypt_ecb, + ._rom_mbedtls_aes_crypt_cbc = mbedtls_aes_crypt_cbc, + ._rom_mbedtls_internal_aes_encrypt = mbedtls_internal_aes_encrypt, + ._rom_mbedtls_internal_aes_decrypt = mbedtls_internal_aes_decrypt, +}; + +/* This structure can be automatically generated by the script with rom.mbedtls.ld. */ +static const mbedtls_rom_eco4_funcs_t mbedtls_rom_eco4_funcs_table = { + /* Fill the ROM functions into mbedtls rom function table. */ + /* aes module */ + ._rom_mbedtls_aes_init = mbedtls_aes_init, + ._rom_mbedtls_aes_free = mbedtls_aes_free, + ._rom_mbedtls_aes_setkey_enc = mbedtls_aes_setkey_enc, + ._rom_mbedtls_aes_setkey_dec = mbedtls_aes_setkey_dec, + ._rom_mbedtls_aes_crypt_ecb = mbedtls_aes_crypt_ecb, + ._rom_mbedtls_aes_crypt_cbc = mbedtls_aes_crypt_cbc, + ._rom_mbedtls_internal_aes_encrypt = mbedtls_internal_aes_encrypt, + ._rom_mbedtls_internal_aes_decrypt = mbedtls_internal_aes_decrypt, + + ._rom_mbedtls_aes_xts_init = mbedtls_aes_xts_init, + ._rom_mbedtls_aes_xts_free = mbedtls_aes_xts_free, + ._rom_mbedtls_aes_xts_setkey_enc = mbedtls_aes_xts_setkey_enc, + ._rom_mbedtls_aes_xts_setkey_dec = mbedtls_aes_xts_setkey_dec, + ._rom_mbedtls_aes_crypt_xts = mbedtls_aes_crypt_xts, +}; + +void mbedtls_rom_osi_functions_init_bootloader(void) +{ + // /* Export the rom mbedtls functions table pointer */ + extern void *mbedtls_rom_osi_funcs_ptr; + + unsigned chip_version = efuse_hal_chip_revision(); + if ( ESP_CHIP_REV_ABOVE(chip_version, 200) ) { + /* Initialize the pointer of rom eco4 mbedtls functions table. */ + mbedtls_rom_osi_funcs_ptr = (mbedtls_rom_eco4_funcs_t *)&mbedtls_rom_eco4_funcs_table; + } else { + /* Initialize the pointer of rom mbedtls functions table. */ + mbedtls_rom_osi_funcs_ptr = (mbedtls_rom_funcs_t *)&mbedtls_rom_funcs_table; + } +} diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index 6f43b478bb..281ff63d8d 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -10,6 +10,7 @@ if(BOOTLOADER_BUILD) idf_component_register(SRCS "${srcs}" REQUIRES "${requires}" + PRIV_REQUIRES "mbedtls" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "private_include" ) diff --git a/components/nvs_flash/private_include/nvs_bootloader_aes.h b/components/nvs_flash/private_include/nvs_bootloader_aes.h index be05e9d4eb..97fc6230be 100644 --- a/components/nvs_flash/private_include/nvs_bootloader_aes.h +++ b/components/nvs_flash/private_include/nvs_bootloader_aes.h @@ -6,18 +6,31 @@ #pragma once #include +#include "soc/soc_caps.h" #include "sdkconfig.h" -#include "rom/aes.h" -#if CONFIG_IDF_TARGET_ESP32 +#if defined(CONFIG_IDF_TARGET_ESP32) || !defined(SOC_AES_SUPPORTED) enum AES_TYPE { AES_ENC, AES_DEC, }; -#endif /* CONFIG_IDF_TARGET_ESP32 */ + +#if !SOC_AES_SUPPORTED +enum AES_BITS { + AES128, + AES192, + AES256 +}; +#endif /* !SOC_AES_SUPPORTED */ +#endif /* CONFIG_IDF_TARGET_ESP32 || !SOC_AES_SUPPORTED */ + +#if SOC_AES_SUPPORTED +#include "rom/aes.h" int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, const unsigned char *key, enum AES_BITS key_bits, const unsigned char input[16], unsigned char output[16]); + +#endif /* SOC_AES_SUPPORTED */ diff --git a/components/nvs_flash/src/nvs_bootloader_aes.c b/components/nvs_flash/src/nvs_bootloader_aes.c index c6a2e20cf0..5cbbab5ad0 100644 --- a/components/nvs_flash/src/nvs_bootloader_aes.c +++ b/components/nvs_flash/src/nvs_bootloader_aes.c @@ -1,13 +1,16 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "esp_log.h" +#include "soc/soc_caps.h" #include "nvs_bootloader_aes.h" #include "sdkconfig.h" +#if SOC_AES_SUPPORTED int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, const unsigned char *key, enum AES_BITS key_bits, @@ -30,14 +33,79 @@ int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, // whereas for other targets ets_aes_setkey return 0 on success ret = 0; } -#else /* !CONFIG_IDF_TARGET_ESP32m*/ +#else /* CONFIG_IDF_TARGET_ESP32 */ ret = ets_aes_setkey(mode, key, key_bits); if (ret == 0) { ets_aes_block(input, output); } -#endif /* CONFIG_IDF_TARGET_ESP32 */ +#endif /* !CONFIG_IDF_TARGET_ESP32 */ ets_aes_disable(); return ret; } + +#else /* SOC_AES_SUPPORTED */ +#if BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER +#if CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB +#error "Enable `CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER` for non SOC_AES_SUPPORTED targets for supporting NVS encryption in bootloader build" +#else /* !CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ +// TODO: IDF-11673 +// Due to unavailability of an software AES layer for bootloader build, +// we cannot support the below NVS bootloader's AES operations +// Thus we are adding stub APIs to indicate that the following operation fail. + +static const char *TAG = "nvs_bootloader_aes"; +static const char *op_unsupported_error = "AES operation in bootloader unsupported for this target"; + +int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, + const unsigned char *key, + enum AES_BITS key_bits, + const unsigned char input[16], + unsigned char output[16]) +{ + ESP_EARLY_LOGE(TAG, "%s", op_unsupported_error); + abort(); + return -1; +} +#endif /* CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ +#else /* BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER */ +#include "mbedtls/aes.h" + +int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, + const unsigned char *key, + enum AES_BITS key_bits, + const unsigned char input[16], + unsigned char output[16]) +{ + int ret = -1; + + uint16_t keybits = key_bits == AES256 ? 256 : key_bits == AES192 ? 192 : 128; + int mbedtls_aes_mode = mode == AES_ENC ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT; + + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); + + if (mode == AES_ENC) { + ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + } else { + ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); + } + + if (ret != 0) { + mbedtls_aes_free(&ctx); + return ret; + } + + ret = mbedtls_aes_crypt_ecb(&ctx, mbedtls_aes_mode, input, output); + + if (ret != 0) { + mbedtls_aes_free(&ctx); + return ret; + } + + mbedtls_aes_free(&ctx); + return ret; +} +#endif /* !(BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER) */ +#endif /* !SOC_AES_SUPPORTED */ diff --git a/components/nvs_flash/src/nvs_bootloader_xts_aes.c b/components/nvs_flash/src/nvs_bootloader_xts_aes.c index bd7500f537..ce204f6a9d 100644 --- a/components/nvs_flash/src/nvs_bootloader_xts_aes.c +++ b/components/nvs_flash/src/nvs_bootloader_xts_aes.c @@ -7,10 +7,15 @@ #include #include #include "esp_err.h" +#include "esp_log.h" #include "nvs_bootloader_aes.h" #include "nvs_bootloader_xts_aes.h" +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#if SOC_AES_SUPPORTED /* * NOTE: The implementation of the below APIs have been copied * from the mbedtls (v3.6.2) implementation of the XTS-AES APIs. @@ -198,3 +203,97 @@ int nvs_bootloader_aes_crypt_xts(nvs_bootloader_xts_aes_context *ctx, return 0; } +#else /* SOC_AES_SUPPORTED */ +#if BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER +#if CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB +#error "Enable `CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER` for non SOC_AES_SUPPORTED targets for supporting NVS encryption in bootloader build" +#else /* !CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ +// TODO: IDF-11673 +// Due to unavailability of an software AES layer for bootloader build, +// we cannot support the below NVS bootloader's AES operations +// Thus we are adding stub APIs to indicate that the following operation fail. + +static const char *TAG = "nvs_bootloader_xts_aes"; +static const char *op_unsupported_error = "XTS-AES operation in bootloader unsupported for this target"; + +void nvs_bootloader_xts_aes_init(nvs_bootloader_xts_aes_context *ctx) +{ + (void) ctx; + ESP_EARLY_LOGE(TAG, "%s", op_unsupported_error); + abort(); +} + +void nvs_bootloader_xts_aes_free(nvs_bootloader_xts_aes_context *ctx) +{ + (void) ctx; + ESP_EARLY_LOGE(TAG, "%s", op_unsupported_error); + abort(); +} + +int nvs_bootloader_xts_aes_setkey(nvs_bootloader_xts_aes_context *ctx, + const unsigned char *key, + unsigned int key_bytes) +{ + (void) ctx; + ESP_EARLY_LOGE(TAG, "%s", op_unsupported_error); + abort(); + return -1; +} +/* + * XTS-AES buffer encryption/decryption + */ +int nvs_bootloader_aes_crypt_xts(nvs_bootloader_xts_aes_context *ctx, + enum AES_TYPE mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output) +{ + (void) ctx; + ESP_EARLY_LOGE(TAG, "XTS-AES operation in bootloader unsupported"); + abort(); + return -1; +} + +#endif /* CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ +#else /* BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER */ +#include "mbedtls/aes.h" + +static mbedtls_aes_xts_context ctx_xts; + +void nvs_bootloader_xts_aes_init(nvs_bootloader_xts_aes_context *ctx) +{ + (void) ctx; + mbedtls_aes_xts_init(&ctx_xts); +} + +void nvs_bootloader_xts_aes_free(nvs_bootloader_xts_aes_context *ctx) +{ + (void) ctx; + mbedtls_aes_xts_free(&ctx_xts); +} + +int nvs_bootloader_xts_aes_setkey(nvs_bootloader_xts_aes_context *ctx, + const unsigned char *key, + unsigned int key_bytes) +{ + (void) ctx; + return mbedtls_aes_xts_setkey_dec(&ctx_xts, key, key_bytes * 8); +} +/* + * XTS-AES buffer encryption/decryption + */ +int nvs_bootloader_aes_crypt_xts(nvs_bootloader_xts_aes_context *ctx, + enum AES_TYPE mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output) +{ + (void) ctx; + + int mbedtls_aes_mode = mode == AES_ENC ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT; + return mbedtls_aes_crypt_xts(&ctx_xts, mbedtls_aes_mode, length, data_unit, input, output); +} +#endif /* !(BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER) */ +#endif /* !SOC_AES_SUPPORTED */