diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 11c6b5d4b2..266a29a2a2 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -421,6 +421,7 @@ NO_TKERNEL_MEM_POOL NO_TLSX_PSKKEM_PLAIN_ANNOUNCE NO_VERIFY_OID NO_WC_SSIZE_TYPE +NO_WOLFCRYPT_WARMUP NO_WOLFSSL_ALLOC_ALIGN NO_WOLFSSL_AUTOSAR_CRYIF NO_WOLFSSL_AUTOSAR_CRYPTO diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c index 407506ab74..9d4c9fc1a0 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c @@ -20,17 +20,19 @@ */ /* ESP-IDF */ -#include #include "sdkconfig.h" +#include /* wolfSSL */ -/* Always include wolfcrypt/settings.h before any other wolfSSL file. */ -/* Reminder: settings.h pulls in user_settings.h; don't include it here. */ +/* The wolfSSL user_settings.h is automatically included by settings.h file. + * Never explicitly include wolfSSL user_settings.h in any source file. + * The settings.h should also be listed above wolfssl library include files. */ #if defined(WOLFSSL_USER_SETTINGS) #include #if defined(WOLFSSL_ESPIDF) #include #include + #include #include #include #include @@ -187,7 +189,16 @@ void app_main(void) ESP_LOGI(TAG, "--------------------------------------------------------"); ESP_LOGI(TAG, "--------------------------------------------------------"); ESP_LOGI(TAG, "Stack Start: 0x%x", stack_start); - +#ifdef HAVE_WOLFCRYPT_WARMUP + /* Unless disabled, we'll try to allocate known, long-term heap items early + * in an attempt to avoid later allocations that may cause fragmentation. */ + ESP_ERROR_CHECK(esp_sdk_wolfssl_warmup()); +#endif +#ifdef DEBUG_WOLFSSL + /* Turn debugging on and off as needed: */ + wolfSSL_Debugging_ON(); + wolfSSL_Debugging_OFF(); +#endif #ifdef WOLFSSL_ESP_NO_WATCHDOG ESP_LOGW(TAG, "Found WOLFSSL_ESP_NO_WATCHDOG, disabling..."); esp_DisableWatchdog(); diff --git a/wolfcrypt/src/port/Espressif/esp32_util.c b/wolfcrypt/src/port/Espressif/esp32_util.c index c7f44b1201..d28b5533ba 100644 --- a/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/wolfcrypt/src/port/Espressif/esp32_util.c @@ -50,6 +50,12 @@ #include #include +#ifndef NO_WOLFCRYPT_WARMUP + #define HAVE_WOLFCRYPT_WARMUP + #if !defined(NO_AES) && defined(HAVE_AESGCM) + #include + #endif +#endif /* ** Version / Platform info. ** @@ -365,6 +371,113 @@ static int ShowExtendedSystemInfo_platform_espressif(void) ******************************************************************************* */ +/* +** All platforms: Warmup wolfssl +*/ +esp_err_t esp_sdk_wolfssl_warmup(void) +{ + esp_err_t ret = ESP_OK; + int ret_i = 0; /* intermediate wolfssl results*/ +#ifdef NO_WOLFCRYPT_WARMUP + ESP_LOGW(TAG, "esp_sdk_wolfssl_warmup called with NO_WOLFCRYPT_WARMUP"); +#else + /* Even though some [name]_NO_MALLOC may defined, there's always the host + * freeRTOS heap. So here, we'll initialize things early on to attempt + * having the heap allocate long term items near the edge of free memory, + * rather than in the middle. */ + WC_RNG rng; + int rng_inited = 0; + unsigned char dummy; +#if !defined(NO_AES) && defined(HAVE_AESGCM) + Aes aes; + unsigned char key16[WC_AES_BLOCK_SIZE]; + unsigned char out[WC_AES_BLOCK_SIZE]; + unsigned char in[WC_AES_BLOCK_SIZE]; + unsigned char iv[WC_AES_BLOCK_SIZE]; + int devId; + int aes_inited = 0; +#endif /* NO_AES && HAVE_AESGCM declarations */ + +#if defined(DEBUG_WOLFSSL_MALLOC_VERBOSE) + ESP_LOGI(TAG, "Warming up RNG"); +#endif + + ret_i = wc_InitRng(&rng); + if (ret_i == 0) { + rng_inited = 1; + /* forces Hash_DRBG/SHA */ + ret_i = wc_RNG_GenerateBlock(&rng, &dummy, sizeof(dummy)); + if (ret_i != 0) { + ESP_LOGE(TAG, "esp_sdk_wolfssl_warmup wc_RNG_GenerateBlock failed"); + } + } + if (ret_i != 0) { + ret = ESP_FAIL; + ESP_LOGE(TAG, "esp_sdk_wolfssl_warmup RNG warmup failed"); + } + if (rng_inited == 1) { + ret_i = wc_FreeRng(&rng); + if (ret_i != 0) { + ret = ESP_FAIL; + ESP_LOGE(TAG, "esp_sdk_wolfssl_warmup wc_FreeRng failed"); + } + } + +#if !defined(NO_AES) && defined(HAVE_AESGCM) +#if defined(DEBUG_WOLFSSL_MALLOC_VERBOSE) + ESP_LOGI(TAG, "Warming up AES"); +#endif + XMEMSET(key16, 0, (word32)sizeof(key16)); + XMEMSET(iv, 0, (word32)sizeof(iv)); + XMEMSET(in, 0, (word32)sizeof(in)); +#ifdef INVALID_DEVID + devId = INVALID_DEVID; /* software by default */ +#else + devId = 0; +#endif + + ret_i = wc_AesInit(&aes, NULL, devId); + if (ret_i == 0) { + aes_inited = 1; + /* Set an ECB key (no IV). This avoids pulling in GCM/GHASH. */ + ret_i = wc_AesSetKey(&aes, key16, (word32)sizeof(key16), NULL, + AES_ENCRYPTION); + } + if (ret_i == 0) { +#ifdef WOLFSSL_AES_DIRECT + /* Single direct block encrypt to exercise the core/driver. */ + ret_i = wc_AesEncryptDirect(&aes, out, in); +#elif !defined(NO_AES_CBC) + /* One-block CBC (tiny; no padding; does not pull GCM). */ + ret_i = wc_AesSetIV(&aes, iv); + if (ret_i == 0) { + ret_i = wc_AesCbcEncrypt(&aes, out, in, (word32)sizeof(in)); + } +#elif defined(WOLFSSL_AES_COUNTER) + /* As another lightweight option, CTR one-block. */ + ret_i = wc_AesSetIV(&aes, iv); + if (ret_i == 0) { + ret_i = wc_AesCtrEncrypt(&aes, out, in, (word32)sizeof(in)); + } +#else + /* No small mode available; setting key already did most of the warmup. */ + ret_i = 0; +#endif /* WOLFSSL_AES_DIRECT, NO_AES_CBC, HAVE_AES_CTR, etc*/ + } + if (ret_i != 0) { + ret = ESP_FAIL; + ESP_LOGE(TAG, "AES warmup failed during esp_sdk_wolfssl_warmup"); + } + if (aes_inited == 1) { + wc_AesFree(&aes); + } + +#endif /* !NO_AES && HAVE_AESGCM */ +#endif /* !NO_WOLFCRYPT_WARMUP */ + + return ret; +} + /* ** All platforms: git details */ diff --git a/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h b/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h index 977a959021..98e04e168a 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h @@ -142,6 +142,9 @@ extern "C" { #endif +#define HAVE_WOLFCRYPT_WARMUP +WOLFSSL_LOCAL esp_err_t esp_sdk_wolfssl_warmup(void); + WOLFSSL_LOCAL esp_err_t esp_sdk_time_mem_init(void); WOLFSSL_LOCAL esp_err_t sdk_var_whereis(const char* v_name, void* v);