From 107c96dd9c096e2d39cf574d5188a46510484138 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 21 Dec 2022 17:25:46 +1300 Subject: [PATCH 1/6] Fixes to work with quoted command line path. E.g., paths that include spaces. Avoid confusing file/directory prompt for default_config_h file that doesn't have an extension. --- IDE/Espressif/ESP-IDF/setup_win.bat | 117 +++++++++++++++------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/IDE/Espressif/ESP-IDF/setup_win.bat b/IDE/Espressif/ESP-IDF/setup_win.bat index 2e279ad947..492155ddfa 100644 --- a/IDE/Espressif/ESP-IDF/setup_win.bat +++ b/IDE/Espressif/ESP-IDF/setup_win.bat @@ -28,15 +28,19 @@ if NOT EXIST "user_settings.h" ( goto :ERR ) +:: Get argument 1 sans quotes +set Arg1=%~1 + :: see if there was a parameter passed for a specific EDP-IDF directory :: this may be different than the standard ESP-IDF environment (e.g. VisualGDB) -if not "%1" == "" ( - if not exist "%1" ( +if not "%Arg1%" == "" ( +echo %Arg1% + if not exist "%Arg1%" ( echo "ERROR: optional directory was specified, but not found: %1" goto :ERR ) - - SET IDF_PATH=%1 + echo "Setting IDF path" + SET IDF_PATH=%Arg1% echo Using specified IDF_PATH: %IDF_PATH% ) @@ -69,14 +73,14 @@ echo Using WOLFSSLEXP_TRG_DIR = %WOLFSSLEXP_TRG_DIR% echo; echo Equivalalent destination path: -dir %WOLFSSL_ESPIDFDIR%\*.xyzzy 2> nul | findstr \ +dir "%WOLFSSL_ESPIDFDIR%\*.xyzzy" 2> nul | findstr \ echo; echo Equivalalent source directory paths: :: show the path of the equivalent %VALUE% (search for files that don't exist, supress error, and look for string with "\") -dir %BASEDIR%\*.xyzzy 2> nul | findstr \ -dir %WOLFSSLLIB_TRG_DIR%\*.xyzzy 2> nul | findstr \ -dir %WOLFSSLEXP_TRG_DIR%\*.xyzzy 2> nul | findstr \ +dir "%BASEDIR%\*.xyzzy" 2> nul | findstr \ +dir "%WOLFSSLLIB_TRG_DIR%\*.xyzzy" 2> nul | findstr \ +dir "%WOLFSSLEXP_TRG_DIR%\*.xyzzy" 2> nul | findstr \ :: set the FileStamp variable to the current date: YYMMYY_HHMMSS :: the simplest method, to use existing TIME ad DATE variables: @@ -92,18 +96,18 @@ if "%TIME:~0,1%" == " " set FileStamp=%DATE:~12,2%%DATE:~7,2%%DATE:~4,2%_0% if NOT "%TIME:~0,1%" == " " set FileStamp=%DATE:~12,2%%DATE:~7,2%%DATE:~4,2%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2% :: Backup existing user settings -if exist %WOLFSSLLIB_TRG_DIR%\include\config.h ( +if exist "%WOLFSSLLIB_TRG_DIR%\include\config.h" ( echo; echo Saving: %WOLFSSLLIB_TRG_DIR%\include\config.h echo to: %SCRIPTDIR%\config_h_%FileStamp%.bak - copy %WOLFSSLLIB_TRG_DIR%\include\config.h %SCRIPTDIR%\config_h_%FileStamp%.bak + copy "%WOLFSSLLIB_TRG_DIR%\include\config.h" "%SCRIPTDIR%\config_h_%FileStamp%.bak" echo; ) -if exist %WOLFSSL_ESPIDFDIR%\user_settings.h ( +if exist "%WOLFSSL_ESPIDFDIR%\user_settings.h" ( echo Saving: %WOLFSSLLIB_TRG_DIR%\include\user_settings.h echo to: %SCRIPTDIR%\user_settings_h_%FileStamp%.bak - copy %WOLFSSLLIB_TRG_DIR%\include\user_settings.h %SCRIPTDIR%\user_settings_h_%FileStamp%.bak + copy "%WOLFSSLLIB_TRG_DIR%\include\user_settings.h" "%SCRIPTDIR%\user_settings_h_%FileStamp%.bak" echo; ) @@ -111,7 +115,7 @@ if exist %WOLFSSL_ESPIDFDIR%\user_settings.h ( ::****************************************************************************************************** :: check if there's already an existing %WOLFSSLLIB_TRG_DIR% and confirm removal ::****************************************************************************************************** -if exist %WOLFSSLLIB_TRG_DIR% ( +if exist "%WOLFSSLLIB_TRG_DIR%" ( echo; echo WARNING: Existing files found in %WOLFSSLLIB_TRG_DIR% echo; @@ -144,11 +148,11 @@ if exist %WOLFSSLLIB_TRG_DIR% ( ::****************************************************************************************************** :: purge existing directory -if exist %WOLFSSLLIB_TRG_DIR% ( +if exist "%WOLFSSLLIB_TRG_DIR%" ( echo; echo Removing %WOLFSSLLIB_TRG_DIR% - rmdir %WOLFSSLLIB_TRG_DIR% /S /Q - if exist %WOLFSSLLIB_TRG_DIR% ( + rmdir "%WOLFSSLLIB_TRG_DIR%" /S /Q + if exist "%WOLFSSLLIB_TRG_DIR%" ( SET COPYERROR=true echo; echo WARNING: Failed to remove %WOLFSSLLIB_TRG_DIR% @@ -166,67 +170,67 @@ if exist %WOLFSSLLIB_TRG_DIR% ( ::****************************************************************************************************** :REFRESH ::****************************************************************************************************** -if not exist %WOLFSSLLIB_TRG_DIR% mkdir %WOLFSSLLIB_TRG_DIR% -if not exist %WOLFSSLLIB_TRG_DIR%\src mkdir %WOLFSSLLIB_TRG_DIR%\src -if not exist %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src mkdir %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src -if not exist %WOLFSSLLIB_TRG_DIR%\wolfssl mkdir %WOLFSSLLIB_TRG_DIR%\wolfssl -if not exist %WOLFSSLLIB_TRG_DIR%\wolfssl\openssl mkdir %WOLFSSLLIB_TRG_DIR%\wolfssl\openssl -if not exist %WOLFSSLLIB_TRG_DIR%\test mkdir %WOLFSSLLIB_TRG_DIR%\test -if not exist %WOLFSSLLIB_TRG_DIR%\include mkdir %WOLFSSLLIB_TRG_DIR%\include +if not exist "%WOLFSSLLIB_TRG_DIR%" mkdir "%WOLFSSLLIB_TRG_DIR%" +if not exist "%WOLFSSLLIB_TRG_DIR%\src" mkdir "%WOLFSSLLIB_TRG_DIR%\src" +if not exist "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\src" mkdir "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\src" +if not exist "%WOLFSSLLIB_TRG_DIR%\wolfssl" mkdir "%WOLFSSLLIB_TRG_DIR%\wolfssl" +if not exist "%WOLFSSLLIB_TRG_DIR%\wolfssl\openssl" mkdir "%WOLFSSLLIB_TRG_DIR%\wolfssl\openssl" +if not exist "%WOLFSSLLIB_TRG_DIR%\test" mkdir "%WOLFSSLLIB_TRG_DIR%\test"" +if not exist "%WOLFSSLLIB_TRG_DIR%\include" mkdir "%WOLFSSLLIB_TRG_DIR%\include" rem copying ... files in src/ into $WOLFSSLLIB_TRG_DIR%/src echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\src\ -xcopy %BASEDIR%\src\*.c %WOLFSSLLIB_TRG_DIR%\src\ /S /E /Q /Y +xcopy "%BASEDIR%\src\*.c" "%WOLFSSLLIB_TRG_DIR%\src\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying src\*.c files to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src -xcopy %BASEDIR%\wolfcrypt\src\*.c %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\src\*.c" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\src" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying src\*.i files to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src -xcopy %BASEDIR%\wolfcrypt\src\*.i %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\src\*.i" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\src" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src\port\ -xcopy %BASEDIR%\wolfcrypt\src\port %WOLFSSLLIB_TRG_DIR%\wolfcrypt\src\port\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\src\port" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\src\port\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\ -xcopy %BASEDIR%\wolfcrypt\test %WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\test" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true :: Copy dummy test_paths.h to handle the case configure hasn't yet executed echo; echo Copying dummy_test_paths.h to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\test_paths.h -echo new config > %WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\test_paths.h +echo new config > "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\test_paths.h" if %errorlevel% NEQ 0 SET COPYERROR=true -xcopy %WOLFSSL_ESPIDFDIR%\dummy_test_paths.h %WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\test_paths.h /S /E /Y +xcopy "%WOLFSSL_ESPIDFDIR%\dummy_test_paths.h" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\test\test_paths.h" /S /E /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\wolfcrypt\benchmark\ -xcopy %BASEDIR%\wolfcrypt\benchmark %WOLFSSLLIB_TRG_DIR%\wolfcrypt\benchmark\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\benchmark" "%WOLFSSLLIB_TRG_DIR%\wolfcrypt\benchmark\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\wolfssl\ -xcopy %BASEDIR%\wolfssl\*.h %WOLFSSLLIB_TRG_DIR%\wolfssl\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfssl\*.h" "%WOLFSSLLIB_TRG_DIR%\wolfssl\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to%WOLFSSLLIB_TRG_DIR%\wolfssl\openssl\ -xcopy %BASEDIR%\wolfssl\openssl\*.h %WOLFSSLLIB_TRG_DIR%\wolfssl\openssl\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfssl\openssl\*.h" "%WOLFSSLLIB_TRG_DIR%\wolfssl\openssl\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true echo; echo Copying files to %WOLFSSLLIB_TRG_DIR%\wolfssl\wolfcrypt\ -xcopy %BASEDIR%\wolfssl\wolfcrypt %WOLFSSLLIB_TRG_DIR%\wolfssl\wolfcrypt\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfssl\wolfcrypt" "%WOLFSSLLIB_TRG_DIR%\wolfssl\wolfcrypt\" /S /E /Q /Y if %errorlevel% NEQ 0 SET COPYERROR=true @@ -236,15 +240,15 @@ if %errorlevel% NEQ 0 SET COPYERROR=true :: user_settings.h (default, may be overwritten by prior file) echo; echo Copying default user_settings.h to %WOLFSSLLIB_TRG_DIR%\include\ -xcopy %WOLFSSL_ESPIDFDIR%\user_settings.h %WOLFSSLLIB_TRG_DIR%\include\ /F +xcopy "%WOLFSSL_ESPIDFDIR%\user_settings.h" "%WOLFSSLLIB_TRG_DIR%\include\" /F if %errorlevel% NEQ 0 SET COPYERROR=true :: echo Creating new config file: %WOLFSSLLIB_TRG_DIR%\include\config.h (default, may be overwritten by prior file) +:: using copy instead of copy to avoid file/directory prompt for files without extension echo new config > %WOLFSSLLIB_TRG_DIR%\include\config.h -xcopy %WOLFSSL_ESPIDFDIR%\dummy_config_h. %WOLFSSLLIB_TRG_DIR%\include\config.h /F /Y +copy "%WOLFSSL_ESPIDFDIR%\dummy_config_h" "%WOLFSSLLIB_TRG_DIR%\include\config.h" /Y if %errorlevel% NEQ 0 SET COPYERROR=true - :: Check if operator wants to keep prior config.h if EXIST config_h_%FileStamp%.bak ( echo; @@ -252,7 +256,7 @@ if EXIST config_h_%FileStamp%.bak ( call; choice /c YN /m "Use your prior config.h " if errorlevel 2 GOTO :NO_CONFIG_RESTORE - xcopy config_h_%FileStamp%.bak %WOLFSSLLIB_TRG_DIR%\include\config.h /Y + xcopy "config_h_%FileStamp%.bak" "%WOLFSSLLIB_TRG_DIR%\include\config.h" /Y if %errorlevel% NEQ 0 SET COPYERROR=true ) else ( @@ -270,7 +274,7 @@ if EXIST user_settings_h_%FileStamp%.bak ( call; choice /c YN /m "User your prior user_settings.h " if errorlevel 2 GOTO :NO_USER_SETTINGS_RESTORE - xcopy user_settings_h_%FileStamp%.bak %WOLFSSLLIB_TRG_DIR%\include\user_settings.h /Y + xcopy user_settings_h_%FileStamp%.bak "%WOLFSSLLIB_TRG_DIR%\include\user_settings.h" /Y if %errorlevel% NEQ 0 SET COPYERROR=true ) else ( @@ -286,63 +290,63 @@ if EXIST user_settings_h_%FileStamp%.bak ( :: unit test app echo; echo Copying unit files to %WOLFSSLLIB_TRG_DIR%\test\ -xcopy %WOLFSSL_ESPIDFDIR%\test %WOLFSSLLIB_TRG_DIR%\test\ /S /E /Q /Y +xcopy "%WOLFSSL_ESPIDFDIR%\test" "%WOLFSSLLIB_TRG_DIR%\test\" /S /E /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR echo; echo Copying CMakeLists.txt to %WOLFSSLLIB_TRG_DIR%\ -xcopy %WOLFSSL_ESPIDFDIR%\libs\CMakeLists.txt %WOLFSSLLIB_TRG_DIR%\ /F +xcopy "%WOLFSSL_ESPIDFDIR%\libs\CMakeLists.txt" "%WOLFSSLLIB_TRG_DIR%\" /F if %errorlevel% NEQ 0 GOTO :COPYERR echo; echo Copying component.mk to %WOLFSSLLIB_TRG_DIR%\ -xcopy %WOLFSSL_ESPIDFDIR%\libs\component.mk %WOLFSSLLIB_TRG_DIR%\ /F +xcopy "%WOLFSSL_ESPIDFDIR%\libs\component.mk" "%WOLFSSLLIB_TRG_DIR%\" /F if %errorlevel% NEQ 0 GOTO :COPYERR :: Benchmark program echo; echo Removing %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\ -rmdir %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\ /S /Q +rmdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\" /S /Q if %errorlevel% NEQ 0 GOTO :COPYERR echo; echo Copying %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\main\ -mkdir %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\main\ +mkdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\main\" -xcopy %BASEDIR%\wolfcrypt\benchmark\benchmark.c %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\main\ /F /Y +xcopy "%BASEDIR%\wolfcrypt\benchmark\benchmark.c" "%WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\main\" /F /Y if %errorlevel% NEQ 0 GOTO :COPYERR -xcopy %WOLFSSL_ESPIDFDIR%\examples\wolfssl_benchmark %WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\ /Q /Y +xcopy "%WOLFSSL_ESPIDFDIR%\examples\wolfssl_benchmark" "%WOLFSSLEXP_TRG_DIR%\wolfssl_benchmark\" /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR :: Crypt Test program echo; echo Copying %WOLFSSLEXP_TRG_DIR%\wolfssl_test\ -rmdir %WOLFSSLEXP_TRG_DIR%\wolfssl_test\ /S /Q -mkdir %WOLFSSLEXP_TRG_DIR%\wolfssl_test\main\ +rmdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_test\" /S /Q +mkdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_test\main\" -xcopy %BASEDIR%\wolfcrypt\test\test.c %WOLFSSLEXP_TRG_DIR%\wolfssl_test\main\ /S /E /Q /Y +xcopy "%BASEDIR%\wolfcrypt\test\test.c" "%WOLFSSLEXP_TRG_DIR%\wolfssl_test\main\" /S /E /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR -xcopy %WOLFSSL_ESPIDFDIR%\examples\wolfssl_test %WOLFSSLEXP_TRG_DIR%\wolfssl_test\ /S /E /Q /Y +xcopy "%WOLFSSL_ESPIDFDIR%\examples\wolfssl_test" "%WOLFSSLEXP_TRG_DIR%\wolfssl_test\" /S /E /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR :: TLS Client program echo; echo Copying %WOLFSSLEXP_TRG_DIR%\wolfssl_client\ -rmdir %WOLFSSLEXP_TRG_DIR%\wolfssl_client\ /S /Q -mkdir %WOLFSSLEXP_TRG_DIR%\wolfssl_client\main\ +rmdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_client\" /S /Q +mkdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_client\main\" -xcopy %WOLFSSL_ESPIDFDIR%\examples\wolfssl_client %WOLFSSLEXP_TRG_DIR%\wolfssl_client\ /S /E /Q /Y +xcopy "%WOLFSSL_ESPIDFDIR%\examples\wolfssl_client" "%WOLFSSLEXP_TRG_DIR%\wolfssl_client\" /S /E /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR :: TLS Server program echo; echo Copying %WOLFSSLEXP_TRG_DIR%\wolfssl_server\ -rmdir %WOLFSSLEXP_TRG_DIR%\wolfssl_server\ /S /Q -mkdir %WOLFSSLEXP_TRG_DIR%\wolfssl_server\main\ +rmdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_server\" /S /Q +mkdir "%WOLFSSLEXP_TRG_DIR%\wolfssl_server\main\" -xcopy %WOLFSSL_ESPIDFDIR%\examples\wolfssl_server %WOLFSSLEXP_TRG_DIR%\wolfssl_server\ /S /E /Q /Y +xcopy "%WOLFSSL_ESPIDFDIR%\examples\wolfssl_server" "%WOLFSSLEXP_TRG_DIR%\wolfssl_server\" /S /E /Q /Y if %errorlevel% NEQ 0 GOTO :COPYERR goto :DONE @@ -369,6 +373,7 @@ goto :ERR ::****************************************************************************************************** :ERR ::****************************************************************************************************** +echo "ERROR" exit /B 1 :: Success From 181d8b85b4b5b4516863cdf3a2b3dba70395de3a Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 21 Dec 2022 17:41:33 +1300 Subject: [PATCH 2/6] Removed unneeded change --- IDE/Espressif/ESP-IDF/setup_win.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDE/Espressif/ESP-IDF/setup_win.bat b/IDE/Espressif/ESP-IDF/setup_win.bat index 492155ddfa..fd0372d127 100644 --- a/IDE/Espressif/ESP-IDF/setup_win.bat +++ b/IDE/Espressif/ESP-IDF/setup_win.bat @@ -245,8 +245,8 @@ if %errorlevel% NEQ 0 SET COPYERROR=true :: echo Creating new config file: %WOLFSSLLIB_TRG_DIR%\include\config.h (default, may be overwritten by prior file) :: using copy instead of copy to avoid file/directory prompt for files without extension -echo new config > %WOLFSSLLIB_TRG_DIR%\include\config.h -copy "%WOLFSSL_ESPIDFDIR%\dummy_config_h" "%WOLFSSLLIB_TRG_DIR%\include\config.h" /Y +echo new config > "%WOLFSSLLIB_TRG_DIR%\include\config.h" +xcopy "%WOLFSSL_ESPIDFDIR%\dummy_config_h" "%WOLFSSLLIB_TRG_DIR%\include\config.h" /F /Y if %errorlevel% NEQ 0 SET COPYERROR=true :: Check if operator wants to keep prior config.h From 56d587d1a004a9c93fed48a05945428776422d66 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 23 Dec 2022 12:14:39 +1300 Subject: [PATCH 3/6] Started implementing support for ESP32s3: * SHA acceleration: added guarded implementation, builds, passes some tests * AES acceleration: added guarded implementation, builds, untested * MP acceleration: added guarded implementation, builds, untested --- wolfcrypt/src/port/Espressif/esp32_aes.c | 56 ++++- wolfcrypt/src/port/Espressif/esp32_mp.c | 257 +++++++++++++++++++++-- wolfcrypt/src/port/Espressif/esp32_sha.c | 120 ++++++++++- 3 files changed, 400 insertions(+), 33 deletions(-) diff --git a/wolfcrypt/src/port/Espressif/esp32_aes.c b/wolfcrypt/src/port/Espressif/esp32_aes.c index 062cd8bad2..66d5830733 100644 --- a/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -56,6 +56,7 @@ static int espaes_CryptHwMutexInit = 0; static int esp_aes_hw_InUse() { int ret = 0; + printf("esp_aes_hw_InUse\n"); ESP_LOGV(TAG, "enter esp_aes_hw_InUse"); @@ -84,6 +85,13 @@ static int esp_aes_hw_InUse() /* Enable AES hardware */ periph_module_enable(PERIPH_AES_MODULE); + +#if CONFIG_IDF_TARGET_ESP32S3 + /* Select working mode. Can be typical or DMA. + * 0 => typical + * 1 => DMA */ + DPORT_REG_WRITE(AES_DMA_ENABLE_REG, 0); +#endif ESP_LOGV(TAG, "leave esp_aes_hw_InUse"); return ret; @@ -133,26 +141,36 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) DPORT_REG_WRITE(AES_KEY_BASE + (i*4), *(((word32*)ctx->key) + i)); } - /* mode - * 0 AES-128 Encryption - * 1 AES-192 Encryption - * 2 AES-256 Encryption - * 4 AES-128 Decryption - * 5 AES-192 Decryption - * 6 AES-256 Decryption + /* + * ESP32: see table 22-1 in ESP32 Technical Reference + * ESP32S3: see table 19-2 in ESP32S3 Technical Reference + * mode Algorithm ESP32 ESP32S3 + * 0 AES-128 Encryption y y + * 1 AES-192 Encryption y n + * 2 AES-256 Encryption y y + * 4 AES-128 Decryption y y + * 5 AES-192 Decryption y n + * 6 AES-256 Decryption y y */ switch(ctx->keylen){ case 24: mode_ += 1; break; case 32: mode_ += 2; break; default: break; } - +#if CONFIG_IDF_TARGET_ESP32S3 + if (mode_ == 1 || mode_ == 5 || mode_ == 7) + { + ESP_LOGE(TAG, " unsupported mode"); + } +#endif DPORT_REG_WRITE(AES_MODE_REG, mode_); ESP_LOGV(TAG, " leave esp_aes_hw_Setkey"); } /* * Process a one block of AES + * in: block of 16 bytes (4 x words32) to process + * out: result of processing input bytes. */ static void esp_aes_bk(const byte* in, byte* out) { @@ -164,7 +182,27 @@ static void esp_aes_bk(const byte* in, byte* out) #endif ESP_LOGV(TAG, "enter esp_aes_bk"); +#if CONFIG_IDF_TARGET_ESP32S3 + // See esp32-s3 technical reference manual §19.4.3 Operation process + // using CPU working mode. The ESP32-S3 also supports a DMA mode. + /* copy text for encrypting/decrypting blocks */ + DPORT_REG_WRITE(AES_TEXT_IN_BASE, inwords[0]); + DPORT_REG_WRITE(AES_TEXT_IN_BASE + 4, inwords[1]); + DPORT_REG_WRITE(AES_TEXT_IN_BASE + 8, inwords[2]); + DPORT_REG_WRITE(AES_TEXT_IN_BASE + 12, inwords[3]); + + /* start engine */ + DPORT_REG_WRITE(AES_TRIGGER_REG, 1); + /* wait until finishing the process */ + while (DPORT_REG_READ(AES_STATE_REG) != 0) + { + // wating for the hardware accelerator to complete operation. + } + + /* read-out blocks */ + esp_dport_access_read_buffer(outwords, AES_TEXT_OUT_BASE, 4); +#else /* copy text for encrypting/decrypting blocks */ DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]); DPORT_REG_WRITE(AES_TEXT_BASE + 4, inwords[1]); @@ -182,6 +220,8 @@ static void esp_aes_bk(const byte* in, byte* out) /* read-out blocks */ esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4); +#endif + ESP_LOGV(TAG, "leave esp_aes_bk"); } diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index a7eb1fdd7b..4e1fa3c3a3 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -70,10 +70,20 @@ static int esp_mp_hw_wait_clean() { word32 timeout = 0; +#if CONFIG_IDF_TARGET_ESP32S3 + + while (!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) + { + /* wait. expected delay 1 to 2 uS */ + } +#else + /* RSA_CLEAN_REG is now called RSA_QUERY_CLEAN_REG. hwcrypto_reg.h maintains + * RSA_CLEAN_REG for backwards compatibility so this block _might_ be not needed. */ while(!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(RSA_CLEAN_REG) != 1) { /* wait. expected delay 1 to 2 uS */ } +#endif if (ESP_TIMEOUT(timeout)) { ESP_LOGE(TAG, "waiting hw ready is timed out."); @@ -131,12 +141,22 @@ static int esp_mp_hw_lock() return MP_NG; } + +#if CONFIG_IDF_TARGET_ESP32S3 + /* Activate teh RSA accelerator. See §20.3 of ESP32-S3 technical manual. + * periph_module_enable doesn't seem to be documented and in private folder + * with v5 release. Maybe it will be deprecated? */ + DPORT_REG_SET_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + + /* clear bit to enable hardware operation; (set to disable) */ + DPORT_REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); +#else /* Enable RSA hardware */ periph_module_enable(PERIPH_RSA_MODULE); - /* clear bit to enable hardware operation; (set to disable) - */ + /* clear bit to enable hardware operation; (set to disable) */ DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); +#endif /* remionder: wait until RSA_CLEAN_REG reads 1 * see esp_mp_hw_wait_clean() @@ -150,13 +170,22 @@ static int esp_mp_hw_lock() */ static void esp_mp_hw_unlock( void ) { +#if CONFIG_IDF_TARGET_ESP32S3 + /* Deactivate teh RSA accelerator. See §20.3 of ESP32-S3 technical manual. + * periph_module_enable doesn't seem to be documented and in private folder + * with v5 release. Maybe it will be deprecated? */ + DPORT_REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); + DPORT_REG_CLR_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + +#else /* set bit to disabled hardware operation; (clear to enable) */ DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); /* Disable RSA hardware */ periph_module_disable(PERIPH_RSA_MODULE); - +#endif + /* unlock */ esp_CryptHwMutexUnLock(&mp_mutex); } @@ -199,7 +228,7 @@ static void process_start(word32 reg) } /* wait until done */ -static int wait_uitil_done(word32 reg) +static int wait_until_done(word32 reg) { word32 timeout = 0; /* wait until done && not timeout */ @@ -208,9 +237,13 @@ static int wait_uitil_done(word32 reg) /* wait */ } +#if CONFIG_IDF_TARGET_ESP32S3 + // ESP32S3 doesn't use interrupt register for completion. +#else /* clear interrupt */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); - +#endif + if (ESP_TIMEOUT(timeout)) { ESP_LOGE(TAG, "rsa operation is timed out."); return MP_NG; @@ -316,7 +349,66 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) ESP_LOGW(TAG, "exceeds max bit length(2048)"); return -2; } + +#if CONFIG_IDF_TARGET_ESP32S3 + /* Steps to perform large number multiplication. Calculates Z = X x Y. The number of + * bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the + * maximum number of bits in the X and Y is 2048. + * See §20.3.3 of ESP32-S3 technical manual + * 1. Lock the hardware so no-one else uses it and wait until it is ready. + * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. + * 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). + * Here N_result_bits is the number of bits in the multiplication result, which + * is 2x the number of bits in the operands. + * 4. Load X, Y operands to memory blocks. Note the Y value must be written to + * offset of 4 x N_bits_Y + * 5. Start the operation by writing 1 to RSA_MULT_START_REG, then wait for it + * to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG). + * 6. Read the result out. + * 7. Release the hardware lock so others can use it. + * x. Clear the interrupt flag, if you used it (we don't). */ + + /* 1. lock hw for use & wait until it is ready. */ + if ((ret = esp_mp_hw_lock()) != MP_OKAY + || (ret = esp_mp_hw_wait_clean()) != MP_OKAY) + { + return ret; + } + + /* 2. Disable completion interrupt singal; we don't use. */ + DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. + + /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ + uint32_t uResultBits = max(Xs, Ys) * 2; + if (uResultBits > ESP_HW_RSAMAX_BIT) + { + ESP_LOGW(TAG, "result exceeds max bit length"); + return -2; + } + DPORT_REG_WRITE(RSA_LENGTH_REG, (uResultBits / 32) - 1); + /* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */ + esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz << 2), Y, Ys, hwWords_sz); + + /* 5. Start operation and wait until it completes. */ + DPORT_REG_WRITE(RSA_MULT_START_REG, 1); + ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); + if (MP_OKAY != ret) + { + return ret; + } + + /* 6. read the result form MEM_Z */ + esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs)); + + /* 7. clear and release hw */ + esp_mp_hw_unlock(); + + Z->sign = (Z->used > 0) ? neg : MP_ZPOS; + + return ret; +#else /*Steps to use hw in the following order: * 1. wait until clean hw engine * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG @@ -356,7 +448,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) process_start(RSA_MULT_START_REG); /* step.4,5 wait until done */ - ret = wait_uitil_done(RSA_INTERRUPT_REG); + ret = wait_until_done(RSA_INTERRUPT_REG); if (ret != MP_OKAY) { ESP_LOGE(TAG, "wait_uitil_done failed."); return ret; @@ -370,6 +462,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) Z->sign = (Z->used > 0) ? neg : MP_ZPOS; return ret; +#endif } /* Z = X * Y (mod M) */ @@ -431,6 +524,74 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) mp_clear(&r_inv); return -1; } + +#if CONFIG_IDF_TARGET_ESP32S3 + /* Steps to perform large number modular multiplication. Calculates Z = (X x Y) modulo M. + * The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the + * maximum number of bits in the X and Y is 2048. + * See §20.3.3 of ESP32-S3 technical manual + * 1. Wait until the hardware is ready. + * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. + * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). + * Here N_bits is the maximum number of bits in X, Y and M. + * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG). + * 5. Load X, Y, M, r' operands to memory blocks. + * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG, then wait for it + * to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG). + * 7. Read the result out. + * 8. Release the hardware lock so others can use it. + * x. Clear the interrupt flag, if you used it (we don't). */ + + /* 1. Wait until hardware is ready. */ + if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) + { + return ret; + } + + /* 2. Disable completion interrupt singal; we don't use. */ + DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. + + /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ + uint32_t uOperandBits = max(max(Xs, Ys), Ms); + if (uOperandBits > ESP_HW_MULTI_RSAMAX_BITS) + { + ESP_LOGW(TAG, "result exceeds max bit length"); + return -2; + } + DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + + /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ + DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + + /* 5. Load X, Y, M, r' operands. */ + esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); + + /* 6. Start operation and wait until it completes. */ + DPORT_REG_WRITE(RSA_MOD_MULT_START_REG, 1); + ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); + if (MP_OKAY != ret) + { + return ret; + } + + /* 7. read the result form MEM_Z */ + esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords); + + /* 8. clear and release hw */ + esp_mp_hw_unlock(); + + // todo: implement work-arounds for known issues with ESP32 version (see below) if needed. + + mp_copy(&tmpZ, Z); + mp_clear(&tmpZ); + mp_clear(&r_inv); + + return ret; +#else + /*Steps to use hw in the following order: * 1. wait until clean hw engine * 2. Write(N/512bits - 1) to MULT_MODE_REG @@ -470,7 +631,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) process_start(RSA_MULT_START_REG); /* step.5,6 wait until done */ - wait_uitil_done(RSA_INTERRUPT_REG); + wait_until_done(RSA_INTERRUPT_REG); /* step.7 Y to MEM_X */ esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, Y, Ys, hwWords_sz); @@ -478,7 +639,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) process_start(RSA_MULT_START_REG); /* step.9,11 wait until done */ - wait_uitil_done(RSA_INTERRUPT_REG); + wait_until_done(RSA_INTERRUPT_REG); /* step.12 read the result from MEM_Z */ esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords); @@ -502,23 +663,25 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) mp_clear(&r_inv); return ret; +#endif } /* Large Number Modular Exponentiation * * Z = X^Y mod M * - * See Chapter 24: - * https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf - * + * See: + * ESP32, Chapter 24, https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf + * ESP32s3, section 20.3.1, https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf * The operation is based on Montgomery multiplication. Aside from the * arguments X, Y , and M, two additional ones are needed —r and M′ .* These arguments are calculated in advance by software. .* .* The RSA Accelerator supports operand lengths of N ∈ {512, 1024, 1536, 2048, -.* 2560, 3072, 3584, 4096} bits. The bit length of arguments Z, X, Y , M, -.* and r can be any one from the N set, but all numbers in a calculation must -.* be of the same length. The bit length of M′ is always 32. +.* 2560, 3072, 3584, 4096} bits on the ESP32 and N ∈ [32, 4096] bits on the ESP32s3. +.* The bit length of arguments Z, X, Y , M, and r can be any one from the N set, +.* but all numbers in a calculation must be of the same length. +.* The bit length of M′ is always 32. .* .* Note some DH references may use: Y = (G ^ X) mod P */ @@ -568,6 +731,69 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) return -1; } +#if CONFIG_IDF_TARGET_ESP32S3 + /* Steps to perform large number modular exponentiation. Calculates Z = (X ^ Y) modulo M. + * The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the + * maximum number of bits in the X and Y is 2048. + * See §20.3.3 of ESP32-S3 technical manual + * 1. Wait until the hardware is ready. + * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. + * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). + * Here N_bits is the maximum number of bits in X, Y and M. + * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG). + * 5. Load X, Y, M, r' operands to memory blocks. + * 6. Start the operation by writing 1 to RSA_MODEXP_START_REG, then wait for it + * to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG). + * 7. Read the result out. + * 8. Release the hardware lock so others can use it. + * x. Clear the interrupt flag, if you used it (we don't). */ + + /* 1. Wait until hardware is ready. */ + if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) + { + return ret; + } + + /* 2. Disable completion interrupt singal; we don't use. */ + DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. + + /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ + uint32_t uOperandBits = max(max(Xs, Ys), Ms); + if (uOperandBits > ESP_HW_MULTI_RSAMAX_BITS) + { + ESP_LOGW(TAG, "result exceeds max bit length"); + return -2; + } + DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + + /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ + DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + + /* 5. Load X, Y, M, r' operands. */ + esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); + + /* 6. Start operation and wait until it completes. */ + DPORT_REG_WRITE(RSA_MODEXP_START_REG, 1); + ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); + if (MP_OKAY != ret) + { + return ret; + } + + /* 7. read the result form MEM_Z */ + esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms)); + + /* 8. clear and release hw */ + esp_mp_hw_unlock(); + + mp_clear(&r_inv); + + return ret; +#else + /*Steps to use hw in the following order: * 1. Write(N/512bits - 1) to MODEXP_MODE_REG * 2. Write X, Y, M and r_inv to memory blocks @@ -600,7 +826,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) process_start(RSA_START_MODEXP_REG); /* step.5 wait until done */ - wait_uitil_done(RSA_INTERRUPT_REG); + wait_until_done(RSA_INTERRUPT_REG); /* step.6 read a result form memory */ esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms)); /* step.7 clear and release hw */ @@ -609,6 +835,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) mp_clear(&r_inv); return ret; +#endif } #endif /* !NO_RSA || HAVE_ECC */ diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 2910291b18..7574483f89 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -37,9 +37,11 @@ #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) -/* TODO this may be chip type dependent: add support for others */ -#include /* ESP32-WROOM */ - +/* Espressif hardware abstraction layers: + * https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/hardware-abstraction.html + * Espressif note their HAL API is experimental and may change between minor releases. */ +#include /* peripheral clock/reset control */ + #include #include #include @@ -123,12 +125,19 @@ static word32 wc_esp_sha_digest_size(enum SHA_TYPE type) */ static void wc_esp_wait_until_idle() { +#if CONFIG_IDF_TARGET_ESP32S3 + while (REG_READ(SHA_BUSY_REG)) + { + /* wait patiently for the SHA to be available. */ + } +#else while((DPORT_REG_READ(SHA_1_BUSY_REG) != 0) || (DPORT_REG_READ(SHA_256_BUSY_REG) != 0) || (DPORT_REG_READ(SHA_384_BUSY_REG) != 0) || (DPORT_REG_READ(SHA_512_BUSY_REG) != 0)) { /* do nothing while waiting. */ } +#endif } /* @@ -149,18 +158,25 @@ int esp_unroll_sha_module_enable(WC_ESP32SHA* ctx) /* if we end up here, there was a prior unexpected fail and * we need to unroll enables */ int ret = 0; /* assume success unless proven otherwise */ - uint32_t this_sha_mask; /* this is the bit-mask for our SHA CLK_EN_REG */ int actual_unroll_count = 0; int max_unroll_count = 1000; /* never get stuck in a hardware wait loop */ - this_sha_mask = periph_ll_get_clk_en_mask(PERIPH_SHA_MODULE); - /* unwind prior calls to THIS ctx. decrement ref_counts[periph] */ /* only when ref_counts[periph] == 0 does something actually happen */ +#if CONFIG_IDF_TARGET_ESP32S3 /* once the value we read is a 0 in the DPORT_PERI_CLK_EN_REG bit * then we have fully unrolled the enables via ref_counts[periph]==0 */ - while ((this_sha_mask & *(uint32_t*)DPORT_PERI_CLK_EN_REG) != 0) { + while (periph_ll_periph_enabled(PERIPH_SHA_MODULE)) +#else + /* this is the bit-mask for our SHA CLK_EN_REG */ + uint32_t this_sha_mask = periph_ll_get_clk_en_mask(PERIPH_SHA_MODULE); + + /* once the value we read is a 0 in the DPORT_PERI_CLK_EN_REG bit + * then we have fully unrolled the enables via ref_counts[periph]==0 */ + while ((this_sha_mask & *(uint32_t*)DPORT_PERI_CLK_EN_REG) != 0) +#endif + { periph_module_disable(PERIPH_SHA_MODULE); actual_unroll_count++; ESP_LOGI(TAG, "unroll not yet successful. try #%d", @@ -193,8 +209,10 @@ int esp_unroll_sha_module_enable(WC_ESP32SHA* ctx) } /* -* lock hw engine. +* lock hw engine, or fallback to software calculations if the hardware is busy. * this should be called before using engine. +* Note: we are assuming all users of the SHA engine will access it through +* the Wolf libraries. */ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx) { @@ -346,6 +364,59 @@ static int esp_sha_start_process(WC_ESP32SHA* sha) ESP_LOGV(TAG, " enter esp_sha_start_process"); +#if CONFIG_IDF_TARGET_ESP32S3 + + /* Translate from Wolf sha type to hardware algorithm. */ + uint8_t uHardwareAlgorithm = 0; + switch (sha->sha_type) + { + case SHA1: + uHardwareAlgorithm = 0; + break; + case SHA2_256: + uHardwareAlgorithm = 2; + break; +#if defined(WOLFSSL_SHA384) + case SHA2_384: + uHardwareAlgorithm = 3; + break; +#endif +#if defined(WOLFSSL_SHA512) + case SHA2_512: + uHardwareAlgorithm = 4; + break; +#endif + default: + /* Unsupported sha mode. */ + sha->mode = ESP32_SHA_FAIL_NEED_UNROLL; + return -1; + } + + REG_WRITE(SHA_MODE_REG, uHardwareAlgorithm); + + if (sha->isfirstblock) + { + REG_WRITE(SHA_START_REG, 1); + sha->isfirstblock = 0; + + ESP_LOGV(TAG, " set sha->isfirstblock = 0"); + +#if defined(DEBUG_WOLFSSL) + this_block_num = 1; /* one-based counter, just for debug info */ +#endif + + } + else + { + REG_WRITE(SHA_CONTINUE_REG, 1); + +#if defined(DEBUG_WOLFSSL) + this_block_num++; /* one-based counter */ + ESP_LOGV(TAG, " continue block #%d", this_block_num); +#endif + } + +#else if(sha->isfirstblock){ /* start registers for first message block * we don't make any relational memory position assumptions. @@ -424,6 +495,7 @@ static int esp_sha_start_process(WC_ESP32SHA* sha) #endif } +#endif ESP_LOGV(TAG, " leave esp_sha_start_process"); @@ -445,10 +517,23 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ ESP_LOGE(TAG, " ERROR esp_process_block len exceeds 0x31 words"); } - /* check if there are any busy engine */ + /* wait until the engine is available */ wc_esp_wait_until_idle(); /* load [len] words of message data into hw */ +#if CONFIG_IDF_TARGET_ESP32S3 + uint32_t *pMessageSource = (uint32_t *)data; + uint32_t *pAcceleratorMessage = (uint32_t *)(SHA_TEXT_BASE); + while(word32_to_save--) + { + /* Must swap endiness of data loaded into harware accelerator to produce + * correct result. Using DPORT_REG_WRITE doesn't avoid this for ESP32s3. */ + DPORT_REG_WRITE(pAcceleratorMessage, __builtin_bswap32(*pMessageSource)); + ++pAcceleratorMessage; + ++pMessageSource; + } + +#else for (i = 0; i < word32_to_save; i++) { /* by using DPORT_REG_WRITE, we avoid the need * to call __builtin_bswap32 to address endiness @@ -461,12 +546,13 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ DPORT_REG_WRITE(SHA_TEXT_BASE + (i*sizeof(word32)), *(data + i)); /* memw confirmed auto inserted by compiler here */ } +#endif /* notify hw to start process * see ctx->sha_type * reg data does not change until we are ready to read */ esp_sha_start_process(ctx); - + ESP_LOGV(TAG, " leave esp_process_block"); } @@ -495,6 +581,17 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) /* wait until idle */ wc_esp_wait_until_idle(); +#if CONFIG_IDF_TARGET_ESP32S3 + /* read hash result into buffer & flip endiness */ + uint32_t* pHashDestination = (uint32_t*)hash; + size_t szHashWords = wc_esp_sha_digest_size(ctx->sha_type) / sizeof(uint32_t); + esp_dport_access_read_buffer(pHashDestination, SHA_H_BASE, szHashWords); + while(szHashWords--) + { + *pHashDestination = __builtin_bswap32(*pHashDestination); + ++pHashDestination; + } +#else /* each sha_type register is at a different location */ switch (ctx->sha_type) { case SHA1: @@ -559,6 +656,8 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) SHA_TEXT_BASE, /* there's a fixed reg addy for all SHA */ wc_esp_sha_digest_size(ctx->sha_type) / sizeof(word32) /* # 4-byte */ ); + + #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) if (ctx->sha_type == SHA2_384 || ctx->sha_type == SHA2_512) { @@ -571,6 +670,7 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) pwrd1[i] ^= pwrd1[i + 1]; } } +#endif #endif ESP_LOGV(TAG, "leave esp_digest_state"); From b22d185c48570f9b24a5783838d120abb21c258f Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 4 Jan 2023 10:59:22 +1300 Subject: [PATCH 4/6] Changes to build and complete wolf_test_task() successfully on ESP32s3 (and ESP32). * esp32-crypt.h - removed ets_sys.h include; not required for ESP32 and breaks ESP32s3 builds. * esp32_sha.c - update wc_esp_digest_state to skip reading digest for first block and correctly decode hash for SHA2_512. * esp32_mp.c fix mul, mulmod, exptmod to pass tests ESP32s3 * random.c - added missing include required to build on Espressif devices when not using hardware acceleration. * aes.c - return error code when setting Aes key if specific algorithms have been disabled (otherwise tests fail). * user_settings.h ** disable ED25519 as it fails test for ESP32 & ESP32s3 ** disable AES-192 as it is not supported on ESP32s3. --- IDE/Espressif/ESP-IDF/user_settings.h | 20 ++- wolfcrypt/src/aes.c | 17 +++ wolfcrypt/src/port/Espressif/README.md | 3 + wolfcrypt/src/port/Espressif/esp32_aes.c | 44 ++++-- wolfcrypt/src/port/Espressif/esp32_mp.c | 130 +++++++++++------- wolfcrypt/src/port/Espressif/esp32_sha.c | 56 ++++++-- wolfcrypt/src/random.c | 1 + .../wolfcrypt/port/Espressif/esp32-crypt.h | 4 +- 8 files changed, 201 insertions(+), 74 deletions(-) diff --git a/IDE/Espressif/ESP-IDF/user_settings.h b/IDE/Espressif/ESP-IDF/user_settings.h index 7c512dc469..1a9b8e6841 100644 --- a/IDE/Espressif/ESP-IDF/user_settings.h +++ b/IDE/Espressif/ESP-IDF/user_settings.h @@ -38,6 +38,18 @@ /* #define DEBUG_WOLFSSL_VERBOSE */ +// Enable key generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#rsa-key-generation +#define WOLFSSL_KEY_GEN + +// Enable certificate generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-generation +#define WOLFSSL_CERT_GEN + +// Enable certificate request generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-signing-request-csr-generation +#define WOLFSSL_CERT_REQ + #define BENCH_EMBEDDED #define USE_CERT_BUFFERS_2048 @@ -60,7 +72,13 @@ #define HAVE_ECC #define HAVE_CURVE25519 #define CURVE25519_SMALL -#define HAVE_ED25519 + +// ED25519 test fails on ESP32 & ESP32s3 +// #define HAVE_ED25519 + +/* AES-192 is not supported on the ESP32s3; is available for ESP32 + * and may be available for other devices. */ +#define NO_AES_192 /* when you want to use pkcs7 */ /* #define HAVE_PKCS7 */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 13e8fbbf68..a514bfe877 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2676,6 +2676,23 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; } +#if !defined(WOLFSSL_AES_128) + if (keylen == 16) { + return BAD_FUNC_ARG; + } +#endif + +#if !defined(WOLFSSL_AES_192) + if (keylen == 24) { + return BAD_FUNC_ARG; + } +#endif +#if !defined(WOLFSSL_AES_256) + if (keylen == 32) { + return BAD_FUNC_ARG; + } +#endif + aes->keylen = keylen; aes->rounds = keylen/4 + 6; diff --git a/wolfcrypt/src/port/Espressif/README.md b/wolfcrypt/src/port/Espressif/README.md index fe98e3be65..d57bbc654f 100644 --- a/wolfcrypt/src/port/Espressif/README.md +++ b/wolfcrypt/src/port/Espressif/README.md @@ -1,6 +1,9 @@ # ESP32 Port Support for the ESP32-WROOM-32 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512 and RSA primitive including mul, mulmod and exptmod. +Supported hardware includes: +* ESP32 +* ESP32s3 ## ESP32 Acceleration diff --git a/wolfcrypt/src/port/Espressif/esp32_aes.c b/wolfcrypt/src/port/Espressif/esp32_aes.c index 66d5830733..d3f13c7734 100644 --- a/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -38,7 +38,8 @@ #include #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h" - +#include + static const char* TAG = "wolf_hw_aes"; /* mutex */ @@ -56,7 +57,6 @@ static int espaes_CryptHwMutexInit = 0; static int esp_aes_hw_InUse() { int ret = 0; - printf("esp_aes_hw_InUse\n"); ESP_LOGV(TAG, "enter esp_aes_hw_InUse"); @@ -114,8 +114,9 @@ static void esp_aes_hw_Leave( void ) /* * set key to hardware key registers. + * return 0 on success; -1 if mode isn't supported. */ -static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) +static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) { word32 i; word32 mode_ = 0; @@ -132,7 +133,7 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) } else { ESP_LOGE(TAG, " >> unexpected error."); - return; + return -1; } } @@ -161,10 +162,13 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) if (mode_ == 1 || mode_ == 5 || mode_ == 7) { ESP_LOGE(TAG, " unsupported mode"); + return -1; } #endif DPORT_REG_WRITE(AES_MODE_REG, mode_); ESP_LOGV(TAG, " leave esp_aes_hw_Setkey"); + + return 0; } /* @@ -232,6 +236,7 @@ static void esp_aes_bk(const byte* in, byte* out) * @param in : a pointer of the input buffer containing plain text to be encrypted * @param out: a pointer of the output buffer in which to store the cipher text of * the encrypted message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) { @@ -239,7 +244,12 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) /* lock the hw engine */ esp_aes_hw_InUse(); /* load the key into the register */ - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } /* process a one block of AES */ esp_aes_bk(in, out); /* release hw */ @@ -254,6 +264,7 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) * @param in : a pointer of the input buffer containing plain text to be decrypted * @param out: a pointer of the output buffer in which to store the cipher text of * the decrypted message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) { @@ -261,7 +272,12 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) /* lock the hw engine */ esp_aes_hw_InUse(); /* load the key into the register */ - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } /* process a one block of AES */ esp_aes_bk(in, out); /* release hw engine */ @@ -279,6 +295,7 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) * the encrypted message * @param in : a pointer of the input buffer containing plain text to be encrypted * @param sz : size of input message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { @@ -294,7 +311,12 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) esp_aes_hw_InUse(); - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } while (blocks--) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); @@ -325,6 +347,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) * the decrypted message * @param in : a pointer of the input buffer containing plain text to be decrypted * @param sz : size of input message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { @@ -340,7 +363,12 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) esp_aes_hw_InUse(); - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } while (blocks--) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index 4e1fa3c3a3..48780fb6ce 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -48,6 +48,7 @@ static const char* const TAG = "wolfssl_mp"; #define ESP_HW_RSAMIN_BIT 512 #define BYTE_TO_WORDS(s) (((s+3)>>2)) /* (s+(4-1))/ 4 */ #define BITS_TO_WORDS(s) (((s+31)>>3)>>2) /* (s+(32-1))/ 8/ 4*/ +#define BITS_IN_ONE_WORD 32 #define MP_NG -1 @@ -146,7 +147,7 @@ static int esp_mp_hw_lock() /* Activate teh RSA accelerator. See §20.3 of ESP32-S3 technical manual. * periph_module_enable doesn't seem to be documented and in private folder * with v5 release. Maybe it will be deprecated? */ - DPORT_REG_SET_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + periph_module_enable(PERIPH_RSA_MODULE); /* clear bit to enable hardware operation; (set to disable) */ DPORT_REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); @@ -175,7 +176,7 @@ static void esp_mp_hw_unlock( void ) * periph_module_enable doesn't seem to be documented and in private folder * with v5 release. Maybe it will be deprecated? */ DPORT_REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - DPORT_REG_CLR_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + periph_module_disable(PERIPH_RSA_MODULE); #else /* set bit to disabled hardware operation; (clear to enable) @@ -237,12 +238,8 @@ static int wait_until_done(word32 reg) /* wait */ } -#if CONFIG_IDF_TARGET_ESP32S3 - // ESP32S3 doesn't use interrupt register for completion. -#else /* clear interrupt */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); -#endif if (ESP_TIMEOUT(timeout)) { ESP_LOGE(TAG, "rsa operation is timed out."); @@ -328,40 +325,36 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) { int ret = 0; int neg = (X->sign == Y->sign)? MP_ZPOS : MP_NEG; + +#if CONFIG_IDF_TARGET_ESP32S3 + + int nBitsInX = mp_count_bits(X); + int nBitsInY = mp_count_bits(Y); + + /* X & Y must be represented by the same number of bits. Must be + * enough to represent the larger one. */ + int nMinXYBits = max(nBitsInX, nBitsInY); + + /* Figure out how many words we need to represent each operand & the result. */ + int nWordsForOperand = bits2words(nMinXYBits); + int nWordsForResult = bits2words(nBitsInX + nBitsInY); - word32 Xs; - word32 Ys; - word32 Zs; - word32 maxWords_sz; - word32 hwWords_sz; - - /* ask bits number */ - Xs = mp_count_bits(X); - Ys = mp_count_bits(Y); - Zs = Xs + Ys; - - /* maximum bits and words for writing to hw */ - maxWords_sz = bits2words(max(Xs, Ys)); - hwWords_sz = words2hwords(maxWords_sz); - - /* sanity check */ - if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) { - ESP_LOGW(TAG, "exceeds max bit length(2048)"); - return -2; + /* Make sure we are within capabilities of hardware. */ + if ((nWordsForOperand * 8) > ESP_HW_MULTI_RSAMAX_BITS) { + ESP_LOGW(TAG, "exceeds max bit length(2048)"); + return -2; } -#if CONFIG_IDF_TARGET_ESP32S3 /* Steps to perform large number multiplication. Calculates Z = X x Y. The number of * bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the * maximum number of bits in the X and Y is 2048. * See §20.3.3 of ESP32-S3 technical manual * 1. Lock the hardware so no-one else uses it and wait until it is ready. * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. - * 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). - * Here N_result_bits is the number of bits in the multiplication result, which - * is 2x the number of bits in the operands. + * 3. Write number of words required for result to the RSA_MODE_REG (now called RSA_LENGTH_REG). + * Number of words required for the result is 2 * words for operand - 1 * 4. Load X, Y operands to memory blocks. Note the Y value must be written to - * offset of 4 x N_bits_Y + * right aligned. * 5. Start the operation by writing 1 to RSA_MULT_START_REG, then wait for it * to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG). * 6. Read the result out. @@ -378,21 +371,21 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) /* 2. Disable completion interrupt singal; we don't use. */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. - /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ - uint32_t uResultBits = max(Xs, Ys) * 2; - if (uResultBits > ESP_HW_RSAMAX_BIT) + /* 3. Write number of words required for result. */ + if (nWordsForOperand * 2 > ESP_HW_RSAMAX_BIT) { ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uResultBits / 32) - 1); + DPORT_REG_WRITE(RSA_LENGTH_REG, (nWordsForOperand * 2 - 1) ); /* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */ - esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); - esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz << 2), Y, Ys, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, nBitsInX, nWordsForOperand); + esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + nWordsForOperand * 4, Y, nBitsInY, nWordsForOperand); + /* 5. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MULT_START_REG, 1); + process_start(RSA_MULT_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { @@ -400,7 +393,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) } /* 6. read the result form MEM_Z */ - esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs)); + esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, nWordsForResult); /* 7. clear and release hw */ esp_mp_hw_unlock(); @@ -409,6 +402,27 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) return ret; #else + word32 Xs; + word32 Ys; + word32 Zs; + word32 maxWords_sz; + word32 hwWords_sz; + + /* ask bits number */ + Xs = mp_count_bits(X); + Ys = mp_count_bits(Y); + Zs = Xs + Ys; + + /* maximum bits and words for writing to hw */ + maxWords_sz = bits2words(max(Xs, Ys)); + hwWords_sz = words2hwords(maxWords_sz); + + /* sanity check */ + if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) { + ESP_LOGW(TAG, "exceeds max bit length(2048)"); + return -2; + } + /*Steps to use hw in the following order: * 1. wait until clean hw engine * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG @@ -504,13 +518,19 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) * where: R = b^n, and b = 2^32 * accordingly R^2 = 2^(n*32*2) */ +#if CONFIG_IDF_TARGET_ESP32S3 + word32 Exponent = maxWords_sz * BITS_IN_ONE_WORD * 2; +#else + word32 Exponent = hwWords_sz << 6; +#endif ret = mp_init_multi(&tmpZ, &r_inv, NULL, NULL, NULL, NULL); - if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz << 6))) != MP_OKAY) { + if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, Exponent)) != MP_OKAY) { ESP_LOGE(TAG, "calculate r_inv failed."); mp_clear(&tmpZ); mp_clear(&r_inv); return ret; } + /* lock hw for use */ if ((ret = esp_mp_hw_lock()) != MP_OKAY) { mp_clear(&tmpZ); @@ -524,16 +544,17 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) mp_clear(&r_inv); return -1; } - + #if CONFIG_IDF_TARGET_ESP32S3 /* Steps to perform large number modular multiplication. Calculates Z = (X x Y) modulo M. * The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the - * maximum number of bits in the X and Y is 2048. + * maximum number of bits in the X and Y is 2048. We must use the same number of words to represent + * the bits in X, Y and M. * See §20.3.3 of ESP32-S3 technical manual * 1. Wait until the hardware is ready. * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. - * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). - * Here N_bits is the maximum number of bits in X, Y and M. + * 3. Write the number of words required to represent the operands to the + * RSA_MODE_REG (now called RSA_LENGTH_REG). * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG). * 5. Load X, Y, M, r' operands to memory blocks. * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG, then wait for it @@ -558,19 +579,24 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + int nWordsForOperand = bits2words(uOperandBits); + DPORT_REG_WRITE(RSA_LENGTH_REG, nWordsForOperand - 1); /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + + /* Select acceleration options. */ + DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - /* 5. Load X, Y, M, r' operands. */ + /* 5. Load X, Y, M, r' operands. + * Note RSA_MEM_RB_BLOCK_BASE == RSA_MEM_Z_BLOC_BASE on ESP32s3*/ esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz); esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz); - esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_RB_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); /* 6. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MOD_MULT_START_REG, 1); + process_start(RSA_MOD_MULT_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { @@ -583,7 +609,9 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) /* 8. clear and release hw */ esp_mp_hw_unlock(); - // todo: implement work-arounds for known issues with ESP32 version (see below) if needed. + if (negcheck) { + mp_sub(M, &tmpZ, &tmpZ); + } mp_copy(&tmpZ, Z); mp_clear(&tmpZ); @@ -627,6 +655,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) /* step.3 write M' into memory */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + /* step.4 start process */ process_start(RSA_MULT_START_REG); @@ -764,7 +793,8 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + int nWordsForOperand = bits2words(uOperandBits); + DPORT_REG_WRITE(RSA_LENGTH_REG, nWordsForOperand - 1); /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); @@ -776,7 +806,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); /* 6. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MODEXP_START_REG, 1); + process_start(RSA_MODEXP_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 7574483f89..1cc87c730f 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -391,7 +391,7 @@ static int esp_sha_start_process(WC_ESP32SHA* sha) sha->mode = ESP32_SHA_FAIL_NEED_UNROLL; return -1; } - + REG_WRITE(SHA_MODE_REG, uHardwareAlgorithm); if (sha->isfirstblock) @@ -509,7 +509,6 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ const word32* data, word32 len) { - int i; int word32_to_save = (len) / (sizeof(word32)); ESP_LOGV(TAG, " enter esp_process_block"); if (word32_to_save > 0x31) { @@ -524,16 +523,19 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ #if CONFIG_IDF_TARGET_ESP32S3 uint32_t *pMessageSource = (uint32_t *)data; uint32_t *pAcceleratorMessage = (uint32_t *)(SHA_TEXT_BASE); - while(word32_to_save--) + while (word32_to_save--) { - /* Must swap endiness of data loaded into harware accelerator to produce - * correct result. Using DPORT_REG_WRITE doesn't avoid this for ESP32s3. */ - DPORT_REG_WRITE(pAcceleratorMessage, __builtin_bswap32(*pMessageSource)); - ++pAcceleratorMessage; - ++pMessageSource; + /* Must swap endiness of data loaded into harware accelerator to produce + * correct result. Using DPORT_REG_WRITE doesn't avoid this for ESP32s3. + * Note: data sheet claims we also need to swap endian across 64 byte words + * when doing SHA-512, but the SHA-512 result is not correct if you do that. */ + DPORT_REG_WRITE(pAcceleratorMessage, __builtin_bswap32(*pMessageSource)); + ++pAcceleratorMessage; + ++pMessageSource; } - + #else + int i; for (i = 0; i < word32_to_save; i++) { /* by using DPORT_REG_WRITE, we avoid the need * to call __builtin_bswap32 to address endiness @@ -578,20 +580,46 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) return -1; } +#if CONFIG_IDF_TARGET_ESP32S3 + if (ctx->isfirstblock == 1) + { + /* no hardware use yet. Nothing to do yet */ + return 0; + } + /* wait until idle */ wc_esp_wait_until_idle(); -#if CONFIG_IDF_TARGET_ESP32S3 /* read hash result into buffer & flip endiness */ uint32_t* pHashDestination = (uint32_t*)hash; size_t szHashWords = wc_esp_sha_digest_size(ctx->sha_type) / sizeof(uint32_t); esp_dport_access_read_buffer(pHashDestination, SHA_H_BASE, szHashWords); - while(szHashWords--) + + if (ctx->sha_type == SHA2_512) + { + /* Although we don't have to swap endian on 64-bit words at the input, + * we do for the output. */ + size_t szHash64Words = szHashWords / 2; + uint64_t *pHash64Buffer = (uint64_t*)pHashDestination; + while (szHash64Words--) + { + *pHash64Buffer = __builtin_bswap64(*pHash64Buffer); + ++pHash64Buffer; + } + } + else { - *pHashDestination = __builtin_bswap32(*pHashDestination); - ++pHashDestination; + while (szHashWords--) + { + *pHashDestination = __builtin_bswap32(*pHashDestination); + ++pHashDestination; + } } #else + + /* wait until idle */ + wc_esp_wait_until_idle(); + /* each sha_type register is at a different location */ switch (ctx->sha_type) { case SHA1: @@ -672,7 +700,7 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) } #endif #endif - + ESP_LOGV(TAG, "leave esp_digest_state"); return 0; } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 81daadfd1d..4036165c17 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3397,6 +3397,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) /* Espressif ESP32 */ #include + #include int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { diff --git a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index 32d4107dee..7ac9e596ac 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -51,7 +51,9 @@ #include "driver/periph_ctrl.h" #endif -#if ESP_IDF_VERSION_MAJOR >= 4 +#if ESP_IDF_VERSION_MAJOR >= 5 + // ets_sys.h isn't required for ESP32; breaks ESP32s3 build. +#elif ESP_IDF_VERSION_MAJOR >= 4 #include #else #include From a3d0d71faef8e73c1e005cc9e9529666ff745a68 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 23 Feb 2023 14:57:12 +1300 Subject: [PATCH 5/6] Fix bug where required number of bits wasn't calculated correctly. (cherry picked from commit c62e53922ac75d38dcbac221f962a45f6b8095f4) --- wolfcrypt/src/port/Espressif/esp32_mp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index c79231e45f..1b40f4e813 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -340,7 +340,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) int nWordsForResult = bits2words(nBitsInX + nBitsInY); /* Make sure we are within capabilities of hardware. */ - if ((nWordsForOperand * 8) > ESP_HW_MULTI_RSAMAX_BITS) { + if ((nWordsForOperand * BITS_IN_ONE_WORD) > ESP_HW_MULTI_RSAMAX_BITS) { ESP_LOGW(TAG, "exceeds max bit length(2048)"); return -2; } @@ -372,7 +372,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. /* 3. Write number of words required for result. */ - if (nWordsForOperand * 2 > ESP_HW_RSAMAX_BIT) + if (nWordsForOperand * BITS_IN_ONE_WORD * 2 > ESP_HW_RSAMAX_BIT) { ESP_LOGW(TAG, "result exceeds max bit length"); return -2; From 360c470c01055287605efcdd0841c691ef4f6537 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 8 Mar 2023 12:31:52 +1300 Subject: [PATCH 6/6] Update for wolfssl_tests to pass with ESP32s3 support. Exclude Espressif backup files from git. --- IDE/Espressif/ESP-IDF/.gitignore | 2 + .../ESP-IDF/examples/wolfssl_test/main/main.c | 2 - IDE/Espressif/ESP-IDF/user_settings.h | 39 ++++++++++++++----- 3 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 IDE/Espressif/ESP-IDF/.gitignore diff --git a/IDE/Espressif/ESP-IDF/.gitignore b/IDE/Espressif/ESP-IDF/.gitignore new file mode 100644 index 0000000000..1babb6fc39 --- /dev/null +++ b/IDE/Espressif/ESP-IDF/.gitignore @@ -0,0 +1,2 @@ +# Exclude sdkconfig backups created by idf.py etc (e.g., sdkconfig.old). +*.old 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 01538f72e3..b8993cb481 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c @@ -177,8 +177,6 @@ void app_main(void) #error "ESP32WROOM32_CRYPT not yet supported on ESP32-C3" #elif defined(CONFIG_IDF_TARGET_ESP32S2) #error "ESP32WROOM32_CRYPT not yet supported on ESP32-S2" - #elif defined(CONFIG_IDF_TARGET_ESP32S3) - #error "ESP32WROOM32_CRYPT not yet supported on ESP32-S3" #else ESP_LOGI(TAG, "ESP32WROOM32_CRYPT is enabled."); #endif diff --git a/IDE/Espressif/ESP-IDF/user_settings.h b/IDE/Espressif/ESP-IDF/user_settings.h index a8ae66b896..6a37e2a923 100644 --- a/IDE/Espressif/ESP-IDF/user_settings.h +++ b/IDE/Espressif/ESP-IDF/user_settings.h @@ -38,16 +38,16 @@ /* #define DEBUG_WOLFSSL_VERBOSE */ -// Enable key generation: -// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#rsa-key-generation +/* Enable key generation: +https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#rsa-key-generation */ #define WOLFSSL_KEY_GEN -// Enable certificate generation: -// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-generation +/* Enable certificate generation: +https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-generation */ #define WOLFSSL_CERT_GEN -// Enable certificate request generation: -// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-signing-request-csr-generation +/* Enable certificate request generation: +https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-signing-request-csr-generation */ #define WOLFSSL_CERT_REQ #define BENCH_EMBEDDED @@ -66,19 +66,36 @@ #define NO_FILESYSTEM #define HAVE_AESGCM -/* when you want to use SHA384 */ + +/* +Enable SHA-384 support +See: https://www.wolfssl.com/documentation/manuals/wolfssl/chapter02.html#wolfssl_sha384 +Note: currently not working. See https://github.com/gojimmypi/wolfssl/tree/ED25519_SHA2_fix/ */ /* #define WOLFSSL_SHA384 */ + + #define WOLFSSL_SHA512 #define HAVE_ECC #define HAVE_CURVE25519 #define CURVE25519_SMALL // ED25519 test fails on ESP32 & ESP32s3 -// #define HAVE_ED25519 +/* Enable ES25519 support. +Currently failing for ESP32 & ESP32s3. +See: https://github.com/wolfSSL/wolfssl/issues/5948 +and: https://github.com/gojimmypi/wolfssl/tree/ED25519_SHA2_fix/ */ +/* #define HAVE_ED25519 */ + +/* Disable SHA-512/224 & SHA-512/256; currently not working. +See https://github.com/gojimmypi/wolfssl/tree/ED25519_SHA2_fix/ */ +#define WOLFSSL_NOSHA512_224 +#define WOLFSSL_NOSHA512_256 /* AES-192 is not supported on the ESP32s3; is available for ESP32 * and may be available for other devices. */ +#if !defined(CONFIG_IDF_TARGET_ESP32S3) #define NO_AES_192 +#endif /* when you want to use pkcs7 */ /* #define HAVE_PKCS7 */ @@ -116,9 +133,13 @@ /* debug options */ /* #define DEBUG_WOLFSSL */ -/* #define WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */ /* #define WOLFSSL_ATECC508A_DEBUG */ +/* Note: WOLFSSL_ESP32WROOM32_CRYPT_DEBUG not available for ESP32s3 due +to issue including "esp_timer.h". See https://github.com/gojimmypi/wolfssl/tree/ED25519_SHA2_fix/ +for pending solution. */ +/* #define WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */ + /* date/time */ /* if it cannot adjust time in the device, */ /* enable macro below */