diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.eco4.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.eco4.ld index 53b9bacc5cb..842d468c858 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.eco4.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.eco4.ld @@ -138,14 +138,14 @@ mbedtls_mpi_gcd = 0x40002768; mbedtls_mpi_inv_mod = 0x4000276c; mbedtls_mpi_is_prime_ext = 0x40002770; -mbedtls_cipher_init = 0x4000277c; -mbedtls_cipher_set_padding_mode = 0x40002780; -mbedtls_cipher_reset = 0x40002784; -mbedtls_cipher_finish = 0x40002788; -mbedtls_cipher_crypt = 0x4000278c; -mbedtls_cipher_cmac_starts = 0x40002790; -mbedtls_cipher_cmac_update = 0x40002794; -mbedtls_cipher_cmac_finish = 0x40002798; +/*mbedtls_cipher_init = 0x4000277c;*/ +/*mbedtls_cipher_set_padding_mode = 0x40002780;*/ +/*mbedtls_cipher_reset = 0x40002784;*/ +/*mbedtls_cipher_finish = 0x40002788;*/ +/*mbedtls_cipher_crypt = 0x4000278c;*/ +/*mbedtls_cipher_cmac_starts = 0x40002790;*/ +/*mbedtls_cipher_cmac_update = 0x40002794;*/ +/*mbedtls_cipher_cmac_finish = 0x40002798;*/ /*************************************** Group eco4_rom_mbedtls diff --git a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c index c345cf5bef0..ac72ab87498 100644 --- a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c +++ b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c @@ -17,7 +17,8 @@ #define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA MBEDTLS_ERR_THREADING_USAGE_ERROR #endif -_Static_assert(sizeof(mbedtls_rom_eco4_funcs_t) == 221 * sizeof(void (*)(void)), +#define MBEDTLS_ROM_ECO4_FUNC_COUNT 221 +_Static_assert(sizeof(mbedtls_rom_eco4_funcs_t) == MBEDTLS_ROM_ECO4_FUNC_COUNT * sizeof(void (*)(void)), "mbedtls_rom_eco4_funcs_t layout must match ROM"); #define ROM_TABLE_FN(table_type, field, fn) ((__typeof__(((table_type *)0)->field))(fn)) @@ -46,65 +47,267 @@ extern void rom_mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_m int (*mutex_lock)(mbedtls_threading_mutex_t *), int (*mutex_unlock)(mbedtls_threading_mutex_t *)); -static void mbedtls_rom_mutex_init( mbedtls_threading_mutex_t *mutex ) -{ - if (mutex == NULL) { - return; - } - #if defined(MBEDTLS_THREADING_ALT) - mutex->mutex = xSemaphoreCreateMutex(); - assert(mutex->mutex != NULL); +static int mbedtls_rom_platform_mutex_init(mbedtls_platform_mutex_t *mutex); +static void mbedtls_rom_platform_mutex_free(mbedtls_platform_mutex_t *mutex); +static int mbedtls_rom_platform_mutex_lock(mbedtls_platform_mutex_t *mutex); +static int mbedtls_rom_platform_mutex_unlock(mbedtls_platform_mutex_t *mutex); +#endif + +static void mbedtls_rom_mutex_init(mbedtls_threading_mutex_t *mutex) +{ +#if defined(MBEDTLS_THREADING_ALT) + int ret = mbedtls_rom_platform_mutex_init(&mutex->MBEDTLS_PRIVATE(mutex)); + mutex->MBEDTLS_PRIVATE(initialized) = (ret == 0); #else mbedtls_mutex_init(mutex); #endif } -static void mbedtls_rom_mutex_free( mbedtls_threading_mutex_t *mutex ) +static void mbedtls_rom_mutex_free(mbedtls_threading_mutex_t *mutex) { - if (mutex == NULL) { +#if defined(MBEDTLS_THREADING_ALT) + if (!mutex->MBEDTLS_PRIVATE(initialized)) { return; } - -#if defined(MBEDTLS_THREADING_ALT) - vSemaphoreDelete(mutex->mutex); + mbedtls_rom_platform_mutex_free(&mutex->MBEDTLS_PRIVATE(mutex)); + mutex->MBEDTLS_PRIVATE(initialized) = 0; #else mbedtls_mutex_free(mutex); #endif } -static int mbedtls_rom_mutex_lock( mbedtls_threading_mutex_t *mutex ) +static int mbedtls_rom_mutex_lock(mbedtls_threading_mutex_t *mutex) { - if (mutex == NULL) { - return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; - } - #if defined(MBEDTLS_THREADING_ALT) - if (xSemaphoreTake(mutex->mutex, portMAX_DELAY) != pdTRUE) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + if (!mutex->MBEDTLS_PRIVATE(initialized)) { + return MBEDTLS_ERR_THREADING_USAGE_ERROR; } - return 0; + return mbedtls_rom_platform_mutex_lock(&mutex->MBEDTLS_PRIVATE(mutex)); #else return mbedtls_mutex_lock(mutex); #endif } -static int mbedtls_rom_mutex_unlock( mbedtls_threading_mutex_t *mutex ) +static int mbedtls_rom_mutex_unlock(mbedtls_threading_mutex_t *mutex) +{ +#if defined(MBEDTLS_THREADING_ALT) + if (!mutex->MBEDTLS_PRIVATE(initialized)) { + return MBEDTLS_ERR_THREADING_USAGE_ERROR; + } + return mbedtls_rom_platform_mutex_unlock(&mutex->MBEDTLS_PRIVATE(mutex)); +#else + return mbedtls_mutex_unlock(mutex); +#endif +} + +#if defined(MBEDTLS_THREADING_ALT) +static int mbedtls_rom_platform_mutex_init(mbedtls_platform_mutex_t *mutex) { if (mutex == NULL) { return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; } -#if defined(MBEDTLS_THREADING_ALT) + mutex->mutex = xSemaphoreCreateMutex(); + mutex->is_valid = (mutex->mutex != NULL); + assert(mutex->is_valid); + return mutex->is_valid ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR; +} + +static void mbedtls_rom_platform_mutex_free(mbedtls_platform_mutex_t *mutex) +{ + if (mutex == NULL || !mutex->is_valid) { + return; + } + + vSemaphoreDelete(mutex->mutex); + mutex->mutex = NULL; + mutex->is_valid = 0; +} + +static int mbedtls_rom_platform_mutex_lock(mbedtls_platform_mutex_t *mutex) +{ + if (mutex == NULL || !mutex->is_valid) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + + if (xSemaphoreTake(mutex->mutex, portMAX_DELAY) != pdTRUE) { + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + return 0; +} + +static int mbedtls_rom_platform_mutex_unlock(mbedtls_platform_mutex_t *mutex) +{ + if (mutex == NULL || !mutex->is_valid) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + if (xSemaphoreGive(mutex->mutex) != pdTRUE) { return MBEDTLS_ERR_THREADING_MUTEX_ERROR; } return 0; -#else - return mbedtls_mutex_unlock(mutex); -#endif } +typedef struct mbedtls_rom_cond_waiter { + SemaphoreHandle_t semaphore; + struct mbedtls_rom_cond_waiter *next; +} mbedtls_rom_cond_waiter_t; + +static void mbedtls_rom_cond_remove_waiter(mbedtls_platform_condition_variable_t *cond, + mbedtls_rom_cond_waiter_t *waiter) +{ + mbedtls_rom_cond_waiter_t **current = &cond->waiters; + + while (*current != NULL) { + if (*current == waiter) { + *current = waiter->next; + waiter->next = NULL; + return; + } + current = &(*current)->next; + } +} + +static int mbedtls_rom_cond_init(mbedtls_platform_condition_variable_t *cond) +{ + if (cond == NULL) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + + cond->mutex = xSemaphoreCreateMutex(); + cond->waiters = NULL; + cond->is_valid = (cond->mutex != NULL); + return cond->is_valid ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR; +} + +static void mbedtls_rom_cond_free(mbedtls_platform_condition_variable_t *cond) +{ + if (cond == NULL || !cond->is_valid) { + return; + } + + vSemaphoreDelete(cond->mutex); + cond->mutex = NULL; + cond->waiters = NULL; + cond->is_valid = 0; +} + +static int mbedtls_rom_cond_signal(mbedtls_platform_condition_variable_t *cond) +{ + mbedtls_rom_cond_waiter_t *waiter; + + if (cond == NULL || !cond->is_valid) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + + if (xSemaphoreTake(cond->mutex, portMAX_DELAY) != pdTRUE) { + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + waiter = cond->waiters; + if (waiter != NULL) { + cond->waiters = waiter->next; + waiter->next = NULL; + if (xSemaphoreGive(waiter->semaphore) != pdTRUE) { + (void) xSemaphoreGive(cond->mutex); + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + } + + if (xSemaphoreGive(cond->mutex) != pdTRUE) { + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + return 0; +} + +static int mbedtls_rom_cond_broadcast(mbedtls_platform_condition_variable_t *cond) +{ + mbedtls_rom_cond_waiter_t *waiter; + + if (cond == NULL || !cond->is_valid) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + + if (xSemaphoreTake(cond->mutex, portMAX_DELAY) != pdTRUE) { + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + waiter = cond->waiters; + cond->waiters = NULL; + + while (waiter != NULL) { + mbedtls_rom_cond_waiter_t *next = waiter->next; + waiter->next = NULL; + if (xSemaphoreGive(waiter->semaphore) != pdTRUE) { + (void) xSemaphoreGive(cond->mutex); + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + waiter = next; + } + + return (xSemaphoreGive(cond->mutex) == pdTRUE) ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR; +} + +static int mbedtls_rom_cond_wait(mbedtls_platform_condition_variable_t *cond, + mbedtls_platform_mutex_t *mutex) +{ + int ret; + mbedtls_rom_cond_waiter_t waiter = { 0 }; + + if (cond == NULL || mutex == NULL || !cond->is_valid) { + return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + } + + waiter.semaphore = xSemaphoreCreateBinary(); + if (waiter.semaphore == NULL) { + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + if (xSemaphoreTake(cond->mutex, portMAX_DELAY) != pdTRUE) { + vSemaphoreDelete(waiter.semaphore); + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + waiter.next = cond->waiters; + cond->waiters = &waiter; + + if (xSemaphoreGive(cond->mutex) != pdTRUE) { + cond->waiters = waiter.next; + waiter.next = NULL; + vSemaphoreDelete(waiter.semaphore); + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + ret = mbedtls_rom_platform_mutex_unlock(mutex); + if (ret != 0) { + if (xSemaphoreTake(cond->mutex, portMAX_DELAY) == pdTRUE) { + mbedtls_rom_cond_remove_waiter(cond, &waiter); + (void) xSemaphoreGive(cond->mutex); + } + vSemaphoreDelete(waiter.semaphore); + return ret; + } + + if (xSemaphoreTake(waiter.semaphore, portMAX_DELAY) != pdTRUE) { + if (xSemaphoreTake(cond->mutex, portMAX_DELAY) == pdTRUE) { + mbedtls_rom_cond_remove_waiter(cond, &waiter); + (void) xSemaphoreGive(cond->mutex); + } + vSemaphoreDelete(waiter.semaphore); + (void) mbedtls_rom_platform_mutex_lock(mutex); + return MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + + vSemaphoreDelete(waiter.semaphore); + ret = mbedtls_rom_platform_mutex_lock(mutex); + /* The wakeup has already been consumed, so a re-lock failure is unrecoverable. */ + assert(ret == 0); + return ret; +} +#endif + /* 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. */ @@ -337,7 +540,15 @@ __attribute__((constructor)) void mbedtls_rom_osi_functions_init(void) extern void *mbedtls_rom_osi_funcs_ptr; #if defined(MBEDTLS_THREADING_ALT) - mbedtls_threading_set_alt(mbedtls_rom_mutex_init, mbedtls_rom_mutex_free, mbedtls_rom_mutex_lock, mbedtls_rom_mutex_unlock); + mbedtls_threading_set_alt(mbedtls_rom_platform_mutex_init, + mbedtls_rom_platform_mutex_free, + mbedtls_rom_platform_mutex_lock, + mbedtls_rom_platform_mutex_unlock, + mbedtls_rom_cond_init, + mbedtls_rom_cond_free, + mbedtls_rom_cond_signal, + mbedtls_rom_cond_broadcast, + mbedtls_rom_cond_wait); #endif /* Initialize the rom function mbedtls_threading_set_alt on chip rev2.0 with rom eco4 */ diff --git a/components/mbedtls/port/mbedtls_rom/threading_alt.h b/components/mbedtls/port/mbedtls_rom/threading_alt.h index 6dc3349da1e..36367b98a10 100644 --- a/components/mbedtls/port/mbedtls_rom/threading_alt.h +++ b/components/mbedtls/port/mbedtls_rom/threading_alt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,15 +8,20 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -typedef struct mbedtls_threading_mutex_t { +struct mbedtls_rom_cond_waiter; + +typedef struct mbedtls_platform_mutex_t { SemaphoreHandle_t mutex; /* is_valid is 0 after a failed init or a free, and nonzero after a * successful init. This field is not considered part of the public * API of Mbed TLS and may change without notice. */ char is_valid; -} mbedtls_threading_mutex_t; +} mbedtls_platform_mutex_t; -extern void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), - void (*mutex_free)(mbedtls_threading_mutex_t *), - int (*mutex_lock)(mbedtls_threading_mutex_t *), - int (*mutex_unlock)(mbedtls_threading_mutex_t *)); +typedef struct mbedtls_platform_condition_variable_t { + /* Protects the waiter list below. */ + SemaphoreHandle_t mutex; + /* Intrusive list of threads currently blocked on this condition variable. */ + struct mbedtls_rom_cond_waiter *waiters; + char is_valid; +} mbedtls_platform_condition_variable_t;