diff --git a/wolfcrypt/src/port/Espressif/esp32_aes.c b/wolfcrypt/src/port/Espressif/esp32_aes.c index b1479de338d..45a1b284b24 100644 --- a/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -474,16 +474,26 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) int ret; ESP_LOGV(TAG, "enter wc_esp32AesDecrypt"); - /* lock the hw engine */ - esp_aes_hw_InUse(); - /* load the key into the register */ + + /* Validate parameters */ + if (aes == NULL || in == NULL || out == NULL) { + ESP_LOGE(TAG, "Invalid parameters"); + return BAD_FUNC_ARG; + } + + /* Lock the hw engine */ + ret = esp_aes_hw_InUse(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to acquire HW lock"); + return ret; + } + + /* Load the key into the register */ ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); if (ret != ESP_OK) { - ESP_LOGE(TAG, "wc_esp32AesDecrypt failed " - "during esp_aes_hw_Set_KeyMode"); - /* release hw */ + ESP_LOGE(TAG, "Failed during esp_aes_hw_Set_KeyMode"); esp_aes_hw_Leave(); - ret = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } if (ret == ESP_OK) { @@ -514,13 +524,27 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) int ret; int i; int offset = 0; - word32 blocks = (sz / WC_AES_BLOCK_SIZE); + word32 blocks; byte *iv; byte temp_block[WC_AES_BLOCK_SIZE]; ESP_LOGV(TAG, "enter wc_esp32AesCbcEncrypt"); + /* Validate parameters */ + if (aes == NULL || out == NULL || in == NULL) { + ESP_LOGE(TAG, "Invalid parameters"); + return BAD_FUNC_ARG; + } + + /* Validate size */ + if (sz == 0 || (sz % WC_AES_BLOCK_SIZE) != 0) { + ESP_LOGE(TAG, "Invalid size: must be multiple of block size"); + return BAD_FUNC_ARG; + } + + blocks = sz / WC_AES_BLOCK_SIZE; iv = (byte*)aes->reg; + XMEMSET(temp_block, 0, WC_AES_BLOCK_SIZE); ret = esp_aes_hw_InUse(); @@ -570,16 +594,29 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { int ret; - int i; int offset = 0; - word32 blocks = (sz / WC_AES_BLOCK_SIZE); + word32 blocks; byte* iv; byte temp_block[WC_AES_BLOCK_SIZE]; ESP_LOGV(TAG, "enter wc_esp32AesCbcDecrypt"); + /* Validate parameters */ + if (aes == NULL || out == NULL || in == NULL) { + ESP_LOGE(TAG, "Invalid parameters"); + return BAD_FUNC_ARG; + } + + /* Validate size */ + if (sz == 0 || (sz % WC_AES_BLOCK_SIZE) != 0) { + ESP_LOGE(TAG, "Invalid size: must be multiple of block size"); + return BAD_FUNC_ARG; + } + + blocks = sz / WC_AES_BLOCK_SIZE; iv = (byte*)aes->reg; + XMEMSET(temp_block, 0, WC_AES_BLOCK_SIZE); ret = esp_aes_hw_InUse(); diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index dbfd13342a3..4aeaacb47fa 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -788,13 +788,18 @@ static int esp_clean_result(MATH_INT_T* Z, int used_padding) /* Start HW process. Reg is SoC-specific register. */ static int process_start(u_int32_t reg) { - int ret = MP_OKAY; - /* see 3.16 "software needs to always use the "volatile" - ** attribute when accessing registers in these two address spaces. */ + if (reg == 0) { + ESP_LOGE(TAG, "Invalid register in process_start"); + return MP_VAL; + } + + /* See 3.16: "software needs to always use the 'volatile' + * attribute when accessing registers in these address spaces" */ + portENTER_CRITICAL(&wc_rsa_reg_lock); DPORT_REG_WRITE((volatile word32*)reg, 1); - ESP_EM__POST_PROCESS_START; + portEXIT_CRITICAL(&wc_rsa_reg_lock); - return ret; + return MP_OKAY; } /* wait until RSA math register indicates operation completed */ @@ -803,27 +808,31 @@ static int wait_until_done(word32 reg) int ret = MP_OKAY; word32 timeout = 0; - /* wait until done && not timeout */ - ESP_EM__MP_HW_WAIT_DONE; - while (!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(reg) != 1) { - asm volatile("nop"); /* wait */ + if (reg == 0) { + ESP_LOGE(TAG, "Invalid register in wait_until_done"); + return MP_VAL; } - ESP_EM__DPORT_FIFO_READ; -#if defined(CONFIG_IDF_TARGET_ESP32C6) - /* Write 1 or 0 to the RSA_INT_ENA_REG register to - * enable or disable the interrupt function. */ - DPORT_REG_WRITE(RSA_INT_CLR_REG, 1); /* write 1 to clear */ - DPORT_REG_WRITE(RSA_INT_ENA_REG, 0); /* disable */ + /* Wait until done && not timeout */ + while (!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(reg) != 1) { + /* Expected delay 1-2 µs */ + } -#elif defined(CONFIG_IDF_TARGET_ESP32C3) - /* not currently clearing / disable on C3 */ - DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); + /* Handle timeouts and cleanup */ + if (ESP_TIMEOUT(timeout)) { + ESP_LOGE(TAG, "Hardware operation timeout in wait_until_done"); + ret = WC_HW_E; + goto cleanup; + } + /* Clear interrupts based on target */ +#if defined(CONFIG_IDF_TARGET_ESP32C6) + /* Write 1 to clear, 0 to disable interrupt function */ + DPORT_REG_WRITE(RSA_INT_CLR_REG, 1); + DPORT_REG_WRITE(RSA_INT_ENA_REG, 0); #else - /* clear interrupt */ + /* Clear interrupt for other targets */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); - #endif #if defined(WOLFSSL_HW_METRICS) @@ -832,9 +841,11 @@ static int wait_until_done(word32 reg) } #endif - if (ESP_TIMEOUT(timeout)) { - ESP_LOGE(TAG, "rsa operation timed out."); - ret = WC_HW_E; /* MP_HW_ERROR; */ +cleanup: + if (ret != MP_OKAY) { + /* Force hardware reset on error */ + periph_module_disable(PERIPH_RSA_MODULE); + periph_module_enable(PERIPH_RSA_MODULE); } return ret; @@ -846,12 +857,27 @@ static int esp_memblock_to_mpint(const word32 mem_address, word32 numwords) { int ret = MP_OKAY; + + if (mp == NULL || numwords == 0 || mem_address == 0 || + numwords > (ESP_HW_MOD_RSAMAX_BITS / 32)) { + ESP_LOGE(TAG, "Invalid parameters in esp_memblock_to_mpint"); + return MP_VAL; + } + + /* Initialize mp->used to prevent buffer overflow */ + mp->used = numwords; + if (mp->used > MP_SIZE) { + ESP_LOGE(TAG, "Buffer overflow prevented in esp_memblock_to_mpint"); + return MP_VAL; + } + + /* Clear destination buffer before copying */ + XMEMSET(mp->dp, 0, numwords * sizeof(word32)); + #ifdef USE_ESP_DPORT_ACCESS_READ_BUFFER esp_dport_access_read_buffer((word32*)mp->dp, mem_address, numwords); #else - ESP_EM__PRE_DPORT_READ; - DPORT_INTERRUPT_DISABLE(); - ESP_EM__READ_NON_FIFO_REG; + portENTER_CRITICAL(&wc_rsa_reg_lock); for (volatile word32 i = 0; i < numwords; ++i) { ESP_EM__3_16; mp->dp[i] = DPORT_SEQUENCE_REG_READ( diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index f9f8d90951d..9af20852aed 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -1273,39 +1273,53 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx) if (sha_mutex == NULL) { ESP_LOGV(TAG, "Initializing sha_mutex"); - /* created, but not yet locked */ - ret = esp_CryptHwMutexInit(&sha_mutex); - if (ret == 0) { + /* Atomic mutex initialization */ + taskENTER_CRITICAL(&sha_crit_sect); + if (sha_mutex == NULL) { + /* created, but not yet locked */ + ret = esp_CryptHwMutexInit(&sha_mutex); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize sha_mutex"); + taskEXIT_CRITICAL(&sha_crit_sect); + ctx->mode = ESP32_SHA_SW; + return ESP_OK; /* Success but revert to SW */ + } + ESP_LOGV(TAG, "esp_CryptHwMutexInit sha_mutex init success."); esp_sha_mutex_ctx_owner_clear(); /* No one has the mutex yet. */ - #ifdef WOLFSSL_DEBUG_MUTEX - { - /* Take mutex for lock/unlock test drive to ensure it works: */ - ret = esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0); - if (ret == ESP_OK) { - ret = esp_CryptHwMutexUnLock(&sha_mutex); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "esp_CryptHwMutexInit fail init lock."); - } - } - else { - ESP_LOGE(TAG, "esp_CryptHwMutexInit fail init unlock."); - } + + /* Verify mutex works properly */ + ret = esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed initial mutex lock test"); + esp_CryptHwMutexDestroy(&sha_mutex); + sha_mutex = NULL; + taskEXIT_CRITICAL(&sha_crit_sect); + ctx->mode = ESP32_SHA_SW; + return ESP_OK; /* Success but revert to SW */ } - #endif - } /* ret == 0 for esp_CryptHwMutexInit */ - else { + + ret = esp_CryptHwMutexUnLock(&sha_mutex); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed initial mutex unlock test"); + esp_CryptHwMutexDestroy(&sha_mutex); + sha_mutex = NULL; + taskEXIT_CRITICAL(&sha_crit_sect); + ctx->mode = ESP32_SHA_SW; + return ESP_OK; /* Success but revert to SW */ + } + } + taskEXIT_CRITICAL(&sha_crit_sect); + + if (ret != ESP_OK) { ESP_LOGE(TAG, "esp_CryptHwMutexInit sha_mutex failed."); #ifdef WOLFSSL_DEBUG_MUTEX { - ESP_LOGV(TAG, "Current mutext owner = %x", this_mutex_owner); + ESP_LOGV(TAG, "Current mutex owner = %x", this_mutex_owner); } #endif sha_mutex = NULL; - - ESP_LOGV(TAG, "Revert to ctx->mode = ESP32_SHA_SW."); - ctx->mode = ESP32_SHA_SW; return ESP_OK; /* success, just not using HW */ } @@ -1375,12 +1389,18 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx) * TODO: allow for SHA interleave on chips that support it. */ - if ((mutex_ctx_owner == NULLPTR) && - esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0) == ESP_OK) { - /* we've successfully locked */ - this_mutex_owner = (uintptr_t)ctx; - esp_sha_mutex_ctx_owner_set(this_mutex_owner); - ESP_LOGV(TAG, "Assigned mutex_ctx_owner to 0x%x", this_mutex_owner); + /* Atomic check and lock */ + taskENTER_CRITICAL(&sha_crit_sect); + if (mutex_ctx_owner == NULLPTR) { + ret = esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0); + if (ret == ESP_OK) { + /* Successfully locked */ + this_mutex_owner = (uintptr_t)ctx; + esp_sha_mutex_ctx_owner_set(this_mutex_owner); + ESP_LOGV(TAG, "Assigned mutex_ctx_owner to 0x%x", this_mutex_owner); + } + } + taskEXIT_CRITICAL(&sha_crit_sect); #ifdef ESP_MONITOR_HW_TASK_LOCK mutex_ctx_task = xTaskGetCurrentTaskHandle(); #endif @@ -1568,17 +1588,26 @@ int esp_sha_hw_unlock(WC_ESP32SHA* ctx) #endif + taskENTER_CRITICAL(&sha_crit_sect); if (ctx->lockDepth > 0) { - #if defined(CONFIG_IDF_TARGET_ESP32C2) || \ - defined(CONFIG_IDF_TARGET_ESP8684) || \ - defined(CONFIG_IDF_TARGET_ESP32C3) || \ - defined(CONFIG_IDF_TARGET_ESP32C6) - ets_sha_disable(); /* disable also resets active, ongoing hash */ - ESP_LOGV(TAG, "ets_sha_disable in esp_sha_hw_unlock()"); - #else - periph_module_disable(PERIPH_SHA_MODULE); - #endif + #if defined(CONFIG_IDF_TARGET_ESP32C2) || \ + defined(CONFIG_IDF_TARGET_ESP8684) || \ + defined(CONFIG_IDF_TARGET_ESP32C3) || \ + defined(CONFIG_IDF_TARGET_ESP32C6) + ets_sha_disable(); /* disable also resets active, ongoing hash */ + ESP_LOGV(TAG, "ets_sha_disable in esp_sha_hw_unlock()"); + #else + periph_module_disable(PERIPH_SHA_MODULE); + #endif ctx->lockDepth--; + + /* Clean up any remaining locks if we're at zero */ + if (ctx->lockDepth == 0) { + esp_CryptHwMutexUnLock(&sha_mutex); + #ifdef ESP_MONITOR_HW_TASK_LOCK + mutex_ctx_task = 0; + #endif + } } else { ESP_LOGW(TAG, "lockDepth <= 0; Disable SHA module skipped for %x", @@ -1586,16 +1615,24 @@ int esp_sha_hw_unlock(WC_ESP32SHA* ctx) ctx->lockDepth = 0; } -#if defined(ESP_MONITOR_HW_TASK_LOCK) && defined(WOLFSSL_ESP32_HW_LOCK_DEBUG) - ESP_LOGI(TAG, "3) esp_sha_hw_unlock Lock depth @ %d = %d " - "for WC_ESP32SHA @ %0x\n", - __LINE__, ctx->lockDepth, (uintptr_t)ctx); -#endif - - if (0 != ctx->lockDepth) { - /* If the lockdepth is not zero, unlock success unknown. */ + /* Handle stray locks if any remain */ + if (ctx->lockDepth > 0) { ESP_LOGE(TAG, "ERROR Non-zero lockDepth. Stray code lock?"); ret = ESP_FAIL; + + /* Force cleanup of stray locks */ + while (ctx->lockDepth > 0) { + #if defined(CONFIG_IDF_TARGET_ESP32C2) || \ + defined(CONFIG_IDF_TARGET_ESP8684) || \ + defined(CONFIG_IDF_TARGET_ESP32C3) || \ + defined(CONFIG_IDF_TARGET_ESP32C6) + ets_sha_disable(); + #else + periph_module_disable(PERIPH_SHA_MODULE); + #endif + ctx->lockDepth--; + } + esp_CryptHwMutexUnLock(&sha_mutex); } else { #if defined(SINGLE_THREADED) @@ -1615,25 +1652,12 @@ int esp_sha_hw_unlock(WC_ESP32SHA* ctx) } #endif /* WOLFSSL_ESP32_HW_LOCK_DEBUG */ - /* There should be exactly 1 instance of SHA unlock, and it's here: */ - esp_CryptHwMutexUnLock(&sha_mutex); - /* We don't set owner to zero here. The HW is not in use, - * but there may be a WIP hash calc (e.g. sha update). - * NO: mutex_ctx_owner = NULLPTR; */ - - #ifdef ESP_MONITOR_HW_TASK_LOCK - mutex_ctx_task = 0; - #endif - #endif #ifdef WOLFSSL_DEBUG_MUTEX - taskENTER_CRITICAL(&sha_crit_sect); - { - mutex_ctx_owner = 0; - } - taskEXIT_CRITICAL(&sha_crit_sect); + mutex_ctx_owner = 0; #endif + taskEXIT_CRITICAL(&sha_crit_sect); } #ifdef WOLFSSL_ESP32_HW_LOCK_DEBUG @@ -2164,14 +2188,19 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) #ifdef WOLFSSL_ESP32_CRYPT_DEBUG ESP_LOGW(TAG, "SHA HW read..."); #endif - esp_dport_access_read_buffer( + + /* Handle different hash pointer types based on ESP-IDF version */ + void* hashPtr; #if ESP_IDF_VERSION_MAJOR >= 4 - (uint32_t*)(hash), /* the result will be found in hash upon exit */ + hashPtr = (uint32_t*)(hash); #else - (word32*)(hash), /* the result will be found in hash upon exit */ + hashPtr = (word32*)(hash); #endif - SHA_TEXT_BASE, /* there's a fixed reg addr for all SHA */ - digestSz / sizeof(word32) /* # 4-byte */ + + esp_dport_access_read_buffer( + hashPtr, /* the result will be found in hash upon exit */ + SHA_TEXT_BASE, /* there's a fixed reg addr for all SHA */ + digestSz / sizeof(word32) /* # 4-byte */ ); #endif diff --git a/wolfcrypt/src/port/Espressif/esp32_util.c b/wolfcrypt/src/port/Espressif/esp32_util.c index 62f40a3d874..51cff07c743 100644 --- a/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/wolfcrypt/src/port/Espressif/esp32_util.c @@ -110,33 +110,43 @@ int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) { */ int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t block_time) { int ret; + + /* Validate parameters */ if (mutex == NULL) { - WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex"); + ESP_LOGE(TAG, "esp_CryptHwMutexLock called with null mutex"); return BAD_MUTEX_E; } + if (block_time == 0) { + ESP_LOGW(TAG, "Zero block time may cause immediate timeout"); + } + #ifdef SINGLE_THREADED - /* does nothing in single thread mode, always return 0 */ + /* Single thread mode - simple lock */ ret = wc_LockMutex(mutex); + if (ret != 0) { + ESP_LOGE(TAG, "wc_LockMutex failed"); + return BAD_MUTEX_E; + } #else + /* Take semaphore with timeout */ ret = xSemaphoreTake(*mutex, block_time); ESP_LOGV(TAG, "xSemaphoreTake 0x%x = %d", (intptr_t)*mutex, ret); + if (ret == pdTRUE) { ret = ESP_OK; } + else if (ret == pdFALSE) { + ESP_LOGW(TAG, "Mutex 0x%x busy - timeout after %d ticks", + (intptr_t)*mutex, block_time); + ret = ESP_ERR_TIMEOUT; + } else { - if (ret == pdFALSE) { - ESP_LOGW(TAG, "xSemaphoreTake failed for 0x%x. Still busy?", - (intptr_t)*mutex); - ret = ESP_ERR_NOT_FINISHED; - } - else { - ESP_LOGE(TAG, "xSemaphoreTake 0x%x unexpected = %d", - (intptr_t)*mutex, ret); - ret = BAD_MUTEX_E; - } + ESP_LOGE(TAG, "Unexpected mutex error: %d", ret); + ret = BAD_MUTEX_E; } #endif + return ret; } @@ -145,36 +155,47 @@ int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t block_time) { * */ esp_err_t esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) { - int ret = pdTRUE; + int ret = ESP_OK; + + /* Validate parameters */ if (mutex == NULL) { - WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex"); + ESP_LOGE(TAG, "esp_CryptHwMutexUnLock called with null mutex"); return BAD_MUTEX_E; } #ifdef SINGLE_THREADED + /* Single thread mode - simple unlock */ ret = wc_UnLockMutex(mutex); + if (ret != 0) { + ESP_LOGE(TAG, "wc_UnLockMutex failed"); + return BAD_MUTEX_E; + } #else - ESP_LOGV(TAG, ">> xSemaphoreGive 0x%x", (intptr_t)*mutex); + ESP_LOGV(TAG, "Unlocking mutex 0x%x", (intptr_t)*mutex); TaskHandle_t mutexHolder = xSemaphoreGetMutexHolder(*mutex); if (mutexHolder == NULL) { - ESP_LOGW(TAG, "esp_CryptHwMutexUnLock with no lock owner 0x%x", - (intptr_t)*mutex); - ret = ESP_OK; + ESP_LOGW(TAG, "Mutex 0x%x has no owner - already unlocked?", + (intptr_t)*mutex); + return ESP_OK; } - else { - ret = xSemaphoreGive(*mutex); - if (ret == pdTRUE) { - ESP_LOGV(TAG, "Success: give mutex 0x%x", (intptr_t)*mutex); - ret = ESP_OK; - } - else { - ESP_LOGV(TAG, "Failed: give mutex 0x%x", (intptr_t)*mutex); - ret = ESP_FAIL; - } + + if (mutexHolder != xTaskGetCurrentTaskHandle()) { + ESP_LOGE(TAG, "Mutex 0x%x owned by different task", + (intptr_t)*mutex); + return ESP_ERR_INVALID_STATE; } + + ret = xSemaphoreGive(*mutex); + if (ret != pdTRUE) { + ESP_LOGE(TAG, "Failed to give mutex 0x%x", (intptr_t)*mutex); + return ESP_FAIL; + } + + ESP_LOGV(TAG, "Successfully unlocked mutex 0x%x", (intptr_t)*mutex); #endif - return ret; + + return ESP_OK; } #endif /* WOLFSSL_ESP32_CRYPT, etc. */ diff --git a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c index 6e7b625c478..c0140760da0 100644 --- a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c +++ b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c @@ -1333,6 +1333,7 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle, ESP_LOGE(TAG, "Unable to allocate memory for bundle pointers"); _esp_crt_bundle_is_valid = ESP_FAIL; ret = ESP_ERR_NO_MEM; + goto cleanup; } } /* ret == ESP_OK */ @@ -1387,29 +1388,38 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle, ret = ESP_ERR_INVALID_ARG; } - if (_esp_crt_bundle_is_valid == ESP_FAIL) { - if (crts == NULL) { + if (ret == ESP_OK) { + /* Free previous bundle before assigning new one */ + if (s_crt_bundle.crts != NULL) { #ifdef DEBUG_WOLFSSL_MALLOC - ESP_LOGW(TAG, "Free certs after invalid bundle"); + ESP_LOGI(TAG, "Free previous crt bundle"); #endif - free(crts); - crts = NULL; - s_crt_bundle.num_certs = 0; - s_crt_bundle.crts = NULL; + free((void*)s_crt_bundle.crts); } + s_crt_bundle.crts = crts; + s_crt_bundle.num_certs = num_certs; + s_crt_bundle.x509_crt_bundle_wolfssl_len = bundle_size; + _esp_crt_bundle_is_valid = ESP_OK; } - else { - /* The previous crt bundle is only updated when initialization of the - * current crt_bundle is successful */ - /* Free previous crt_bundle */ - if (s_crt_bundle.crts != NULL) { + +cleanup: + if (ret != ESP_OK) { + /* Cleanup on error */ + if (crts != NULL) { #ifdef DEBUG_WOLFSSL_MALLOC - ESP_LOGI(TAG, "Free crts"); + ESP_LOGW(TAG, "Free certs after error"); #endif - free(s_crt_bundle.crts); + free((void*)crts); + crts = NULL; } - s_crt_bundle.num_certs = num_certs; - s_crt_bundle.crts = crts; + s_crt_bundle.crts = NULL; + s_crt_bundle.num_certs = 0; + s_crt_bundle.x509_crt_bundle_wolfssl_len = 0; + _esp_crt_bundle_is_valid = ESP_FAIL; + _cert_bundle_loaded = 0; + _crt_found = 0; + _added_cert = 0; + _need_bundle_cert = 0; } /* Consider using WOLFSSL_ASN_ALLOW_0_SERIAL or WOLFSSL_NO_ASN_STRICT diff --git a/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c b/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c index 5bd7a649d0a..4677d15f01d 100644 --- a/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c +++ b/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c @@ -265,38 +265,72 @@ esp_err_t sdk_var_whereis(const char* v_name, void* v) { intptr_t esp_sdk_stack_pointer(void) { intptr_t sp = 0; + + /* Get stack pointer based on architecture */ #if defined(CONFIG_IDF_TARGET_ARCH_RISCV) - if (CONFIG_IDF_TARGET_ARCH_RISCV == 1) { - __asm volatile("mv %0, sp" : "=r" (sp)); - } + __asm__ volatile("mv %0, sp" : "=r" (sp)); #elif defined(CONFIG_IDF_TARGET_ARCH_XTENSA) - if (CONFIG_IDF_TARGET_ARCH_XTENSA == 1) { - __asm volatile("mov %0, sp" : "=r"(sp)); - } + __asm__ volatile("mov %0, sp" : "=r" (sp)); +#else + #error "Unsupported architecture for stack pointer access" #endif + + /* Initialize starting stack pointer if not set */ if (_starting_stack_pointer == 0) { _starting_stack_pointer = sp; } + + /* Calculate current stack usage */ _stack_used = _starting_stack_pointer - sp; + if (_stack_used < 0) { + ESP_LOGE(TAG, "Stack overflow detected!"); + _stack_used = 0; + } + return sp; } esp_err_t esp_sdk_mem_lib_init(void) { - int ret = ESP_OK; - sdk_init_meminfo(); + esp_err_t ret; + + /* Initialize memory segment tracking */ + ret = sdk_init_meminfo(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize memory info"); + return ret; + } + + /* Initialize stack tracking */ + _starting_stack_pointer = esp_sdk_stack_pointer(); + if (_starting_stack_pointer == 0) { + ESP_LOGE(TAG, "Failed to get initial stack pointer"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "esp_sdk_mem_lib_init Ver %d", ESP_SDK_MEM_LIB_VERSION); - return ret; + return ESP_OK; } void* wc_debug_pvPortMalloc(size_t size, const char* file, int line, const char* fname) { - void* ret = NULL; - ret = pvPortMalloc(size); + if (size == 0) { + ESP_LOGE(TAG, "Invalid allocation size: 0 bytes at %s:%d (%s)", + file, line, fname); + return NULL; + } + + void* ret = pvPortMalloc(size); if (ret == NULL) { - ESP_LOGE("malloc", "%s:%d (%s)", file, line, fname); - ESP_LOGE("malloc", "Failed Allocating memory of size: %d bytes", size); + ESP_LOGE(TAG, "Memory allocation failed: %zu bytes at %s:%d (%s)", + size, file, line, fname); + /* Log stack usage to help debug memory issues */ + ESP_LOGW(TAG, "Current stack usage: %d bytes", _stack_used); + return NULL; } + + /* Track allocation for debugging */ + sdk_var_whereis(fname, ret); return ret; } diff --git a/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c b/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c index db7c95435de..344126a3c52 100644 --- a/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c +++ b/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c @@ -324,14 +324,17 @@ static EventGroupHandle_t s_wifi_event_group; static int s_retry_num = 0; -ip_event_got_ip_t* event; - static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base == NULL || event_data == NULL) { + ESP_LOGE(TAG, "Invalid event parameters"); + return; + } + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { esp_wifi_connect(); } @@ -343,63 +346,109 @@ static void event_handler(void* arg, ESP_LOGI(TAG, "retry to connect to the AP"); } else { - xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + if (s_wifi_event_group != NULL) { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } } ESP_LOGI(TAG, "connect to the AP fail"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - event = (ip_event_got_ip_t*) event_data; - /* wifi_show_ip(); */ - s_retry_num = 0; - xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + ip_event_got_ip_t* ip_event = (ip_event_got_ip_t*)event_data; + if (ip_event != NULL) { + s_retry_num = 0; + if (s_wifi_event_group != NULL) { + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } + } } } esp_err_t wc_wifi_init_sta(void) { - esp_err_t ret = ESP_OK; + esp_err_t ret; + esp_event_handler_instance_t instance_any_id = NULL; + esp_event_handler_instance_t instance_got_ip = NULL; s_wifi_event_group = xEventGroupCreate(); + if (s_wifi_event_group == NULL) { + ESP_LOGE(TAG, "Failed to create event group"); + return ESP_FAIL; + } - ESP_ERROR_CHECK(esp_netif_init()); + ret = esp_netif_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize netif"); + vEventGroupDelete(s_wifi_event_group); + return ret; + } + + ret = esp_event_loop_create_default(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create event loop"); + esp_netif_deinit(); + vEventGroupDelete(s_wifi_event_group); + return ret; + } - ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ret = esp_wifi_init(&cfg); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to init wifi"); + esp_netif_deinit(); + vEventGroupDelete(s_wifi_event_group); + return ret; + } - esp_event_handler_instance_t instance_any_id; - esp_event_handler_instance_t instance_got_ip; - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, - ESP_EVENT_ANY_ID, - &event_handler, - NULL, - &instance_any_id)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, - IP_EVENT_STA_GOT_IP, - &event_handler, - NULL, - &instance_got_ip)); + ret = esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to register WIFI event handler"); + esp_wifi_deinit(); + esp_netif_deinit(); + vEventGroupDelete(s_wifi_event_group); + return ret; + } - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_ESP_WIFI_SSID, - .password = EXAMPLE_ESP_WIFI_PASS, - /* Authmode threshold resets to WPA2 as default if password matches - * WPA2 standards (password len => 8). If you want to connect the - * device to deprecated WEP/WPA networks, Please set the threshold - * value WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with - * length and format matching to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK - * standards. */ - .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, - #ifdef HAS_WPA3_FEATURES - .sae_pwe_h2e = WPA3_SAE_PWE_BOTH, - #endif - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ret = esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to register IP event handler"); + esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id); + esp_wifi_deinit(); + esp_netif_deinit(); + vEventGroupDelete(s_wifi_event_group); + return ret; + } + + wifi_config_t wifi_config; + memset(&wifi_config, 0, sizeof(wifi_config_t)); + memcpy(wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID, + sizeof(EXAMPLE_ESP_WIFI_SSID)); + memcpy(wifi_config.sta.password, EXAMPLE_ESP_WIFI_PASS, + sizeof(EXAMPLE_ESP_WIFI_PASS)); + wifi_config.sta.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD; +#ifdef HAS_WPA3_FEATURES + wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH; +#endif + ret = esp_wifi_set_mode(WIFI_MODE_STA); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set WiFi mode"); + goto cleanup; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set WiFi config"); + goto cleanup; + } #ifdef CONFIG_EXAMPLE_WIFI_SSID if (XSTRCMP(CONFIG_EXAMPLE_WIFI_SSID, "myssid") == 0) { @@ -411,7 +460,11 @@ esp_err_t wc_wifi_init_sta(void) ESP_LOGW(TAG, "WARNING: CONFIG_EXAMPLE_WIFI_SSID not defined."); #endif - ESP_ERROR_CHECK(esp_wifi_start() ); + ret = esp_wifi_start(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to start WiFi"); + goto cleanup; + } ESP_LOGI(TAG, "wifi_init_sta finished."); @@ -454,6 +507,24 @@ esp_err_t wc_wifi_init_sta(void) ret = -2; } #endif + +cleanup: + if (instance_got_ip != NULL) { + esp_event_handler_instance_unregister(IP_EVENT, + IP_EVENT_STA_GOT_IP, + instance_got_ip); + } + if (instance_any_id != NULL) { + esp_event_handler_instance_unregister(WIFI_EVENT, + ESP_EVENT_ANY_ID, + instance_any_id); + } + esp_wifi_deinit(); + esp_netif_deinit(); + if (s_wifi_event_group != NULL) { + vEventGroupDelete(s_wifi_event_group); + s_wifi_event_group = NULL; + } return ret; } diff --git a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index a74d796f173..01fb4540a01 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -33,6 +33,19 @@ #error "WOLFSSL_USER_SETTINGS must be defined for Espressif targets" #endif +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declarations */ +struct wolfSSL_Mutex; +struct Aes; +struct wc_Sha; +struct wc_Sha256; +struct wc_Sha512; + +/* Function declarations */ + #include "sdkconfig.h" /* ensure ESP-IDF settings are available everywhere */ /* wolfSSL */ @@ -658,65 +671,32 @@ enum { ****************************************************************************** */ -#ifdef __cplusplus -extern "C" -{ -#endif - /* ****************************************************************************** -** Some common esp utilities +** Function Declarations ****************************************************************************** */ - WOLFSSL_LOCAL int esp_ShowExtendedSystemInfo(void); - - WOLFSSL_LOCAL esp_err_t esp_DisableWatchdog(void); - - WOLFSSL_LOCAL esp_err_t esp_EnableWatchdog(void); - - /* Compare MATH_INT_T A to MATH_INT_T B - * During debug, the strings name_A and name_B can help - * identify variable name. */ - WOLFSSL_LOCAL int esp_mp_cmp(char* name_A, MATH_INT_T* A, - char* name_B, MATH_INT_T* B); - - /* Show MATH_INT_T value attributes. */ - WOLFSSL_LOCAL int esp_show_mp_attributes(char* c, MATH_INT_T* X); +/* System utilities */ +WOLFSSL_LOCAL int esp_ShowExtendedSystemInfo(void); +WOLFSSL_LOCAL esp_err_t esp_DisableWatchdog(void); +WOLFSSL_LOCAL esp_err_t esp_EnableWatchdog(void); - /* Show MATH_INT_T value. - * - * Calls esp_show_mp_attributes(). - * - * During debug, the string name_A can help - * identify variable name. */ - WOLFSSL_LOCAL int esp_show_mp(char* name_X, MATH_INT_T* X); - - /* To use a Mutex, it must first be initialized. */ - WOLFSSL_LOCAL int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex); - - /* Take the mutex to indicate the HW is in use. Wait up to [block_time]. - * When the HW in use the mutex will be locked. */ - WOLFSSL_LOCAL int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, - TickType_t block_time); - - /* Release the mutex to indicate the HW is no longer in use. */ - WOLFSSL_LOCAL int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex); - - /* Validation active check. When active, we'll fall back to SW. */ - WOLFSSL_LOCAL int esp_hw_validation_active(void); +/* Math operations */ +WOLFSSL_LOCAL int esp_mp_cmp(char* name_A, MATH_INT_T* A, char* name_B, MATH_INT_T* B); +WOLFSSL_LOCAL int esp_show_mp_attributes(char* c, MATH_INT_T* X); +WOLFSSL_LOCAL int esp_show_mp(char* name_X, MATH_INT_T* X); -/* -******************************************************************************* -** AES features: -******************************************************************************* -*/ +/* Mutex operations */ +WOLFSSL_LOCAL int esp_CryptHwMutexInit(struct wolfSSL_Mutex* mutex); +WOLFSSL_LOCAL int esp_CryptHwMutexLock(struct wolfSSL_Mutex* mutex, TickType_t block_time); +WOLFSSL_LOCAL int esp_CryptHwMutexUnLock(struct wolfSSL_Mutex* mutex); +WOLFSSL_LOCAL int esp_hw_validation_active(void); #ifndef NO_AES - /* wolfSSL does not use Espressif rom/aes.h */ - struct Aes; /* see wolcrypt/aes.h */ +struct Aes; /* see wolcrypt/aes.h */ - typedef enum tagES32_AES_PROCESS +typedef enum tagES32_AES_PROCESS { ESP32_AES_LOCKHW = 1, ESP32_AES_UPDATEKEY_ENCRYPT = 2, @@ -730,20 +710,10 @@ extern "C" WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLenValue(int keylen); WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLen(struct Aes* aes); - WOLFSSL_LOCAL int wc_esp32AesCbcEncrypt(struct Aes* aes, - byte* out, - const byte* in, - word32 sz); - WOLFSSL_LOCAL int wc_esp32AesCbcDecrypt(struct Aes* aes, - byte* out, - const byte* in, - word32 sz); - WOLFSSL_LOCAL int wc_esp32AesEncrypt( struct Aes* aes, - const byte* in, - byte* out); - WOLFSSL_LOCAL int wc_esp32AesDecrypt( struct Aes* aes, - const byte* in, - byte* out); + WOLFSSL_LOCAL int wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); + WOLFSSL_LOCAL int wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); + WOLFSSL_LOCAL int wc_esp32AesEncrypt(struct Aes* aes, const byte* in, byte* out); + WOLFSSL_LOCAL int wc_esp32AesDecrypt(struct Aes* aes, const byte* in, byte* out); #endif /* ! NO_AES */ #ifdef WOLFSSL_ESP32_CRYPT_DEBUG @@ -753,11 +723,7 @@ extern "C" #endif /* WOLFSSL_ESP32_CRYPT_DEBUG */ -/* -******************************************************************************* -** Cryptographic hash algorithms (e.g. SHA[x]): -******************************************************************************* -*/ +/* Cryptographic hash algorithms (e.g. SHA[x]) */ #if !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \ (!defined(NO_SHA) || !defined(NO_SHA256) || \ @@ -914,12 +880,6 @@ extern "C" #endif /* NO_SHA && etc */ -/* -******************************************************************************* -** RSA Big Math -******************************************************************************* -*/ - #if !defined(NO_RSA) || defined(HAVE_ECC) #if !defined(ESP_RSA_TIMEOUT_CNT) @@ -927,20 +887,8 @@ extern "C" #endif #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD - /* - * The parameter names in the Espressif implementation are arbitrary. - * - * The wolfSSL names come from DH: Y=G^x mod M (see wolfcrypt/tfm.h) - * - * G=base, X is the private exponent, Y is the public value w - **/ - /* Z = (X ^ Y) mod M : Espressif generic notation */ - /* Y = (G ^ X) mod P : wolfSSL DH reference notation */ - WOLFSSL_LOCAL int esp_mp_exptmod(MATH_INT_T* X, /* G */ - MATH_INT_T* Y, /* X */ - MATH_INT_T* M, /* P */ - MATH_INT_T* Z); /* Y */ + WOLFSSL_LOCAL int esp_mp_exptmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z); /* HW_MATH_ENABLED is typically used in wolfcrypt tests */ #undef HW_MATH_ENABLED @@ -948,21 +896,14 @@ extern "C" #endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */ #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL - /* Z = X * Y */ - WOLFSSL_LOCAL int esp_mp_mul(MATH_INT_T* X, - MATH_INT_T* Y, - MATH_INT_T* Z); + WOLFSSL_LOCAL int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z); /* HW_MATH_ENABLED is typically used in wolfcrypt tests */ #undef HW_MATH_ENABLED #define HW_MATH_ENABLED #endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */ #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD - /* Z = X * Y (mod M) */ - WOLFSSL_LOCAL int esp_mp_mulmod(MATH_INT_T* X, - MATH_INT_T* Y, - MATH_INT_T* M, - MATH_INT_T* Z); + WOLFSSL_LOCAL int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z); /* HW_MATH_ENABLED is typically used in wolfcrypt tests */ #undef HW_MATH_ENABLED #define HW_MATH_ENABLED @@ -971,25 +912,11 @@ extern "C" #endif /* !NO_RSA || HAVE_ECC*/ -/* Optionally enable some metrics to count interesting usage */ -/* -******************************************************************************* -** Usage metrics -******************************************************************************* -*/ #ifdef WOLFSSL_HW_METRICS #define WOLFSSL_HAS_METRICS - - /* Allow sha256 code to keep track of SW fallback during active HW */ WOLFSSL_LOCAL int esp_sw_sha256_count_add(void); - - /* show MP HW Metrics*/ WOLFSSL_LOCAL int esp_hw_show_mp_metrics(void); - - /* show SHA HW Metrics*/ WOLFSSL_LOCAL int esp_hw_show_sha_metrics(void); - - /* show all HW Metrics*/ WOLFSSL_LOCAL int esp_hw_show_metrics(void); #endif @@ -1000,12 +927,7 @@ WOLFSSL_LOCAL int esp_sha_stack_check(WC_ESP32SHA* sha); #endif /* WOLFSSL_STACK_CHECK */ -/* - * Errata Mitigation. See - * esp32_errata_en.pdf - * esp32-c3_errata_en.pdf - * esp32-s3_errata_en.pdf - */ +/* Errata Mitigation */ #define ESP_MP_HW_LOCK_MAX_DELAY ( TickType_t ) 0xffUL #if defined(CONFIG_IDF_TARGET_ESP32) && !defined(ESP_NO_ERRATA_MITIGATION) @@ -1104,6 +1026,10 @@ WOLFSSL_LOCAL int esp_sha_stack_check(WC_ESP32SHA* sha); #warning "CONFIG_ESP_MAIN_TASK_STACK_SIZE not defined!" #endif +#ifdef __cplusplus +} +#endif + #endif /* WOLFSSL_ESPIDF (entire contents excluded when not Espressif ESP-IDF) */ #endif /* __ESP32_CRYPT_H__ */